home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / pcmail / main / invoke.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  4.6 KB  |  327 lines

  1. /*++
  2.  
  3. /* NAME
  4.  
  5. /*      invoke 3
  6.  
  7. /* SUMMARY
  8.  
  9. /*      system-dependent process control stuff
  10.  
  11. /* PROJECT
  12.  
  13. /*      pc-mail
  14.  
  15. /* PACKAGE
  16.  
  17. /*      mailsh
  18.  
  19. /* SYNOPSIS
  20.  
  21. /*      #include "status.h"
  22.  
  23. /*
  24.  
  25. /*    int invokelp(arg0,arg1,...)
  26.  
  27. /*      char *arg0,*arg1,...
  28.  
  29. /*
  30.  
  31. /*    int invokevp(argv)
  32.  
  33. /*    char **argv;
  34.  
  35. /* DESCRIPTION
  36.  
  37. /*      invokelp() creates a child process to execute a command.
  38.  
  39. /*      arg0, arg1,... is a null-terminated list of string pointers,
  40.  
  41. /*    the first being the name of the program. Use is made
  42.  
  43. /*    of the search path to locate the program in arg0.
  44.  
  45. /*    With MS-DOS, batch files can only be executed if their name is
  46.  
  47. /*    given including the suffix.
  48.  
  49. /*
  50.  
  51. /*    invokevp() is similar to invokelp; the difference is that
  52.  
  53. /*    argv is an array of pointers to arguments, and that MS-DOS batch
  54.  
  55. /*    files are not supported.
  56.  
  57. /* DIAGNOSTICS
  58.  
  59. /*    invokelp(), invokevp() return the exit status of the child process,
  60.  
  61. /*    E_SYSFAIL if there were insufficient resources, and
  62.  
  63. /*    E_NOPROG if the program in arg0 or argv[0] could not be found.
  64.  
  65. /* BUGS
  66.  
  67. /*    The invokexx() functions should not be used if the command involves
  68.  
  69. /*    shell built-ins, i/o redirection or other shell meta characters.
  70.  
  71. /* AUTHOR(S)
  72.  
  73. /*      W.Z. Venema
  74.  
  75. /*      Eindhoven University of Technology
  76.  
  77. /*      Department of Mathematics and Computer Science
  78.  
  79. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  80.  
  81. /* CREATION DATE
  82.  
  83. /*      Sun Apr  5 15:27:37 GMT+1:00 1987
  84.  
  85. /* LAST MODIFICATION
  86.  
  87. /*    90/01/22 13:01:50
  88.  
  89. /* VERSION/RELEASE
  90.  
  91. /*    2.1
  92.  
  93. /*--*/
  94.  
  95.  
  96.  
  97. #include <stdio.h>
  98.  
  99. #include <varargs.h>
  100.  
  101. #include <errno.h>
  102.  
  103.  
  104.  
  105. #include "defs.h"
  106.  
  107. #include "status.h"
  108.  
  109.  
  110.  
  111. #ifdef  MSDOS
  112.  
  113. #include <process.h>
  114.  
  115. #endif
  116.  
  117.  
  118.  
  119. /* invokelp - create child process to execute command */
  120.  
  121.  
  122.  
  123. /* VARARGS */
  124.  
  125.  
  126.  
  127. public int invokelp(va_alist) 
  128.  
  129. va_dcl
  130.  
  131. {
  132.  
  133.     va_list ap;
  134.  
  135. #ifdef lint
  136.  
  137.      static
  138.  
  139. #endif
  140.  
  141.     char   *argv[BUFSIZ];
  142.  
  143.     char  **cpp = argv;
  144.  
  145. #ifdef    MSDOS
  146.  
  147.     char   *cp;
  148.  
  149.  
  150.  
  151.     /*
  152.  
  153.      * Under MS-DOS, we must explicitly invoke a command processor in case of
  154.  
  155.      * batch files. If we see the command is a batch file we just stick a
  156.  
  157.      * command processor invocation in front of the argument vector. We try
  158.  
  159.      * to avoid the command processor since it presently does not return exit
  160.  
  161.      * status codes.
  162.  
  163.      */
  164.  
  165.  
  166.  
  167.     va_start(ap);
  168.  
  169.     cp = va_arg(ap, char *);
  170.  
  171.     if (istrcmp(cp + strlen(cp) - 4, ".bat") == 0) {
  172.  
  173.     *cpp++ = "command";
  174.  
  175.     *cpp++ = "/c";
  176.  
  177.     }
  178.  
  179.     va_end(ap);
  180.  
  181. #endif
  182.  
  183.  
  184.  
  185.     /* Copy variable-length argument list to variable-length vector */
  186.  
  187.  
  188.  
  189.     va_start(ap);
  190.  
  191.     while (*cpp++ = va_arg(ap, char *))
  192.  
  193.      /* void */ ;
  194.  
  195.     va_end(ap);
  196.  
  197.  
  198.  
  199.     /* invokevp will do the rest */
  200.  
  201.  
  202.  
  203.     return (invokevp(argv));
  204.  
  205.  
  206.  
  207. #if (!defined(unix) && !defined(MSDOS))
  208.  
  209.     "Specify how to do process management"
  210.  
  211. #endif
  212.  
  213. }
  214.  
  215.  
  216.  
  217. /* invokevp - create child process to execute command */
  218.  
  219.  
  220.  
  221. public int invokevp(argv)
  222.  
  223. char  **argv;
  224.  
  225. {
  226.  
  227.     extern void _exit();
  228.  
  229.  
  230.  
  231.     /*
  232.  
  233.      * On unix systems we fork a process and overlay the child with the
  234.  
  235.      * desired program. This means we get -1 if the fork did not succeed,
  236.  
  237.      * otherwise the exit status of the child process. The code is a bit
  238.  
  239.      * elaborate since we want to handle various error conditions.
  240.  
  241.      */
  242.  
  243. #ifdef unix
  244.  
  245.     register int pid;
  246.  
  247.  
  248.  
  249.     if ((pid = fork()) < 0) {            /* fork off a process */
  250.  
  251.     return (E_SYSFAIL);            /* resources exhausted */
  252.  
  253.     } else if (pid == 0) {            /* this is the child process */
  254.  
  255.     (void) execvp(*argv, argv);        /* try to replace it */
  256.  
  257.     _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL);    /* sorry, failed */
  258.  
  259.     /* NOTREACHED */
  260.  
  261.     } else {                    /* this is the parent */
  262.  
  263.     int     xstat,
  264.  
  265.             wstat;
  266.  
  267.  
  268.  
  269.     /* wait till above child terminates */
  270.  
  271.  
  272.  
  273.     while ((wstat = wait(&xstat)) != -1 && wstat != pid)
  274.  
  275.          /* void */ ;
  276.  
  277.     if (wstat == -1) {
  278.  
  279.         return (E_SYSFAIL);            /* oops: no child! */
  280.  
  281.     } else if (xstat & 0377) {
  282.  
  283.         return (E_UNKNOWN);            /* child was killed */
  284.  
  285.     } else {
  286.  
  287.         return (xstat >> 8);        /* child died naturally */
  288.  
  289.     }
  290.  
  291.     /* NOTREACHED */
  292.  
  293.     }
  294.  
  295. #endif
  296.  
  297.  
  298.  
  299.     /*
  300.  
  301.      * With MS-DOS, less can go wrong. On the other hand, MS-DOS can do less.
  302.  
  303.      */
  304.  
  305. #ifdef MSDOS
  306.  
  307.     int     stat;
  308.  
  309.  
  310.  
  311.     return ((stat = spawnvp(P_WAIT, *argv, argv)) >= 0 ?
  312.  
  313.         stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL));
  314.  
  315. #endif
  316.  
  317.  
  318.  
  319. #if (!defined(unix) && !defined(MSDOS))
  320.  
  321.     "Specify how to do process management"
  322.  
  323. #endif
  324.  
  325. }
  326.  
  327.