|
Packit |
bf707c |
/* @(#)spawn.c 1.16 03/07/13 Copyright 1985, 1989, 1995-2003 J. Schilling */
|
|
Packit |
bf707c |
/*
|
|
Packit |
bf707c |
* Spawn another process/ wait for child process
|
|
Packit |
bf707c |
*
|
|
Packit |
bf707c |
* Copyright (c) 1985, 1989, 1995-2003 J. Schilling
|
|
Packit |
bf707c |
*/
|
|
Packit |
bf707c |
/*
|
|
Packit |
bf707c |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
bf707c |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
bf707c |
* the Free Software Foundation; either version 2, or (at your option)
|
|
Packit |
bf707c |
* any later version.
|
|
Packit |
bf707c |
*
|
|
Packit |
bf707c |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
bf707c |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
bf707c |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
bf707c |
* GNU General Public License for more details.
|
|
Packit |
bf707c |
*
|
|
Packit |
bf707c |
* You should have received a copy of the GNU General Public License along with
|
|
Packit |
bf707c |
* this program; see the file COPYING. If not, write to the Free Software
|
|
Packit |
bf707c |
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
Packit |
bf707c |
*/
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
#include <mconfig.h>
|
|
Packit |
bf707c |
#include <stdio.h>
|
|
Packit |
bf707c |
#include <standard.h>
|
|
Packit |
bf707c |
#define fspawnl __nothing__ /* prototype in schily.h is wrong */
|
|
Packit |
bf707c |
#define spawnl __nothing__ /* prototype in schily.h is wrong */
|
|
Packit |
bf707c |
#include <schily.h>
|
|
Packit |
bf707c |
#undef fspawnl
|
|
Packit |
bf707c |
#undef spawnl
|
|
Packit |
bf707c |
#include <unixstd.h>
|
|
Packit |
bf707c |
#include <stdxlib.h>
|
|
Packit |
bf707c |
#include <vadefs.h>
|
|
Packit |
bf707c |
#include <waitdefs.h>
|
|
Packit |
bf707c |
#include <errno.h>
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
#define MAX_F_ARGS 16
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
EXPORT int fspawnl __PR((FILE *, FILE *, FILE *, ...));
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
EXPORT int
|
|
Packit |
bf707c |
fspawnv(in, out, err, argc, argv)
|
|
Packit |
bf707c |
FILE *in;
|
|
Packit |
bf707c |
FILE *out;
|
|
Packit |
bf707c |
FILE *err;
|
|
Packit |
bf707c |
int argc;
|
|
Packit |
bf707c |
char * const argv[];
|
|
Packit |
bf707c |
{
|
|
Packit |
bf707c |
int pid;
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
if ((pid = fspawnv_nowait(in, out, err, argv[0], argc, argv)) < 0)
|
|
Packit |
bf707c |
return (pid);
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
return (wait_chld(pid));
|
|
Packit |
bf707c |
}
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
/* VARARGS5 */
|
|
Packit |
bf707c |
#ifdef PROTOTYPES
|
|
Packit |
bf707c |
EXPORT int
|
|
Packit |
bf707c |
fspawnl(FILE *in, FILE *out, FILE *err, ...)
|
|
Packit |
bf707c |
#else
|
|
Packit |
bf707c |
EXPORT int
|
|
Packit |
bf707c |
fspawnl(in, out, err, va_alist)
|
|
Packit |
bf707c |
FILE *in;
|
|
Packit |
bf707c |
FILE *out;
|
|
Packit |
bf707c |
FILE *err;
|
|
Packit |
bf707c |
va_dcl
|
|
Packit |
bf707c |
#endif
|
|
Packit |
bf707c |
{
|
|
Packit |
bf707c |
va_list args;
|
|
Packit |
bf707c |
int ac = 0;
|
|
Packit |
bf707c |
char *xav[MAX_F_ARGS];
|
|
Packit |
bf707c |
char **av;
|
|
Packit |
bf707c |
char **pav;
|
|
Packit |
bf707c |
char *p;
|
|
Packit |
bf707c |
int ret;
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
#ifdef PROTOTYPES
|
|
Packit |
bf707c |
va_start(args, err);
|
|
Packit |
bf707c |
#else
|
|
Packit |
bf707c |
va_start(args);
|
|
Packit |
bf707c |
#endif
|
|
Packit |
bf707c |
while (va_arg(args, char *) != NULL)
|
|
Packit |
bf707c |
ac++;
|
|
Packit |
bf707c |
va_end(args);
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
if (ac < MAX_F_ARGS) {
|
|
Packit |
bf707c |
pav = av = xav;
|
|
Packit |
bf707c |
} else {
|
|
Packit |
bf707c |
pav = av = (char **)malloc((ac+1)*sizeof (char *));
|
|
Packit |
bf707c |
if (av == 0)
|
|
Packit |
bf707c |
return (-1);
|
|
Packit |
bf707c |
}
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
#ifdef PROTOTYPES
|
|
Packit |
bf707c |
va_start(args, err);
|
|
Packit |
bf707c |
#else
|
|
Packit |
bf707c |
va_start(args);
|
|
Packit |
bf707c |
#endif
|
|
Packit |
bf707c |
do {
|
|
Packit |
bf707c |
p = va_arg(args, char *);
|
|
Packit |
bf707c |
*pav++ = p;
|
|
Packit |
bf707c |
} while (p != NULL);
|
|
Packit |
bf707c |
va_end(args);
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
ret = fspawnv(in, out, err, ac, av);
|
|
Packit |
bf707c |
if (av != xav)
|
|
Packit |
bf707c |
free(av);
|
|
Packit |
bf707c |
return (ret);
|
|
Packit |
bf707c |
}
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
EXPORT int
|
|
Packit |
bf707c |
fspawnv_nowait(in, out, err, name, argc, argv)
|
|
Packit |
bf707c |
FILE *in;
|
|
Packit |
bf707c |
FILE *out;
|
|
Packit |
bf707c |
FILE *err;
|
|
Packit |
bf707c |
const char *name;
|
|
Packit |
bf707c |
int argc;
|
|
Packit |
bf707c |
char * const argv[];
|
|
Packit |
bf707c |
{
|
|
Packit |
bf707c |
int pid = -1; /* Initialization needed to make GCC happy */
|
|
Packit |
bf707c |
int i;
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
for (i = 1; i < 64; i *= 2) {
|
|
Packit |
bf707c |
if ((pid = fork()) >= 0)
|
|
Packit |
bf707c |
break;
|
|
Packit |
bf707c |
sleep(i);
|
|
Packit |
bf707c |
}
|
|
Packit |
bf707c |
if (pid != 0)
|
|
Packit |
bf707c |
return (pid);
|
|
Packit |
bf707c |
/*
|
|
Packit |
bf707c |
* silly: fexecv must set av[ac] = NULL
|
|
Packit |
bf707c |
* so we have to cast argv tp (char **)
|
|
Packit |
bf707c |
*/
|
|
Packit |
bf707c |
fexecv(name, in, out, err, argc, (char **)argv);
|
|
Packit |
bf707c |
exit(geterrno());
|
|
Packit |
bf707c |
/* NOTREACHED */
|
|
Packit |
bf707c |
#ifndef lint
|
|
Packit |
bf707c |
return (0); /* keep gnu compiler happy */
|
|
Packit |
bf707c |
#endif
|
|
Packit |
bf707c |
}
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
EXPORT int
|
|
Packit |
bf707c |
wait_chld(pid)
|
|
Packit |
bf707c |
int pid;
|
|
Packit |
bf707c |
{
|
|
Packit |
bf707c |
int died;
|
|
Packit |
bf707c |
WAIT_T status;
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
do {
|
|
Packit |
bf707c |
do {
|
|
Packit |
bf707c |
died = wait(&status);
|
|
Packit |
bf707c |
} while (died < 0 && geterrno() == EINTR);
|
|
Packit |
bf707c |
if (died < 0)
|
|
Packit |
bf707c |
return (died);
|
|
Packit |
bf707c |
} while (died != pid);
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
if (WCOREDUMP(status))
|
|
Packit |
bf707c |
unlink("core");
|
|
Packit |
bf707c |
|
|
Packit |
bf707c |
return (WEXITSTATUS(status));
|
|
Packit |
bf707c |
}
|