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
34 * these don't correspond to any STD_ constant.
36 static const PCON_STREAM StdStreams
[] = { StdIn
, StdOut
, StdErr
};
37 static HANDLE ExtraHandles
[10 - 3]; // 3 == ARRAYSIZE(StdStreams)
39 HANDLE
GetHandle(UINT Number
)
42 return ConStreamGetOSHandle(StdStreams
[Number
]);
43 // return GetStdHandle(STD_INPUT_HANDLE - Number);
44 else if (Number
< ARRAYSIZE(ExtraHandles
) + 3)
45 return ExtraHandles
[Number
- 3];
47 return INVALID_HANDLE_VALUE
;
50 VOID
SetHandle(UINT Number
, HANDLE Handle
)
54 ConStreamSetOSHandle(StdStreams
[Number
], Handle
);
55 /* Synchronize the associated Win32 handle */
56 SetStdHandle(STD_INPUT_HANDLE
- Number
, Handle
);
58 else if (Number
< ARRAYSIZE(ExtraHandles
) + 3)
59 ExtraHandles
[Number
- 3] = Handle
;
63 PerformRedirection(REDIRECTION
*RedirList
)
70 static SECURITY_ATTRIBUTES SecAttr
= { sizeof(SECURITY_ATTRIBUTES
), NULL
, TRUE
};
72 /* Some parameters used for read, write, and append, respectively */
73 static struct REDIR_PARAMS
75 DWORD dwDesiredAccess
;
77 DWORD dwCreationDisposition
;
80 {GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, OPEN_EXISTING
}, // REDIR_READ
81 {GENERIC_WRITE
, FILE_SHARE_READ
, CREATE_ALWAYS
}, // REDIR_WRITE
82 {GENERIC_WRITE
, FILE_SHARE_READ
, OPEN_ALWAYS
} // REDIR_APPEND
85 for (Redir
= RedirList
; Redir
; Redir
= Redir
->Next
)
87 Filename
= DoDelayedExpansion(Redir
->Filename
);
90 StripQuotes(Filename
);
92 if (*Filename
== _T('&'))
94 DupNumber
= Filename
[1] - _T('0');
95 if (DupNumber
>= 10 ||
96 !DuplicateHandle(GetCurrentProcess(),
102 DUPLICATE_SAME_ACCESS
))
104 hNew
= INVALID_HANDLE_VALUE
;
109 hNew
= CreateFile(Filename
,
110 RedirParams
[Redir
->Mode
].dwDesiredAccess
,
111 RedirParams
[Redir
->Mode
].dwShareMode
,
113 RedirParams
[Redir
->Mode
].dwCreationDisposition
,
118 if (hNew
== INVALID_HANDLE_VALUE
)
120 /* TODO: Print a more detailed message */
121 ConErrResPrintf(Redir
->Mode
== REDIR_READ
? STRING_CMD_ERROR1
: STRING_CMD_ERROR3
,
125 /* Undo all the redirections before this one */
126 UndoRedirection(RedirList
, Redir
);
130 if (Redir
->Mode
== REDIR_APPEND
)
131 SetFilePointer(hNew
, 0, NULL
, FILE_END
);
132 Redir
->OldHandle
= GetHandle(Redir
->Number
);
133 SetHandle(Redir
->Number
, hNew
);
135 TRACE("%d redirected to: %s\n", Redir
->Number
, debugstr_aw(Filename
));
142 UndoRedirection(REDIRECTION
*Redir
, REDIRECTION
*End
)
144 for (; Redir
!= End
; Redir
= Redir
->Next
)
146 CloseHandle(GetHandle(Redir
->Number
));
147 SetHandle(Redir
->Number
, Redir
->OldHandle
);
148 Redir
->OldHandle
= INVALID_HANDLE_VALUE
;
153 FreeRedirection(REDIRECTION
*Redir
)
156 for (; Redir
; Redir
= Next
)
159 ASSERT(Redir
->OldHandle
== INVALID_HANDLE_VALUE
);
164 #endif /* FEATURE_REDIRECTION */