about summary refs log tree commit diff
path: root/lib/libpm.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-09-05 19:20:10 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-09-05 19:20:10 +0000
commit5cd3c91e72481a3328ef439f075e6f22131d9cdf (patch)
tree46730d1c6018ad4e4b880626dd0bc3e7e5120185 /lib/libpm.c
parentec93ed84ae933a65eea0873c85ba1d5766426d45 (diff)
downloadnetpbm-mirror-5cd3c91e72481a3328ef439f075e6f22131d9cdf.tar.gz
netpbm-mirror-5cd3c91e72481a3328ef439f075e6f22131d9cdf.tar.xz
netpbm-mirror-5cd3c91e72481a3328ef439f075e6f22131d9cdf.zip
Add pm_fork(), pm_waitpid(), pm_waitpidSimple()
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@983 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'lib/libpm.c')
-rw-r--r--lib/libpm.c99
1 files changed, 93 insertions, 6 deletions
diff --git a/lib/libpm.c b/lib/libpm.c
index 1089da3c..099d4bf7 100644
--- a/lib/libpm.c
+++ b/lib/libpm.c
@@ -10,6 +10,9 @@
 
 #define _XOPEN_SOURCE 500    /* Make sure ftello, fseeko are defined */
 
+#include "netpbm/pm_config.h"
+
+#include <assert.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -18,15 +21,19 @@
 #include <setjmp.h>
 #include <time.h>
 #include <limits.h>
+#if HAVE_FORK
+#include <sys/wait.h>
+#endif
+#include <sys/types.h>
 
-#include "pm_c_util.h"
-#include "mallocvar.h"
-#include "version.h"
+#include "netpbm/pm_c_util.h"
+#include "netpbm/mallocvar.h"
+#include "netpbm/version.h"
+#include "netpbm/nstring.h"
+#include "netpbm/shhopt.h"
 #include "compile.h"
-#include "nstring.h"
-#include "shhopt.h"
 
-#include "pm.h"
+#include "netpbm/pm.h"
 
 /* The following are set by pm_init(), then used by subsequent calls to other
    pm_xxx() functions.
@@ -95,6 +102,86 @@ pm_longjmp(void) {
 
 
 void
+pm_fork(int *         const iAmParentP,
+        pid_t *       const childPidP,
+        const char ** const errorP) {
+/*----------------------------------------------------------------------------
+   Same as POSIX fork, except with a nicer interface and works
+   (fails cleanly) on systems that don't have POSIX fork().
+-----------------------------------------------------------------------------*/
+#if HAVE_FORK
+    int rc;
+
+    rc = fork();
+
+    if (rc < 0) {
+        asprintfN(errorP, "Failed to fork a process.  errno=%d (%s)",
+                  errno, strerror(errno));
+    } else {
+        *errorP = NULL;
+
+        if (rc == 0) {
+            *iAmParentP = FALSE;
+        } else {
+            *iAmParentP = TRUE;
+            *childPidP = rc;
+        }
+    }
+#else
+    asprintfN(errorP, "Cannot fork a process, because this system does "
+              "not have POSIX fork()");
+#endif
+}
+
+
+
+void
+pm_waitpid(pid_t         const pid,
+           int *         const statusP,
+           int           const options,
+           pid_t *       const exitedPidP,
+           const char ** const errorP) {
+
+#if HAVE_FORK
+    pid_t rc;
+    rc = waitpid(pid, statusP, options);
+    if (rc == (pid_t)-1) {
+        asprintfN(errorP, "Failed to wait for process exit.  "
+                  "waitpid() errno = %d (%s)",
+                  errno, strerror(errno));
+    } else {
+        *exitedPidP = rc;
+        *errorP = NULL;
+    }
+#else
+    pm_error("INTERNAL ERROR: Attempt to wait for a process we created on "
+             "a system on which we can't create processes");
+#endif
+}
+
+
+
+void
+pm_waitpidSimple(pid_t const pid) {
+
+    int status;
+    pid_t exitedPid;
+    const char * error;
+
+    pm_waitpid(pid, &status, 0, &exitedPid, &error);
+
+    if (error) {
+        pm_errormsg("%s", error);
+        strfree(error);
+        pm_longjmp();
+    } else {
+        assert(exitedPid != 0);
+    }
+}
+
+
+
+void
 pm_setusererrormsgfn(pm_usererrormsgfn * fn) {
 
     userErrorMsgFn = fn;