Author: jmorlan Date: Tue Mar 3 23:06:54 2009 New Revision: 39858
URL: http://svn.reactos.org/svn/reactos?rev=39858&view=rev Log: Rework batch-file processing so that 'call file.bat' doesn't return until the file has finished, allowing constructs like 'call file.bat & somethingelse' to work properly.
Modified: trunk/reactos/base/shell/cmd/batch.c trunk/reactos/base/shell/cmd/batch.h trunk/reactos/base/shell/cmd/call.c trunk/reactos/base/shell/cmd/cmd.c trunk/reactos/base/shell/cmd/cmd.h trunk/reactos/base/shell/cmd/internal.c
Modified: trunk/reactos/base/shell/cmd/batch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/batch.c?rev=... ============================================================================== --- trunk/reactos/base/shell/cmd/batch.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/batch.c [iso-8859-1] Tue Mar 3 23:06:54 2009 @@ -171,8 +171,6 @@
if (bc != NULL) { - LPBATCH_CONTEXT t = bc; - if (bc->hBatchFile) { CloseHandle (bc->hBatchFile); @@ -192,7 +190,6 @@ bEcho = bc->bEcho;
bc = bc->prev; - cmd_free(t); }
if (msg && *msg) @@ -207,8 +204,10 @@ * */
-BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, BOOL forcenew) -{ +BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd) +{ + BATCH_CONTEXT new; + HANDLE hFile; SetLastError(0); hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, @@ -227,22 +226,7 @@ /* Kill any and all FOR contexts */ fc = NULL;
- if (bc == NULL || forcenew) - { - /* No curent batch file, create a new context */ - LPBATCH_CONTEXT n = (LPBATCH_CONTEXT)cmd_alloc (sizeof(BATCH_CONTEXT)); - - if (n == NULL) - { - error_out_of_memory (); - return FALSE; - } - - n->prev = bc; - bc = n; - bc->RedirList = NULL; - } - else if (bc->hBatchFile != INVALID_HANDLE_VALUE) + if (bc != NULL && Cmd == bc->current) { /* Then we are transferring to another batch */ CloseHandle (bc->hBatchFile); @@ -251,6 +235,20 @@ cmd_free (bc->params); if (bc->raw_params) cmd_free (bc->raw_params); + AddBatchRedirection(&Cmd->Redirections); + } + else + { + /* If a batch file runs another batch file as part of a compound command + * (e.g. "x.bat & somethingelse") then the first file gets terminated. */ + if (Cmd != NULL) + ExitBatch(NULL); + + /* Create a new context. This function will not + * return until this context has been exited */ + new.prev = bc; + bc = &new; + bc->RedirList = NULL; }
GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, NULL); @@ -264,16 +262,41 @@ // // Allocate enough memory to hold the params and copy them over without modifications // - bc->raw_params = (TCHAR*) cmd_alloc((_tcslen(param)+1) * sizeof(TCHAR)); - if (bc->raw_params != NULL) - { - _tcscpy(bc->raw_params,param); - } - else + bc->raw_params = cmd_dup(param); + if (bc->raw_params == NULL) { error_out_of_memory(); return FALSE; } + + /* Check if this is a "CALL :label" */ + if (*firstword == _T(':')) + cmd_goto(firstword); + + /* If we have created a new context, don't return + * until this batch file has completed. */ + while (bc == &new && !bExit) + { + Cmd = ParseCommand(NULL); + if (!Cmd) + continue; + + /* JPP 19980807 */ + /* Echo batch file line */ + if (bEcho && Cmd->Type != C_QUIET) + { + PrintPrompt(); + EchoCommand(Cmd); + ConOutChar(_T('\n')); + } + + bc->current = Cmd; + ExecuteCommand(Cmd); + if (bEcho && !bIgnoreEcho && Cmd->Type != C_QUIET) + ConOutChar(_T('\n')); + FreeCommand(Cmd); + bIgnoreEcho = FALSE; + }
/* Don't print a newline for this command */ bIgnoreEcho = TRUE; @@ -313,50 +336,34 @@
LPTSTR ReadBatchLine () { - LPTSTR first; - /* No batch */ if (bc == NULL) return NULL;
TRACE ("ReadBatchLine ()\n");
- while (1) - { - /* User halt */ - if (CheckCtrlBreak (BREAK_BATCHFILE)) - { - while (bc) - ExitBatch (NULL); - return NULL; - } - - /* No batch */ - if (bc == NULL) - return NULL; - - if (!FileGetString (bc->hBatchFile, textline, sizeof (textline) / sizeof (textline[0]) - 1)) - { - TRACE ("ReadBatchLine(): Reached EOF!\n"); - /* End of file.... */ + /* User halt */ + if (CheckCtrlBreak (BREAK_BATCHFILE)) + { + while (bc) ExitBatch (NULL); - - if (bc == NULL) - return NULL; - - continue; - } - TRACE ("ReadBatchLine(): textline: '%s'\n", debugstr_aw(textline)); - - if (textline[_tcslen(textline) - 1] != _T('\n')) - _tcscat(textline, _T("\n")); - - first = textline; - - break; - } - - return first; + return NULL; + } + + if (!FileGetString (bc->hBatchFile, textline, sizeof (textline) / sizeof (textline[0]) - 1)) + { + TRACE ("ReadBatchLine(): Reached EOF!\n"); + /* End of file.... */ + ExitBatch (NULL); + return NULL; + } + + TRACE ("ReadBatchLine(): textline: '%s'\n", debugstr_aw(textline)); + + if (textline[_tcslen(textline) - 1] != _T('\n')) + _tcscat(textline, _T("\n")); + + return textline; }
/* EOF */
Modified: trunk/reactos/base/shell/cmd/batch.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/batch.h?rev=... ============================================================================== --- trunk/reactos/base/shell/cmd/batch.h [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/batch.h [iso-8859-1] Tue Mar 3 23:06:54 2009 @@ -17,6 +17,7 @@ INT shiftlevel; BOOL bEcho; /* Preserve echo flag across batch calls */ REDIRECTION *RedirList; + PARSED_COMMAND *current; } BATCH_CONTEXT, *LPBATCH_CONTEXT;
typedef struct tagFORCONTEXT @@ -45,7 +46,7 @@ LPTSTR FindArg (INT); LPTSTR BatchParams (LPTSTR, LPTSTR); VOID ExitBatch (LPTSTR); -BOOL Batch (LPTSTR, LPTSTR, LPTSTR, BOOL); +BOOL Batch (LPTSTR, LPTSTR, LPTSTR, PARSED_COMMAND *); LPTSTR ReadBatchLine(); VOID AddBatchRedirection(REDIRECTION **);
Modified: trunk/reactos/base/shell/cmd/call.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/call.c?rev=3... ============================================================================== --- trunk/reactos/base/shell/cmd/call.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/call.c [iso-8859-1] Tue Mar 3 23:06:54 2009 @@ -42,8 +42,6 @@
INT cmd_call (LPTSTR param) { - LPBATCH_CONTEXT n = NULL; - TRACE ("cmd_call: ('%s')\n", debugstr_aw(param)); if (!_tcsncmp (param, _T("/?"), 2)) { @@ -62,39 +60,10 @@ while (_istspace(*param)) param++; } - if (!Batch(bc->BatchFilePath, first, param, TRUE)) - return 1; - return cmd_goto(first); + return !Batch(bc->BatchFilePath, first, param, NULL); }
- nErrorLevel = 0; - - n = (LPBATCH_CONTEXT)cmd_alloc (sizeof (BATCH_CONTEXT)); - - if (n == NULL) - { - error_out_of_memory (); - return 1; - } - - n->prev = bc; - bc = n; - - bc->hBatchFile = INVALID_HANDLE_VALUE; - bc->params = NULL; - bc->shiftlevel = 0; - bc->RedirList = NULL; - ParseCommandLine (param); - - - /* Wasn't a batch file so remove conext */ - if (bc->hBatchFile == INVALID_HANDLE_VALUE) - { - bc = bc->prev; - cmd_free (n); - } - - return 0; + return !DoCommand(param, NULL); }
/* EOF */
Modified: trunk/reactos/base/shell/cmd/cmd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.c?rev=39... ============================================================================== --- trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] Tue Mar 3 23:06:54 2009 @@ -324,7 +324,7 @@ */
static BOOL -Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest) +Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd) { TCHAR *szFullName=NULL; TCHAR *first = NULL; @@ -470,7 +470,7 @@ if (dot && (!_tcsicmp (dot, _T(".bat")) || !_tcsicmp (dot, _T(".cmd")))) { TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest)); - Batch (szFullName, first, rest, FALSE); + Batch (szFullName, first, rest, Cmd); } else { @@ -568,7 +568,7 @@ */
BOOL -DoCommand (LPTSTR line) +DoCommand (LPTSTR line, PARSED_COMMAND *Cmd) { TCHAR *com = NULL; /* the first word in the command */ TCHAR *cp = NULL; @@ -642,7 +642,7 @@ /* If end of table execute ext cmd */ if (cmdptr->name == NULL) { - ret = Execute (line, com, rest); + ret = Execute (line, com, rest, Cmd); break; }
@@ -866,7 +866,6 @@ BOOL ExecuteCommand(PARSED_COMMAND *Cmd) { - BOOL bNewBatch = TRUE; PARSED_COMMAND *Sub; LPTSTR ExpandedLine; BOOL Success = TRUE; @@ -877,20 +876,14 @@ switch (Cmd->Type) { case C_COMMAND: - if(bc) - bNewBatch = FALSE; - ExpandedLine = DoDelayedExpansion(Cmd->Command.CommandLine); if (!ExpandedLine) { Success = FALSE; break; } - Success = DoCommand(ExpandedLine); + Success = DoCommand(ExpandedLine, Cmd); cmd_free(ExpandedLine); - - if(bNewBatch && bc) - AddBatchRedirection(&Cmd->Redirections); break; case C_QUIET: case C_BLOCK: @@ -1330,7 +1323,7 @@ LPTSTR ip;
/* if no batch input then... */ - if (!(ip = ReadBatchLine())) + if (bc == NULL) { if (bNoInteractive) { @@ -1360,6 +1353,9 @@ } else { + ip = ReadBatchLine(); + if (!ip) + return FALSE; bIsBatch = TRUE; }
@@ -1378,17 +1374,8 @@ if (!Cmd) continue;
- /* JPP 19980807 */ - /* Echo batch file line */ - if (bIsBatch && bEcho && Cmd->Type != C_QUIET) - { - PrintPrompt (); - EchoCommand(Cmd); - ConOutChar(_T('\n')); - } - ExecuteCommand(Cmd); - if (bEcho && !bIgnoreEcho && (!bIsBatch || Cmd->Type != C_QUIET)) + if (bEcho && !bIgnoreEcho) ConOutChar ('\n'); FreeCommand(Cmd); bIgnoreEcho = FALSE;
Modified: trunk/reactos/base/shell/cmd/cmd.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.h?rev=39... ============================================================================== --- trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] Tue Mar 3 23:06:54 2009 @@ -104,7 +104,7 @@ VOID RemoveBreakHandler (VOID); BOOL SubstituteForVars(TCHAR *Src, TCHAR *Dest); LPTSTR DoDelayedExpansion(LPTSTR Line); -BOOL DoCommand (LPTSTR line); +BOOL DoCommand (LPTSTR line, struct _PARSED_COMMAND *Cmd); BOOL ReadLine(TCHAR *commandline, BOOL bMore); int cmd_main (int argc, const TCHAR *argv[]);
Modified: trunk/reactos/base/shell/cmd/internal.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/internal.c?r... ============================================================================== --- trunk/reactos/base/shell/cmd/internal.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/internal.c [iso-8859-1] Tue Mar 3 23:06:54 2009 @@ -707,7 +707,7 @@ LPTSTR NewCommand = cmd_alloc((_tcslen(param)+4)*sizeof(TCHAR)); _tcscpy(NewCommand, param); _tcscat(NewCommand, _T(" /?")); - DoCommand(NewCommand); + DoCommand(NewCommand, NULL); cmd_free(NewCommand); } /* Else, display detailed commands list */