Mercurial > emacs
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 } |