home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- /* NAME
-
- /* invoke 3
-
- /* SUMMARY
-
- /* system-dependent process control stuff
-
- /* PROJECT
-
- /* pc-mail
-
- /* PACKAGE
-
- /* mailsh
-
- /* SYNOPSIS
-
- /* #include "status.h"
-
- /*
-
- /* int invokelp(arg0,arg1,...)
-
- /* char *arg0,*arg1,...
-
- /*
-
- /* int invokevp(argv)
-
- /* char **argv;
-
- /* DESCRIPTION
-
- /* invokelp() creates a child process to execute a command.
-
- /* arg0, arg1,... is a null-terminated list of string pointers,
-
- /* the first being the name of the program. Use is made
-
- /* of the search path to locate the program in arg0.
-
- /* With MS-DOS, batch files can only be executed if their name is
-
- /* given including the suffix.
-
- /*
-
- /* invokevp() is similar to invokelp; the difference is that
-
- /* argv is an array of pointers to arguments, and that MS-DOS batch
-
- /* files are not supported.
-
- /* DIAGNOSTICS
-
- /* invokelp(), invokevp() return the exit status of the child process,
-
- /* E_SYSFAIL if there were insufficient resources, and
-
- /* E_NOPROG if the program in arg0 or argv[0] could not be found.
-
- /* BUGS
-
- /* The invokexx() functions should not be used if the command involves
-
- /* shell built-ins, i/o redirection or other shell meta characters.
-
- /* AUTHOR(S)
-
- /* W.Z. Venema
-
- /* Eindhoven University of Technology
-
- /* Department of Mathematics and Computer Science
-
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
-
- /* CREATION DATE
-
- /* Sun Apr 5 15:27:37 GMT+1:00 1987
-
- /* LAST MODIFICATION
-
- /* 90/01/22 13:01:50
-
- /* VERSION/RELEASE
-
- /* 2.1
-
- /*--*/
-
-
-
- #include <stdio.h>
-
- #include <varargs.h>
-
- #include <errno.h>
-
-
-
- #include "defs.h"
-
- #include "status.h"
-
-
-
- #ifdef MSDOS
-
- #include <process.h>
-
- #endif
-
-
-
- /* invokelp - create child process to execute command */
-
-
-
- /* VARARGS */
-
-
-
- public int invokelp(va_alist)
-
- va_dcl
-
- {
-
- va_list ap;
-
- #ifdef lint
-
- static
-
- #endif
-
- char *argv[BUFSIZ];
-
- char **cpp = argv;
-
- #ifdef MSDOS
-
- char *cp;
-
-
-
- /*
-
- * Under MS-DOS, we must explicitly invoke a command processor in case of
-
- * batch files. If we see the command is a batch file we just stick a
-
- * command processor invocation in front of the argument vector. We try
-
- * to avoid the command processor since it presently does not return exit
-
- * status codes.
-
- */
-
-
-
- va_start(ap);
-
- cp = va_arg(ap, char *);
-
- if (istrcmp(cp + strlen(cp) - 4, ".bat") == 0) {
-
- *cpp++ = "command";
-
- *cpp++ = "/c";
-
- }
-
- va_end(ap);
-
- #endif
-
-
-
- /* Copy variable-length argument list to variable-length vector */
-
-
-
- va_start(ap);
-
- while (*cpp++ = va_arg(ap, char *))
-
- /* void */ ;
-
- va_end(ap);
-
-
-
- /* invokevp will do the rest */
-
-
-
- return (invokevp(argv));
-
-
-
- #if (!defined(unix) && !defined(MSDOS))
-
- "Specify how to do process management"
-
- #endif
-
- }
-
-
-
- /* invokevp - create child process to execute command */
-
-
-
- public int invokevp(argv)
-
- char **argv;
-
- {
-
- extern void _exit();
-
-
-
- /*
-
- * On unix systems we fork a process and overlay the child with the
-
- * desired program. This means we get -1 if the fork did not succeed,
-
- * otherwise the exit status of the child process. The code is a bit
-
- * elaborate since we want to handle various error conditions.
-
- */
-
- #ifdef unix
-
- register int pid;
-
-
-
- if ((pid = fork()) < 0) { /* fork off a process */
-
- return (E_SYSFAIL); /* resources exhausted */
-
- } else if (pid == 0) { /* this is the child process */
-
- (void) execvp(*argv, argv); /* try to replace it */
-
- _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL); /* sorry, failed */
-
- /* NOTREACHED */
-
- } else { /* this is the parent */
-
- int xstat,
-
- wstat;
-
-
-
- /* wait till above child terminates */
-
-
-
- while ((wstat = wait(&xstat)) != -1 && wstat != pid)
-
- /* void */ ;
-
- if (wstat == -1) {
-
- return (E_SYSFAIL); /* oops: no child! */
-
- } else if (xstat & 0377) {
-
- return (E_UNKNOWN); /* child was killed */
-
- } else {
-
- return (xstat >> 8); /* child died naturally */
-
- }
-
- /* NOTREACHED */
-
- }
-
- #endif
-
-
-
- /*
-
- * With MS-DOS, less can go wrong. On the other hand, MS-DOS can do less.
-
- */
-
- #ifdef MSDOS
-
- int stat;
-
-
-
- return ((stat = spawnvp(P_WAIT, *argv, argv)) >= 0 ?
-
- stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL));
-
- #endif
-
-
-
- #if (!defined(unix) && !defined(MSDOS))
-
- "Specify how to do process management"
-
- #endif
-
- }
-
-