(spawn): Return subprocess return code as an argument.
Explicitly copy environment block.
(main): Update to use return value argument with spawn.
Retry if spawn failed when a subshell was not tried.
vfprintf (stderr, msg, args);
va_end (args);
vfprintf (stderr, msg, args);
va_end (args);
+/* Change from normal usage; return value indicates whether spawn
+ succeeded or failed - program return code is returned separately. */
-spawn (char * progname, char * cmdline)
+spawn (char * progname, char * cmdline, int * retcode)
SECURITY_ATTRIBUTES sec_attrs;
STARTUPINFO start;
SECURITY_ATTRIBUTES sec_attrs;
STARTUPINFO start;
+ /* In theory, passing NULL for the environment block to CreateProcess
+ is the same as passing the value of GetEnvironmentStrings, but
+ doing this explicitly seems to cure problems running DOS programs
+ in some cases. */
char * envblock = GetEnvironmentStrings ();
sec_attrs.nLength = sizeof (sec_attrs);
char * envblock = GetEnvironmentStrings ();
sec_attrs.nLength = sizeof (sec_attrs);
if (CreateProcess (progname, cmdline, &sec_attrs, NULL, TRUE,
0, envblock, NULL, &start, &child))
{
if (CreateProcess (progname, cmdline, &sec_attrs, NULL, TRUE,
0, envblock, NULL, &start, &child))
{
/* wait for completion and pass on return code */
WaitForSingleObject (child.hProcess, INFINITE);
/* wait for completion and pass on return code */
WaitForSingleObject (child.hProcess, INFINITE);
- GetExitCodeProcess (child.hProcess, &rc);
+ if (retcode)
+ GetExitCodeProcess (child.hProcess, (DWORD *)retcode);
CloseHandle (child.hThread);
CloseHandle (child.hProcess);
child.hProcess = NULL;
CloseHandle (child.hThread);
CloseHandle (child.hProcess);
child.hProcess = NULL;
FreeEnvironmentStrings (envblock);
FreeEnvironmentStrings (envblock);
}
/* Return size of current environment block. */
}
/* Return size of current environment block. */
/* We are being used as a helper to run a DOS app; just pass
command line to DOS app without change. */
/* TODO: fill in progname. */
/* We are being used as a helper to run a DOS app; just pass
command line to DOS app without change. */
/* TODO: fill in progname. */
- return spawn (NULL, GetCommandLine ());
+ if (spawn (NULL, GetCommandLine (), &rc))
+ return rc;
+ fail ("Could not run %s\n", GetCommandLine ());
}
/* Process command line. If running interactively (-c or /c not
}
/* Process command line. If running interactively (-c or /c not
if (need_shell)
{
char * p;
if (need_shell)
{
char * p;
if (!cmdline)
cmdline = progname;
if (!cmdline)
cmdline = progname;
- rc = spawn (progname, cmdline);
+ if (spawn (progname, cmdline, &rc))
+ return rc;
+ if (!need_shell)
+ {
+ need_shell = TRUE;
+ goto pass_to_shell;
+ }
+
+ fail ("Could not run %s\n", progname);
+
+ return 0;