home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / libstuff / execute.c < prev    next >
C/C++ Source or Header  |  1995-10-12  |  3KB  |  125 lines

  1. #include <bsd/libc.h> /* first to get rid of pre-comp warning */
  2. #include <mach/mach.h> /* first to get rid of pre-comp warning */
  3. #include "stdio.h"
  4. #include <signal.h>
  5. #include <sys/wait.h>
  6. #include "stuff/errors.h"
  7. #include "stuff/allocate.h"
  8. #include "stuff/execute.h"
  9.  
  10. /*
  11.  * execute() does an execvp using the argv passed to it.  If the parameter
  12.  * verbose is non-zero the command is printed to stderr.  A non-zero return
  13.  * value indicates success zero indicates failure.
  14.  */
  15. __private_extern__
  16. int
  17. execute(
  18. char **argv,
  19. long verbose)
  20. {
  21.     char *name, **p;
  22.     int forkpid, waitpid, termsig;
  23. #ifdef __TEFLON__
  24.     int waitstatus;
  25. #else
  26.     union wait waitstatus;
  27. #endif
  28.  
  29.     name = argv[0];
  30.  
  31.     if(verbose){
  32.         fprintf(stderr, "+ %s ", name);
  33.         p = &(argv[1]);
  34.         while(*p != (char *)0)
  35.             fprintf(stderr, "%s ", *p++);
  36.         fprintf(stderr, "\n");
  37.     }
  38.  
  39.     forkpid = fork();
  40.     if(forkpid == -1)
  41.         system_fatal("can't fork a new process to execute: %s", name);
  42.  
  43.     if(forkpid == 0){
  44.         if(execvp(name, argv) == -1)
  45.         system_fatal("can't find or exec: %s", name);
  46.         return(1); /* can't get here, removes a warning from the compiler */
  47.     }
  48.     else{
  49.         waitpid = wait(&waitstatus);
  50.         if(waitpid == -1)
  51.         system_fatal("wait on forked process %d failed", forkpid);
  52. #ifdef __TEFLON__
  53.         termsig = WTERMSIG(waitstatus);
  54. #else
  55.         termsig = waitstatus.w_termsig;
  56. #endif
  57.         if(termsig != 0 && termsig != SIGINT)
  58.         fatal("fatal error in %s", name);
  59.         return(
  60. #ifdef __TEFLON__
  61.         WEXITSTATUS(waitstatus) &&
  62. #else
  63.         waitstatus.w_retcode == 0 &&
  64. #endif
  65.         termsig == 0);
  66.     }
  67. }
  68.  
  69. /*
  70.  * runlist is used by the routine execute_list() to execute a program and it 
  71.  * contains the command line arguments.  Strings are added to it by
  72.  * add_execute_list().  The routine reset_execute_list() resets it for new use.
  73.  */
  74. static struct {
  75.     int size;
  76.     int next;
  77.     char **strings;
  78. } runlist;
  79.  
  80. /*
  81.  * This routine is passed a string to be added to the list of strings for 
  82.  * command line arguments.
  83.  */
  84. __private_extern__
  85. void
  86. add_execute_list(
  87. char *str)
  88. {
  89.     if(runlist.strings == (char **)0){
  90.         runlist.next = 0;
  91.         runlist.size = 128;
  92.         runlist.strings = allocate(runlist.size * sizeof(char **));
  93.     }
  94.     if(runlist.next + 1 >= runlist.size){
  95.         runlist.strings = reallocate(runlist.strings,
  96.                 (runlist.size * 2) * sizeof(char **));
  97.         runlist.size *= 2;
  98.     }
  99.     runlist.strings[runlist.next++] = str;
  100.     runlist.strings[runlist.next] = (char *)0;
  101. }
  102.  
  103. /*
  104.  * This routine reset the list of strings of command line arguments so that
  105.  * an new command line argument list can be built.
  106.  */
  107. __private_extern__
  108. void
  109. reset_execute_list(void)
  110. {
  111.     runlist.next = 0;
  112. }
  113.  
  114. /*
  115.  * This routine calls execute() to run the command built up in the runlist
  116.  * strings.
  117.  */
  118. __private_extern__
  119. int
  120. execute_list(
  121. long verbose)
  122. {
  123.     return(execute(runlist.strings, verbose));
  124. }
  125.