diff options
Diffstat (limited to 'src/spawn-posix.c')
-rw-r--r-- | src/spawn-posix.c | 101 |
1 files changed, 74 insertions, 27 deletions
diff --git a/src/spawn-posix.c b/src/spawn-posix.c index 6914b0b..8e36ee1 100644 --- a/src/spawn-posix.c +++ b/src/spawn-posix.c @@ -398,6 +398,35 @@ _gpgrt_make_pipe (int filedes[2], estream_t *r_fp, int direction, return do_create_pipe (filedes); } +/* + * UNION PROCESS_ID: + * + * gpgrt_process_t object is an object which represents process handle. + * It must be same size as pid_t and must have same bit pattern. + */ +union process { + gpgrt_process_t process_id; + pid_t pid; +}; + +static gpgrt_process_t +convert_from_pid (pid_t pid) +{ + union process u; + + u.pid = pid; + return u.process_id; +} + +static pid_t +convert_from_process (gpgrt_process_t process_id) +{ + union process u; + + u.process_id = process_id; + return u.pid; +} + /* Fork and exec the PGMNAME, see gpgrt-int.h for details. */ gpg_err_code_t @@ -406,7 +435,7 @@ _gpgrt_spawn_process (const char *pgmname, const char *argv[], estream_t *r_infp, estream_t *r_outfp, estream_t *r_errfp, - pid_t *pid) + gpgrt_process_t *r_process_id) { gpg_error_t err; int inpipe[2] = {-1, -1}; @@ -416,6 +445,7 @@ _gpgrt_spawn_process (const char *pgmname, const char *argv[], estream_t outfp = NULL; estream_t errfp = NULL; int nonblock = !!(flags & GPGRT_SPAWN_NONBLOCK); + pid_t pid; if (r_infp) *r_infp = NULL; @@ -423,7 +453,7 @@ _gpgrt_spawn_process (const char *pgmname, const char *argv[], *r_outfp = NULL; if (r_errfp) *r_errfp = NULL; - *pid = (pid_t)(-1); /* Always required. */ + *r_process_id = convert_from_pid (-1); if (r_infp) { @@ -472,9 +502,9 @@ _gpgrt_spawn_process (const char *pgmname, const char *argv[], } _gpgrt_pre_syscall (); - *pid = fork (); + pid = fork (); _gpgrt_post_syscall (); - if (*pid == (pid_t)(-1)) + if (pid == (pid_t)(-1)) { err = _gpg_err_code_from_syserror (); _gpgrt_log_error (_("error forking process: %s\n"), _gpg_strerror (err)); @@ -502,7 +532,7 @@ _gpgrt_spawn_process (const char *pgmname, const char *argv[], return err; } - if (!*pid) + if (!pid) { /* This is the child. */ _gpgrt_fclose (infp); @@ -528,6 +558,7 @@ _gpgrt_spawn_process (const char *pgmname, const char *argv[], if (r_errfp) *r_errfp = errfp; + *r_process_id = convert_from_pid (pid); return 0; } @@ -538,22 +569,24 @@ _gpgrt_spawn_process_fd (const char *pgmname, const char *argv[], int infd, int outfd, int errfd, int (*spawn_cb) (void *), void *spawn_cb_arg, - pid_t *pid) + gpgrt_process_t *r_process_id) { gpg_error_t err; int ask_inherit_fds = 0; + pid_t pid; + *r_process_id = convert_from_pid (-1); _gpgrt_pre_syscall (); - *pid = fork (); + pid = fork (); _gpgrt_post_syscall (); - if (*pid == (pid_t)(-1)) + if (pid == (pid_t)(-1)) { err = _gpg_err_code_from_syserror (); _gpgrt_log_error (_("error forking process: %s\n"), _gpg_strerror (err)); return err; } - if (!*pid) + if (!pid) { if (spawn_cb) ask_inherit_fds = (*spawn_cb) (spawn_cb_arg); @@ -564,6 +597,7 @@ _gpgrt_spawn_process_fd (const char *pgmname, const char *argv[], /*NOTREACHED*/ } + *r_process_id = convert_from_pid (pid); return 0; } @@ -630,10 +664,14 @@ get_result (pid_t pid, int *r_exitcode) /* See gpgrt-int.h for a description. */ gpg_err_code_t -_gpgrt_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) +_gpgrt_wait_process (const char *pgmname, gpgrt_process_t process_id, int hang, + int *r_exitcode) { gpg_err_code_t ec; int i, status; + pid_t pid; + + pid = convert_from_process (process_id); if (r_exitcode) *r_exitcode = -1; @@ -696,12 +734,13 @@ _gpgrt_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) * and threads. */ gpg_err_code_t -_gpgrt_wait_processes (const char **pgmnames, pid_t *pids, size_t count, - int hang, int *r_exitcodes) +_gpgrt_wait_processes (const char **pgmnames, gpgrt_process_t *process_ids, + size_t count, int hang, int *r_exitcodes) { gpg_err_code_t ec = 0; size_t i, left; int *dummy = NULL; + pid_t pid; if (!r_exitcodes) { @@ -714,8 +753,10 @@ _gpgrt_wait_processes (const char **pgmnames, pid_t *pids, size_t count, { int status = -1; + pid = convert_from_process (process_ids[i]); + /* Skip invalid PID. */ - if (pids[i] == (pid_t)(-1)) + if (pid == (pid_t)(-1)) { r_exitcodes[i] = -1; left -= 1; @@ -723,7 +764,7 @@ _gpgrt_wait_processes (const char **pgmnames, pid_t *pids, size_t count, } /* See if there was a previously stored result for this pid. */ - if (get_result (pids[i], &status)) + if (get_result (pid, &status)) left -= 1; r_exitcodes[i] = status; @@ -731,22 +772,22 @@ _gpgrt_wait_processes (const char **pgmnames, pid_t *pids, size_t count, while (left > 0) { - pid_t pid; + pid_t pid0; int status; _gpgrt_pre_syscall (); - while ((pid = waitpid (-1, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1) + while ((pid0 = waitpid (-1, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1) && errno == EINTR); _gpgrt_post_syscall (); - if (pid == (pid_t)(-1)) + if (pid0 == (pid_t)(-1)) { ec = _gpg_err_code_from_syserror (); _gpgrt_log_error (_("waiting for processes to terminate" " failed: %s\n"), _gpg_strerror (ec)); break; } - else if (!pid) + else if (!pid0) { ec = GPG_ERR_TIMEOUT; /* Still running. */ break; @@ -754,22 +795,25 @@ _gpgrt_wait_processes (const char **pgmnames, pid_t *pids, size_t count, else { for (i = 0; i < count; i++) - if (pid == pids[i]) - break; + { + pid = convert_from_process (process_ids[i]); + if (pid0 == pid) + break; + } if (i == count) { /* No match, store this result. */ - ec = store_result (pid, status); + ec = store_result (pid0, status); if (ec) break; continue; } - /* Process PIDS[i] died. */ + /* Process PROCESS_PIDS[i] died. */ if (r_exitcodes[i] != (pid_t) -1) { - _gpgrt_log_error ("PID %d was reused", (int)pid); + _gpgrt_log_error ("PID %d was reused", (int)pid0); ec = GPG_ERR_GENERAL; break; } @@ -815,7 +859,7 @@ _gpgrt_wait_processes (const char **pgmnames, pid_t *pids, size_t count, * callback. */ gpg_err_code_t _gpgrt_spawn_process_detached (const char *pgmname, const char *argv[], - const char *envp[] ) + const char *envp[]) { gpg_err_code_t ec; pid_t pid; @@ -884,8 +928,11 @@ _gpgrt_spawn_process_detached (const char *pgmname, const char *argv[], * gnupg_wait_process must be called to actually remove the process from the system. An invalid PID is ignored. */ void -_gpgrt_kill_process (pid_t pid) +_gpgrt_kill_process (gpgrt_process_t process_id) { + pid_t pid; + + pid = convert_from_process (process_id); if (pid != (pid_t)(-1)) { _gpgrt_pre_syscall (); @@ -896,7 +943,7 @@ _gpgrt_kill_process (pid_t pid) void -_gpgrt_release_process (pid_t pid) +_gpgrt_release_process (gpgrt_process_t process_id) { - (void)pid; + (void)process_id; } |