1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
/*
** Copyright 2000-2006 Double Precision, Inc.
** See COPYING for distribution information.
*/
#include "config.h"
#include "waitlib.h"
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
static const char rcsid[]="$Id: waitlib2.c,v 1.2 2006/05/28 15:29:52 mrsam Exp $";
static pid_t *static_pid_buf=0;
static void start_reaper(pid_t pid, int exit_stat)
{
}
static RETSIGTYPE start_reap(int signum)
{
wait_reap(start_reaper, start_reap);
#if RETSIGTYPE != void
return (0);
#endif
}
void wait_forchild( void (*)(pid_t, int), /* Reaper */
RETSIGTYPE (*)(int)); /* Signal handler stub */
int wait_startchildren(unsigned nchildren, pid_t **pidptr)
{
int pipefd[2];
pid_t p;
unsigned i;
if (!pidptr)
{
if (static_pid_buf) free(static_pid_buf);
static_pid_buf=0;
pidptr= &static_pid_buf;
}
if (*pidptr == 0 && (*pidptr=malloc(nchildren * sizeof(pid_t))) == 0)
return (-1);
if (pipe(pipefd) < 0) return (-1);
signal(SIGCHLD, start_reap);
wait_block();
for (i=0; i<nchildren; i++)
{
p=fork();
if (p < 0)
{
while (i)
{
kill( (*pidptr)[--i], SIGKILL);
wait_forchild(start_reaper, start_reap);
}
close(pipefd[0]);
close(pipefd[1]);
wait_clear(start_reap);
signal(SIGCHLD, SIG_DFL);
return (-1);
}
if (p == 0)
{
char buf;
wait_restore();
close(pipefd[1]);
if (read(pipefd[0], &buf, 1) != 1)
exit(1);
close(pipefd[0]);
return (1);
}
(*pidptr)[i]=p;
}
wait_restore();
close(pipefd[0]);
for (i=0; i<nchildren; i++)
if (write(pipefd[1], "", 1) < 0)
; /* Shut gcc up */
close(pipefd[1]);
return (0);
}
int wait_reforkchild(unsigned nchildren, pid_t *pidptr, pid_t pid)
{
unsigned i;
for (i=0; i<nchildren; i++)
if (pidptr[i] == pid) break;
if (i >= nchildren) return (0);
switch ((pidptr[i]=fork())) {
case 0:
wait_restore(); /* Just in case */
return (1);
case -1:
return (-1);
default:
break;
}
return (0);
}
|