comparison nt/cmdproxy.c @ 21598:235f717e6916

(fail): Exit with a negative return value. (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.
author Geoff Voelker <voelker@cs.washington.edu>
date Fri, 17 Apr 1998 05:04:21 +0000
parents f645084cc96c
children a373669e1196
comparison
equal deleted inserted replaced
21597:409211e285bc 21598:235f717e6916
88 88
89 va_start (args, msg); 89 va_start (args, msg);
90 vfprintf (stderr, msg, args); 90 vfprintf (stderr, msg, args);
91 va_end (args); 91 va_end (args);
92 92
93 exit (1); 93 exit (-1);
94 } 94 }
95 95
96 void 96 void
97 warn (char * msg, ...) 97 warn (char * msg, ...)
98 { 98 {
364 #endif 364 #endif
365 } 365 }
366 return TRUE; 366 return TRUE;
367 } 367 }
368 368
369 int 369 /* Change from normal usage; return value indicates whether spawn
370 spawn (char * progname, char * cmdline) 370 succeeded or failed - program return code is returned separately. */
371 { 371 int
372 DWORD rc = 0xff; 372 spawn (char * progname, char * cmdline, int * retcode)
373 {
374 BOOL success = FALSE;
373 SECURITY_ATTRIBUTES sec_attrs; 375 SECURITY_ATTRIBUTES sec_attrs;
374 STARTUPINFO start; 376 STARTUPINFO start;
377 /* In theory, passing NULL for the environment block to CreateProcess
378 is the same as passing the value of GetEnvironmentStrings, but
379 doing this explicitly seems to cure problems running DOS programs
380 in some cases. */
375 char * envblock = GetEnvironmentStrings (); 381 char * envblock = GetEnvironmentStrings ();
376 382
377 sec_attrs.nLength = sizeof (sec_attrs); 383 sec_attrs.nLength = sizeof (sec_attrs);
378 sec_attrs.lpSecurityDescriptor = NULL; 384 sec_attrs.lpSecurityDescriptor = NULL;
379 sec_attrs.bInheritHandle = FALSE; 385 sec_attrs.bInheritHandle = FALSE;
382 start.cb = sizeof (start); 388 start.cb = sizeof (start);
383 389
384 if (CreateProcess (progname, cmdline, &sec_attrs, NULL, TRUE, 390 if (CreateProcess (progname, cmdline, &sec_attrs, NULL, TRUE,
385 0, envblock, NULL, &start, &child)) 391 0, envblock, NULL, &start, &child))
386 { 392 {
393 success = TRUE;
387 /* wait for completion and pass on return code */ 394 /* wait for completion and pass on return code */
388 WaitForSingleObject (child.hProcess, INFINITE); 395 WaitForSingleObject (child.hProcess, INFINITE);
389 GetExitCodeProcess (child.hProcess, &rc); 396 if (retcode)
397 GetExitCodeProcess (child.hProcess, (DWORD *)retcode);
390 CloseHandle (child.hThread); 398 CloseHandle (child.hThread);
391 CloseHandle (child.hProcess); 399 CloseHandle (child.hProcess);
392 child.hProcess = NULL; 400 child.hProcess = NULL;
393 } 401 }
394 402
395 FreeEnvironmentStrings (envblock); 403 FreeEnvironmentStrings (envblock);
396 404
397 return (int) rc; 405 return success;
398 } 406 }
399 407
400 /* Return size of current environment block. */ 408 /* Return size of current environment block. */
401 int 409 int
402 get_env_size () 410 get_env_size ()
452 || stricmp (modname, path) != 0) 460 || stricmp (modname, path) != 0)
453 { 461 {
454 /* We are being used as a helper to run a DOS app; just pass 462 /* We are being used as a helper to run a DOS app; just pass
455 command line to DOS app without change. */ 463 command line to DOS app without change. */
456 /* TODO: fill in progname. */ 464 /* TODO: fill in progname. */
457 return spawn (NULL, GetCommandLine ()); 465 if (spawn (NULL, GetCommandLine (), &rc))
466 return rc;
467 fail ("Could not run %s\n", GetCommandLine ());
458 } 468 }
459 469
460 /* Process command line. If running interactively (-c or /c not 470 /* Process command line. If running interactively (-c or /c not
461 specified) then spawn a real command shell, passing it the command 471 specified) then spawn a real command shell, passing it the command
462 line arguments. 472 line arguments.
566 if (progname != NULL) 576 if (progname != NULL)
567 need_shell = FALSE; 577 need_shell = FALSE;
568 } 578 }
569 } 579 }
570 580
581 pass_to_shell:
571 if (need_shell) 582 if (need_shell)
572 { 583 {
573 char * p; 584 char * p;
574 int extra_arg_space = 0; 585 int extra_arg_space = 0;
575 586
647 fail ("Internal error: program name not defined\n"); 658 fail ("Internal error: program name not defined\n");
648 659
649 if (!cmdline) 660 if (!cmdline)
650 cmdline = progname; 661 cmdline = progname;
651 662
652 rc = spawn (progname, cmdline); 663 if (spawn (progname, cmdline, &rc))
653 664 return rc;
654 return rc; 665
655 } 666 if (!need_shell)
667 {
668 need_shell = TRUE;
669 goto pass_to_shell;
670 }
671
672 fail ("Could not run %s\n", progname);
673
674 return 0;
675 }