summaryrefslogtreecommitdiffstats
path: root/waitlib/waitlib2.c
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /waitlib/waitlib2.c
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'waitlib/waitlib2.c')
-rw-r--r--waitlib/waitlib2.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/waitlib/waitlib2.c b/waitlib/waitlib2.c
new file mode 100644
index 0000000..52dfc26
--- /dev/null
+++ b/waitlib/waitlib2.c
@@ -0,0 +1,114 @@
+/*
+** 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 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);
+}