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 */
64 static struct REDIR_PARAMS
66 DWORD dwDesiredAccess
;
68 DWORD dwCreationDisposition
;
71 {GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, OPEN_EXISTING
}, // REDIR_READ
72 {GENERIC_WRITE
, FILE_SHARE_READ
, CREATE_ALWAYS
}, // REDIR_WRITE
73 {GENERIC_WRITE
, FILE_SHARE_READ
, OPEN_ALWAYS
} // REDIR_APPEND
76 for (Redir
= RedirList
; Redir
; Redir
= Redir
->Next
)
78 Filename
= DoDelayedExpansion(Redir
->Filename
);
81 StripQuotes(Filename
);
83 if (*Filename
== _T('&'))
85 DupNumber
= Filename
[1] - _T('0');
86 if (DupNumber
>= 10 ||
87 !DuplicateHandle(GetCurrentProcess(),
93 DUPLICATE_SAME_ACCESS
))
95 hNew
= INVALID_HANDLE_VALUE
;
100 hNew
= CreateFile(Filename
,
101 RedirParams
[Redir
->Mode
].dwDesiredAccess
,
102 RedirParams
[Redir
->Mode
].dwShareMode
,
104 RedirParams
[Redir
->Mode
].dwCreationDisposition
,
109 if (hNew
== INVALID_HANDLE_VALUE
)
111 /* TODO: Print a more detailed message */
112 ConErrResPrintf(Redir
->Mode
== REDIR_READ
? STRING_CMD_ERROR1
: STRING_CMD_ERROR3
,
116 /* Undo all the redirections before this one */
117 UndoRedirection(RedirList
, Redir
);
121 if (Redir
->Mode
== REDIR_APPEND
)
122 SetFilePointer(hNew
, 0, NULL
, FILE_END
);
123 Redir
->OldHandle
= GetHandle(Redir
->Number
);
124 SetHandle(Redir
->Number
, hNew
);
126 TRACE("%d redirected to: %s\n", Redir
->Number
, debugstr_aw(Filename
));
133 UndoRedirection(REDIRECTION
*Redir
, REDIRECTION
*End
)
135 for (; Redir
!= End
; Redir
= Redir
->Next
)
137 CloseHandle(GetHandle(Redir
->Number
));
138 SetHandle(Redir
->Number
, Redir
->OldHandle
);
139 Redir
->OldHandle
= INVALID_HANDLE_VALUE
;
144 FreeRedirection(REDIRECTION
*Redir
)
147 for (; Redir
; Redir
= Next
)
150 ASSERT(Redir
->OldHandle
== INVALID_HANDLE_VALUE
);
155 #endif /* FEATURE_REDIRECTION */