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
)
61 static SECURITY_ATTRIBUTES SecAttr
= { sizeof(SECURITY_ATTRIBUTES
), NULL
, TRUE
};
63 /* Some parameters used for read, write, and append, respectively */
67 DWORD dwDesiredAccess
;
69 DWORD dwCreationDisposition
;
72 {GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, OPEN_EXISTING
}, // REDIR_READ
73 {GENERIC_WRITE
, FILE_SHARE_READ
, CREATE_ALWAYS
}, // REDIR_WRITE
74 {GENERIC_WRITE
, FILE_SHARE_READ
, OPEN_ALWAYS
} // REDIR_APPEND
77 for (Redir
= RedirList
; Redir
; Redir
= Redir
->Next
)
79 Filename
= DoDelayedExpansion(Redir
->Filename
);
82 StripQuotes(Filename
);
84 if (*Filename
== _T('&'))
86 DupNumber
= Filename
[1] - _T('0');
87 if (DupNumber
>= 10 ||
88 !DuplicateHandle(GetCurrentProcess(),
94 DUPLICATE_SAME_ACCESS
))
96 hNew
= INVALID_HANDLE_VALUE
;
101 hNew
= CreateFile(Filename
,
102 RedirParams
[Redir
->Mode
].dwDesiredAccess
,
103 RedirParams
[Redir
->Mode
].dwShareMode
,
105 RedirParams
[Redir
->Mode
].dwCreationDisposition
,
110 if (hNew
== INVALID_HANDLE_VALUE
)
112 /* TODO: Print a more detailed message */
113 ConErrResPrintf(Redir
->Mode
== REDIR_READ
? STRING_CMD_ERROR1
: STRING_CMD_ERROR3
,
117 /* Undo all the redirections before this one */
118 UndoRedirection(RedirList
, Redir
);
122 if (Redir
->Mode
== REDIR_APPEND
)
123 SetFilePointer(hNew
, 0, NULL
, FILE_END
);
124 Redir
->OldHandle
= GetHandle(Redir
->Number
);
125 SetHandle(Redir
->Number
, hNew
);
127 TRACE("%d redirected to: %s\n", Redir
->Number
, debugstr_aw(Filename
));
134 UndoRedirection(REDIRECTION
*Redir
, REDIRECTION
*End
)
136 for (; Redir
!= End
; Redir
= Redir
->Next
)
138 CloseHandle(GetHandle(Redir
->Number
));
139 SetHandle(Redir
->Number
, Redir
->OldHandle
);
140 Redir
->OldHandle
= INVALID_HANDLE_VALUE
;
145 FreeRedirection(REDIRECTION
*Redir
)
148 for (; Redir
; Redir
= Next
)
151 ASSERT(Redir
->OldHandle
== INVALID_HANDLE_VALUE
);
156 #endif /* FEATURE_REDIRECTION */