From 5cd3c91e72481a3328ef439f075e6f22131d9cdf Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 5 Sep 2009 19:20:10 +0000 Subject: 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 --- lib/libpm.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- lib/pm.h | 15 ++++++++++ 2 files changed, 108 insertions(+), 6 deletions(-) (limited to 'lib') 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 #include #include #include @@ -18,15 +21,19 @@ #include #include #include +#if HAVE_FORK +#include +#endif +#include -#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. @@ -94,6 +101,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) { diff --git a/lib/pm.h b/lib/pm.h index 4ba20aa5..55ea4f29 100644 --- a/lib/pm.h +++ b/lib/pm.h @@ -164,6 +164,21 @@ pm_setjmpbufsave(jmp_buf * const jmpbufP, void pm_longjmp(void); +void +pm_fork(int * const iAmParentP, + pid_t * const childPidP, + const char ** const errorP); + +void +pm_waitpid(pid_t const pid, + int * const statusP, + int const options, + pid_t * const exitedPidP, + const char ** const errorP); + + +void +pm_waitpidSimple(pid_t const pid); typedef void pm_usermessagefn(const char * msg); -- cgit 1.4.1