Back to index

courier  0.68.2
waitlib2.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2000-2006 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #include      "config.h"
00007 #include      "waitlib.h"
00008 #include      <stdlib.h>
00009 #include      <sys/types.h>
00010 #include      <string.h>
00011 #include      <signal.h>
00012 #if    HAVE_UNISTD_H
00013 #include      <unistd.h>
00014 #endif
00015 
00016 
00017 static pid_t *static_pid_buf=0;
00018 
00019 static void start_reaper(pid_t pid, int exit_stat)
00020 {
00021 }
00022 
00023 static RETSIGTYPE start_reap(int signum)
00024 {
00025        wait_reap(start_reaper, start_reap);
00026 
00027 #if    RETSIGTYPE != void
00028        return (0);
00029 #endif
00030 }
00031 
00032 void wait_forchild( void (*)(pid_t, int), /* Reaper */
00033         RETSIGTYPE (*)(int));   /* Signal handler stub */
00034 
00035 int wait_startchildren(unsigned nchildren, pid_t **pidptr)
00036 {
00037 int    pipefd[2];
00038 pid_t  p;
00039 unsigned i;
00040 
00041        if (!pidptr)
00042        {
00043               if (static_pid_buf)  free(static_pid_buf);
00044               static_pid_buf=0;
00045               pidptr= &static_pid_buf;
00046        }
00047 
00048        if (*pidptr == 0 && (*pidptr=malloc(nchildren * sizeof(pid_t))) == 0)
00049               return (-1);
00050 
00051        if (pipe(pipefd) < 0)       return (-1);
00052 
00053        signal(SIGCHLD, start_reap);
00054        wait_block();
00055        for (i=0; i<nchildren; i++)
00056        {
00057               p=fork();
00058               if (p < 0)
00059               {
00060                      while (i)
00061                      {
00062                             kill( (*pidptr)[--i], SIGKILL);
00063                             wait_forchild(start_reaper, start_reap);
00064                      }
00065                      close(pipefd[0]);
00066                      close(pipefd[1]);
00067                      wait_clear(start_reap);
00068                      signal(SIGCHLD, SIG_DFL);
00069                      return (-1);
00070               }
00071 
00072               if (p == 0)
00073               {
00074               char   buf;
00075 
00076                      wait_restore();
00077                      close(pipefd[1]);
00078                      if (read(pipefd[0], &buf, 1) != 1)
00079                             exit(1);
00080                      close(pipefd[0]);
00081                      return (1);
00082               }
00083 
00084               (*pidptr)[i]=p;
00085        }
00086        wait_restore();
00087        close(pipefd[0]);
00088        for (i=0; i<nchildren; i++)
00089               if (write(pipefd[1], "", 1) < 0)
00090                      ; /* Shut gcc up */
00091        close(pipefd[1]);
00092        return (0);
00093 }
00094 
00095 int wait_reforkchild(unsigned nchildren, pid_t *pidptr, pid_t pid)
00096 {
00097 unsigned i;
00098 
00099        for (i=0; i<nchildren; i++)
00100               if (pidptr[i] == pid)       break;
00101 
00102        if (i >= nchildren)  return (0);
00103 
00104        switch ((pidptr[i]=fork())) {
00105        case 0:
00106               wait_restore();      /* Just in case */
00107               return (1);
00108        case -1:
00109               return (-1);
00110        default:
00111               break;
00112        }
00113        return (0);
00114 }