From 085c0f4a3a367eb52721140c109343b47cee9170 Mon Sep 17 00:00:00 2001 From: Jason Edmeades Date: Tue, 13 Mar 2007 00:09:05 +0000 Subject: [PATCH] cmd.exe: Add support for stderr redirection to a file. --- programs/cmd/wcmdmain.c | 67 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 11c2576f4e9..eaac82b8f7c 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -385,15 +385,20 @@ int main (int argc, char *argv[]) void WCMD_process_command (char *command) { - char *cmd, *p, *s, *t; + char *cmd, *p, *s, *t, *redir; int status, i; DWORD count, creationDisposition; HANDLE h; char *whichcmd; SECURITY_ATTRIBUTES sa; char *new_cmd; - HANDLE old_stdin = INVALID_HANDLE_VALUE; - HANDLE old_stdout = INVALID_HANDLE_VALUE; + char *first_redir = NULL; + HANDLE old_stdhandles[3] = {INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE}; + DWORD idx_stdhandles[3] = {STD_INPUT_HANDLE, + STD_OUTPUT_HANDLE, + STD_ERROR_HANDLE}; /* Move copy of the command onto the heap so it can be expanded */ new_cmd = HeapAlloc( GetProcessHeap(), 0, MAXSTRING ); @@ -486,16 +491,16 @@ void WCMD_process_command (char *command) return; } - /* Don't issue newline WCMD_output (newline); @JED*/ - sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; + /* - * Redirect stdin and/or stdout if required. + * Redirect stdin, stdout and/or stderr if required. */ if ((p = strchr(cmd,'<')) != NULL) { + if (first_redir == NULL) first_redir = p; h = CreateFile (WCMD_parameter (++p, 0, NULL), GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) { @@ -503,11 +508,24 @@ void WCMD_process_command (char *command) HeapFree( GetProcessHeap(), 0, cmd ); return; } - old_stdin = GetStdHandle (STD_INPUT_HANDLE); + old_stdhandles[0] = GetStdHandle (STD_INPUT_HANDLE); SetStdHandle (STD_INPUT_HANDLE, h); } - if ((p = strchr(cmd,'>')) != NULL) { - *p++ = '\0'; + + /* Scan the whole command looking for > and 2> */ + redir = cmd; + while (redir != NULL && ((p = strchr(redir,'>')) != NULL)) { + int handle = 0; + + if (*(p-1)!='2') { + if (first_redir == NULL) first_redir = p; + handle = 1; + } else { + if (first_redir == NULL) first_redir = (p-1); + handle = 2; + } + + p++; if ('>' == *p) { creationDisposition = OPEN_ALWAYS; p++; @@ -515,21 +533,24 @@ void WCMD_process_command (char *command) else { creationDisposition = CREATE_ALWAYS; } + redir = p; h = CreateFile (WCMD_parameter (p, 0, NULL), GENERIC_WRITE, 0, &sa, creationDisposition, - FILE_ATTRIBUTE_NORMAL, NULL); + FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) { - WCMD_print_error (); + WCMD_print_error (); HeapFree( GetProcessHeap(), 0, cmd ); - return; + return; } if (SetFilePointer (h, 0, NULL, FILE_END) == - INVALID_SET_FILE_POINTER) { + INVALID_SET_FILE_POINTER) { WCMD_print_error (); } - old_stdout = GetStdHandle (STD_OUTPUT_HANDLE); - SetStdHandle (STD_OUTPUT_HANDLE, h); + old_stdhandles[handle] = GetStdHandle (idx_stdhandles[handle]); + SetStdHandle (idx_stdhandles[handle], h); } - if ((p = strchr(cmd,'<')) != NULL) *p = '\0'; + + /* Terminate the command string at <, or first 2> or > */ + if (first_redir != NULL) *first_redir = '\0'; /* * Strip leading whitespaces, and a '@' if supplied @@ -681,13 +702,13 @@ void WCMD_process_command (char *command) WCMD_run_program (whichcmd, 0); } HeapFree( GetProcessHeap(), 0, cmd ); - if (old_stdin != INVALID_HANDLE_VALUE) { - CloseHandle (GetStdHandle (STD_INPUT_HANDLE)); - SetStdHandle (STD_INPUT_HANDLE, old_stdin); - } - if (old_stdout != INVALID_HANDLE_VALUE) { - CloseHandle (GetStdHandle (STD_OUTPUT_HANDLE)); - SetStdHandle (STD_OUTPUT_HANDLE, old_stdout); + + /* Restore old handles */ + for (i=0; i<3; i++) { + if (old_stdhandles[i] != INVALID_HANDLE_VALUE) { + CloseHandle (GetStdHandle (idx_stdhandles[i])); + SetStdHandle (idx_stdhandles[i], old_stdhandles[i]); + } } } -- 2.11.4.GIT