2 * REDIR.C - redirection handling.
7 * 12/15/95 (Tim Norman)
10 * 12 Jul 98 (Hans B Pufal)
11 * Rewrote to make more efficient and to conform to new command.c
12 * and batch.c processing.
14 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
15 * Added config.h include
17 * 22-Jan-1999 (Eric Kohl)
19 * Added new error redirection "2>" and "2>>".
21 * 26-Jan-1999 (Eric Kohl)
22 * Added new error AND output redirection "&>" and "&>>".
24 * 24-Jun-2005 (Brandon Turner <turnerb7@msu.edu>)
25 * simple check to fix > and | bug with 'rem'
30 #ifdef FEATURE_REDIRECTION
33 /* cmd allows redirection of handles numbered 3-9 even though these don't
34 * correspond to any STD_ constant. */
35 static HANDLE ExtraHandles
[10 - 3];
37 static HANDLE
GetHandle(UINT Number
)
40 return GetStdHandle(STD_INPUT_HANDLE
- Number
);
42 return ExtraHandles
[Number
- 3];
45 static VOID
SetHandle(UINT Number
, HANDLE Handle
)
48 SetStdHandle(STD_INPUT_HANDLE
- Number
, Handle
);
50 ExtraHandles
[Number
- 3] = Handle
;
54 PerformRedirection(REDIRECTION
*RedirList
)
60 static SECURITY_ATTRIBUTES SecAttr
= { sizeof(SECURITY_ATTRIBUTES
), NULL
, TRUE
};
62 /* Some parameters used for read, write, and append, respectively */
63 static const DWORD dwAccess
[] = {
68 static const DWORD dwShareMode
[] = {
69 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
73 static const DWORD dwCreationDisposition
[] = {
79 for (Redir
= RedirList
; Redir
; Redir
= Redir
->Next
)
81 Filename
= DoDelayedExpansion(Redir
->Filename
);
84 StripQuotes(Filename
);
86 if (*Filename
== _T('&'))
88 DupNumber
= Filename
[1] - _T('0');
89 if (DupNumber
>= 10 ||
90 !DuplicateHandle(GetCurrentProcess(),
96 DUPLICATE_SAME_ACCESS
))
98 hNew
= INVALID_HANDLE_VALUE
;
103 hNew
= CreateFile(Filename
,
104 dwAccess
[Redir
->Type
],
105 dwShareMode
[Redir
->Type
],
107 dwCreationDisposition
[Redir
->Type
],
112 if (hNew
== INVALID_HANDLE_VALUE
)
114 ConErrResPrintf(Redir
->Type
== REDIR_READ
? STRING_CMD_ERROR1
: STRING_CMD_ERROR3
,
118 /* Undo all the redirections before this one */
119 UndoRedirection(RedirList
, Redir
);
123 if (Redir
->Type
== REDIR_APPEND
)
124 SetFilePointer(hNew
, 0, NULL
, FILE_END
);
125 Redir
->OldHandle
= GetHandle(Redir
->Number
);
126 SetHandle(Redir
->Number
, hNew
);
128 TRACE("%d redirected to: %s\n", Redir
->Number
, debugstr_aw(Filename
));
135 UndoRedirection(REDIRECTION
*Redir
, REDIRECTION
*End
)
137 for (; Redir
!= End
; Redir
= Redir
->Next
)
139 CloseHandle(GetHandle(Redir
->Number
));
140 SetHandle(Redir
->Number
, Redir
->OldHandle
);
141 Redir
->OldHandle
= INVALID_HANDLE_VALUE
;
146 FreeRedirection(REDIRECTION
*Redir
)
149 for (; Redir
; Redir
= Next
)
152 ASSERT(Redir
->OldHandle
== INVALID_HANDLE_VALUE
);
157 #endif /* FEATURE_REDIRECTION */