home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume3 / pcmail / part05 / invoke.c < prev    next >
C/C++ Source or Header  |  1989-02-03  |  5KB  |  179 lines

  1. /*++
  2. /* NAME
  3. /*      invoke 3
  4. /* SUMMARY
  5. /*      system-dependent process control stuff
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      mailsh
  10. /* SYNOPSIS
  11. /*      #include "status.h"
  12. /*
  13. /*    int invokelp(arg0,arg1,...)
  14. /*      char *arg0,*arg1,...
  15. /*
  16. /*    int invokevp(argv)
  17. /*    char **argv;
  18. /*
  19. /*    int onexit(command)
  20. /*    char *command;
  21. /* DESCRIPTION
  22. /*      invokelp() creates a child process to execute a command.
  23. /*      arg0, arg1,... is a null-terminated list of string pointers,
  24. /*    the first being the name of the program. Use is made
  25. /*    of the search path to locate the program in arg0.
  26. /*
  27. /*    invokevp() is similar to invokelp; the difference is that
  28. /*    argv is an array of pointers to arguments.
  29. /*
  30. /*    onexit() executes a command, thereby terminating the current process.
  31. /* DIAGNOSTICS
  32. /*    invokelp(), invokevp() return the exit status of the child process, 
  33. /*    E_SYSFAIL if there were insufficient resources, and
  34. /*    E_NOPROG if the program in arg0 or argv[0] could not be found.
  35. /*
  36. /*    onexit() return -1 if there were problems.
  37. /* BUGS
  38. /*    The invokexx() functions should not be used if the command needs to 
  39. /*    be handled by a command-language processor (e.g. shell built-ins,
  40. /*    or i/o redirection).
  41. /* AUTHOR(S)
  42. /*      W.Z. Venema
  43. /*      Eindhoven University of Technology
  44. /*      Department of Mathematics and Computer Science
  45. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  46. /* CREATION DATE
  47. /*      Sun Apr  5 15:27:37 GMT+1:00 1987
  48. /* LAST MODIFICATION
  49. /*    Wed Apr  6 00:19:56 MET 1988
  50. /* VERSION/RELEASE
  51. /*    1.4
  52. /*--*/
  53.  
  54. #include <errno.h>
  55. #include "defs.h"
  56. #include "status.h"
  57.  
  58. #ifdef  MSDOS
  59. #include <process.h>
  60. #endif
  61.  
  62. /* invokelp - create child process to execute command */
  63.  
  64. /* VARARGS2 */
  65.  
  66. public int invokelp(arg0,arg1,arg2,arg3,arg4)
  67. char *arg0,*arg1,*arg2,*arg3,*arg4;
  68. {
  69.     /*
  70.     * On unix systems we fork a process and overlay the child with
  71.     * the desired program.
  72.     * This means we get -1 if the fork did not succeed, otherwise
  73.     * the exit status if the child process. The code is a bit elaborate
  74.     * since we want to handle various error conditions.
  75.     */
  76. #ifdef unix
  77.     register int pid;
  78.  
  79.     if ((pid = fork()) < 0) {        /* fork off a process */
  80.     return(E_SYSFAIL);        /* resources exhausted */
  81.     } else if (pid == 0) {        /* this is the child process */
  82.     execlp(arg0,arg0,arg1,arg2,arg3,arg4);/* try to replace it */
  83.     _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL); /* sorry, failed */
  84.     /* NOTREACHED */
  85.     } else {
  86.     int xstat,wstat;        /* wait till above child terminates */
  87.     while ((wstat = wait(&xstat)) != -1 && wstat != pid)
  88.         /* void */ ;
  89.     if (wstat == -1) {
  90.         return(E_SYSFAIL);        /* oops: no child! */
  91.     } else if (xstat&0377) {
  92.         return(E_UNKNOWN);        /* child was killed */
  93.     } else {
  94.         return(xstat>>8);        /* child died naturally */
  95.     }
  96.     /* NOTREACHED */
  97.     }
  98. #endif
  99.  
  100.     /*
  101.     * On MS-DOS systems we try to avoid the command.com shell because
  102.     * it always returns a zero status code. 
  103.     */
  104. #ifdef MSDOS
  105.     int stat;
  106.     char *p;
  107.  
  108.     if ((stat = spawnlp(P_WAIT,arg0,arg0,arg1,arg2,arg3,arg4)) < 0
  109.     && errno == ENOENT 
  110.     && (strcmp(p = arg0+strlen(arg0)-4,".bat") == 0 || strcmp(p,".BAT") == 0))
  111.     stat = spawnlp(P_WAIT,"command","command","/c",arg0,arg1,arg2,arg3,arg4);
  112.     return(stat >= 0 ? stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL));
  113. #endif
  114. }
  115.  
  116. /* invokelp - create child process to execute command */
  117.  
  118. public int invokevp(argv)
  119. char **argv;
  120. {
  121.     /*
  122.     * On unix systems we fork a process and overlay the child with
  123.     * the desired program.
  124.     * This means we get -1 if the fork did not succeed, otherwise
  125.     * the exit status if the child process. The code is a bit elaborate
  126.     * since we want to handle various error conditions.
  127.     */
  128. #ifdef unix
  129.     register int pid;
  130.  
  131.     if ((pid = fork()) < 0) {        /* fork off a process */
  132.     return(E_SYSFAIL);        /* resources exhausted */
  133.     } else if (pid == 0) {        /* this is the child process */
  134.     execvp(*argv,argv);        /* try to replace it */
  135.     _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL); /* sorry, failed */
  136.     /* NOTREACHED */
  137.     } else {
  138.     int xstat,wstat;        /* wait till above child terminates */
  139.     while ((wstat = wait(&xstat)) != -1 && wstat != pid)
  140.         /* void */ ;
  141.     if (wstat == -1) {
  142.         return(E_SYSFAIL);        /* oops: no child! */
  143.     } else if (xstat&0377) {
  144.         return(E_UNKNOWN);        /* child was killed */
  145.     } else {
  146.         return(xstat>>8);        /* child died naturally */
  147.     }
  148.     /* NOTREACHED */
  149.     }
  150. #endif
  151.  
  152.     /*
  153.     * On MS-DOS systems we try to avoid the command.com shell because
  154.     * it always returns a zero status code. 
  155.     */
  156. #ifdef MSDOS
  157.     int stat;
  158.  
  159.     return((stat = spawnvp(P_WAIT,*argv,argv)) >= 0 ? 
  160.     stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL));
  161. #endif
  162. }
  163.  
  164. /* onexit - exec another command */
  165.  
  166. int onexit(command)
  167. char *command;
  168. {
  169.     if (command && *command) {
  170. #ifdef unix
  171.     return(execlp("/bin/sh","sh","-c",command));
  172. #endif
  173.  
  174. #ifdef MSDOS
  175.     return(system(command));
  176. #endif
  177.     }
  178. }
  179.