[ros-diffs] [jmorlan] 39858: 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.

jmorlan at svn.reactos.org jmorlan at svn.reactos.org
Tue Mar 3 21:06:55 CET 2009


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=39858&r1=39857&r2=39858&view=diff
==============================================================================
--- 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=39858&r1=39857&r2=39858&view=diff
==============================================================================
--- 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=39858&r1=39857&r2=39858&view=diff
==============================================================================
--- 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=39858&r1=39857&r2=39858&view=diff
==============================================================================
--- 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=39858&r1=39857&r2=39858&view=diff
==============================================================================
--- 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?rev=39858&r1=39857&r2=39858&view=diff
==============================================================================
--- 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 */



More information about the Ros-diffs mailing list