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=…
==============================================================================
--- 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=3…
==============================================================================
--- 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=3…
==============================================================================
--- 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?…
==============================================================================
--- 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 */