diff options
Diffstat (limited to 'src/spawn-posix.c')
-rw-r--r-- | src/spawn-posix.c | 393 |
1 files changed, 187 insertions, 206 deletions
diff --git a/src/spawn-posix.c b/src/spawn-posix.c index 9e7800f..add012b 100644 --- a/src/spawn-posix.c +++ b/src/spawn-posix.c @@ -39,14 +39,6 @@ #include <unistd.h> #include <fcntl.h> -#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */ -#undef HAVE_NPTH -#undef USE_NPTH -#endif - -#ifdef HAVE_NPTH -#include <npth.h> -#endif #include <sys/wait.h> #ifdef HAVE_GETRLIMIT @@ -63,30 +55,22 @@ # include <dirent.h> #endif /*__linux__ */ -#include "util.h" -#include "i18n.h" -#include "sysutils.h" -#include "exechelp.h" - +#include "gpgrt-int.h" -/* Helper */ -static inline gpg_error_t -my_error_from_syserror (void) -{ - return gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); -} -static inline gpg_error_t -my_error (int errcode) +static void +out_of_core (int line) { - return gpg_err_make (default_errsource, errcode); + _gpgrt_log_fatal ("malloc failed at line %d: %s\n", + line, _gpg_strerror (_gpg_err_code_from_syserror ())); + /*NOTREACHED*/ } /* Return the maximum number of currently allowed open file - descriptors. Only useful on POSIX systems but returns a value on - other systems too. */ -int + * descriptors. Only useful on POSIX systems but returns a value on + * other systems too. */ +static int get_max_fds (void) { int max_fds = -1; @@ -110,6 +94,7 @@ get_max_fds (void) const char *s; int x; + /* FIXME: Check gpgme on how to do this right on Linux. */ dir = opendir ("/proc/self/fd"); if (dir) { @@ -176,10 +161,10 @@ get_max_fds (void) /* Close all file descriptors starting with descriptor FIRST. If - EXCEPT is not NULL, it is expected to be a list of file descriptors - which shall not be closed. This list shall be sorted in ascending - order with the end marked by -1. */ -void + * EXCEPT is not NULL, it is expected to be a list of file descriptors + * which shall not be closed. This list shall be sorted in ascending + * order with the end marked by -1. */ +static void close_all_fds (int first, int *except) { int max_fd = get_max_fds (); @@ -211,16 +196,20 @@ close_all_fds (int first, int *except) close (fd); } - gpg_err_set_errno (0); + _gpg_err_set_errno (0); } /* Returns an array with all currently open file descriptors. The end - of the array is marked by -1. The caller needs to release this - array using the *standard free* and not with xfree. This allow the - use of this function right at startup even before libgcrypt has - been initialized. Returns NULL on error and sets ERRNO - accordingly. */ + * of the array is marked by -1. The caller needs to release this + * array using the *standard free* and not with xfree. This allow the + * use of this function right at startup even before libgcrypt has + * been initialized. Returns NULL on error and sets ERRNO + * accordingly. + * + * FIXME: Needs to be adjusted for use here. + */ +#if 0 int * get_all_open_fds (void) { @@ -263,9 +252,10 @@ get_all_open_fds (void) #endif /*HAVE_STAT*/ return array; } +#endif /*0*/ -/* The exec core used right after the fork. This will never return. */ +/* The exec core used right after the fork. This will never return. */ static void do_exec (const char *pgmname, const char *argv[], int fd_in, int fd_out, int fd_err, @@ -284,12 +274,18 @@ do_exec (const char *pgmname, const char *argv[], if (argv) while (argv[i]) i++; - arg_list = xcalloc (i+2, sizeof *arg_list); + arg_list = xtrycalloc (i+2, sizeof *arg_list); + if (!arg_list) + out_of_core (__LINE__); arg_list[0] = strrchr (pgmname, '/'); if (arg_list[0]) arg_list[0]++; else - arg_list[0] = xstrdup (pgmname); + { + arg_list[0] = xtrystrdup (pgmname); + if (!arg_list[0]) + out_of_core (__LINE__); + } if (argv) for (i=0,j=1; argv[i]; i++, j++) arg_list[j] = (char*)argv[i]; @@ -301,8 +297,8 @@ do_exec (const char *pgmname, const char *argv[], { fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY); if (fds[i] == -1) - log_fatal ("failed to open '%s': %s\n", - "/dev/null", strerror (errno)); + _gpgrt_log_fatal ("failed to open '%s': %s\n", + "/dev/null", strerror (errno)); } } @@ -310,8 +306,8 @@ do_exec (const char *pgmname, const char *argv[], for (i=0; i <= 2; i++) { if (fds[i] != i && dup2 (fds[i], i) == -1) - log_fatal ("dup2 std%s failed: %s\n", - i==0?"in":i==1?"out":"err", strerror (errno)); + _gpgrt_log_fatal ("dup2 std%s failed: %s\n", + i==0?"in":i==1?"out":"err", strerror (errno)); } /* Close all other files. */ @@ -320,19 +316,20 @@ do_exec (const char *pgmname, const char *argv[], if (preexec) preexec (); execv (pgmname, arg_list); - /* No way to print anything, as we have closed all streams. */ + /* No way to print anything, as we have may have closed all streams. */ _exit (127); } -static gpg_error_t +/* Helper for _gpgrt_make_pipe. */ +static gpg_err_code_t do_create_pipe (int filedes[2]) { gpg_error_t err = 0; if (pipe (filedes) == -1) { - err = my_error_from_syserror (); + err = _gpg_err_code_from_syserror (); filedes[0] = filedes[1] = -1; } @@ -340,30 +337,31 @@ do_create_pipe (int filedes[2]) } -static gpg_error_t -create_pipe_and_estream (int filedes[2], estream_t *r_fp, - int outbound, int nonblock) +/* Helper for _gpgrt_make_pipe. */ +static gpg_err_code_t +do_create_pipe_and_estream (int filedes[2], estream_t *r_fp, + int outbound, int nonblock) { - gpg_error_t err; + gpg_err_code_t err; if (pipe (filedes) == -1) { - err = my_error_from_syserror (); - log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + err = _gpg_err_code_from_syserror (); + _gpgrt_log_error (_("error creating a pipe: %s\n"), _gpg_strerror (err)); filedes[0] = filedes[1] = -1; *r_fp = NULL; return err; } if (!outbound) - *r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r"); + *r_fp = _gpgrt_fdopen (filedes[0], nonblock? "r,nonblock" : "r"); else - *r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w"); + *r_fp = _gpgrt_fdopen (filedes[1], nonblock? "w,nonblock" : "w"); if (!*r_fp) { - err = my_error_from_syserror (); - log_error (_("error creating a stream for a pipe: %s\n"), - gpg_strerror (err)); + err = _gpg_err_code_from_syserror (); + _gpgrt_log_error (_("error creating a stream for a pipe: %s\n"), + _gpg_strerror (err)); close (filedes[0]); close (filedes[1]); filedes[0] = filedes[1] = -1; @@ -373,49 +371,31 @@ create_pipe_and_estream (int filedes[2], estream_t *r_fp, } -/* Portable function to create a pipe. Under Windows the write end is - inheritable. If R_FP is not NULL, an estream is created for the - read end and stored at R_FP. */ -gpg_error_t -gnupg_create_inbound_pipe (int filedes[2], estream_t *r_fp, int nonblock) +/* Create a pipe. The DIRECTION parameter gives the type of the created pipe: + * DIRECTION < 0 := Inbound pipe: On Windows the write end is inheritable. + * DIRECTION > 0 := Outbound pipe: On Windows the read end is inheritable. + * If R_FP is NULL a standard pipe and no stream is created, DIRECTION + * should then be 0. */ +gpg_err_code_t +_gpgrt_make_pipe (int filedes[2], estream_t *r_fp, int direction, + int nonblock) { - if (r_fp) - return create_pipe_and_estream (filedes, r_fp, 0, nonblock); + if (r_fp && direction) + return do_create_pipe_and_estream (filedes, r_fp, + (direction > 0), nonblock); else return do_create_pipe (filedes); } -/* Portable function to create a pipe. Under Windows the read end is - inheritable. If R_FP is not NULL, an estream is created for the - write end and stored at R_FP. */ -gpg_error_t -gnupg_create_outbound_pipe (int filedes[2], estream_t *r_fp, int nonblock) -{ - if (r_fp) - return create_pipe_and_estream (filedes, r_fp, 1, nonblock); - else - return do_create_pipe (filedes); -} - - -/* Portable function to create a pipe. Under Windows both ends are - inheritable. */ -gpg_error_t -gnupg_create_pipe (int filedes[2]) -{ - return do_create_pipe (filedes); -} - - -/* Fork and exec the PGMNAME, see exechelp.h for details. */ -gpg_error_t -gnupg_spawn_process (const char *pgmname, const char *argv[], - int *except, void (*preexec)(void), unsigned int flags, - estream_t *r_infp, - estream_t *r_outfp, - estream_t *r_errfp, - pid_t *pid) +/* Fork and exec the PGMNAME, see gpgrt-int.h for details. */ +gpg_err_code_t +_gpgrt_spawn_process (const char *pgmname, const char *argv[], + int *except, void (*preexec)(void), unsigned int flags, + estream_t *r_infp, + estream_t *r_outfp, + estream_t *r_errfp, + pid_t *pid) { gpg_error_t err; int inpipe[2] = {-1, -1}; @@ -424,7 +404,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], estream_t infp = NULL; estream_t outfp = NULL; estream_t errfp = NULL; - int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK); + int nonblock = !!(flags & GPGRT_SPAWN_NONBLOCK); if (r_infp) *r_infp = NULL; @@ -436,18 +416,18 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], if (r_infp) { - err = create_pipe_and_estream (inpipe, &infp, 1, nonblock); + err = _gpgrt_create_outbound_pipe (inpipe, &infp, nonblock); if (err) return err; } if (r_outfp) { - err = create_pipe_and_estream (outpipe, &outfp, 0, nonblock); + err = _gpgrt_create_inbound_pipe (outpipe, &outfp, nonblock); if (err) { if (infp) - es_fclose (infp); + _gpgrt_fclose (infp); else if (inpipe[1] != -1) close (inpipe[1]); if (inpipe[0] != -1) @@ -459,18 +439,18 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], if (r_errfp) { - err = create_pipe_and_estream (errpipe, &errfp, 0, nonblock); + err = _gpgrt_create_inbound_pipe (errpipe, &errfp, nonblock); if (err) { if (infp) - es_fclose (infp); + _gpgrt_fclose (infp); else if (inpipe[1] != -1) close (inpipe[1]); if (inpipe[0] != -1) close (inpipe[0]); if (outfp) - es_fclose (outfp); + _gpgrt_fclose (outfp); else if (outpipe[0] != -1) close (outpipe[0]); if (outpipe[1] != -1) @@ -484,25 +464,25 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], *pid = fork (); if (*pid == (pid_t)(-1)) { - err = my_error_from_syserror (); - log_error (_("error forking process: %s\n"), gpg_strerror (err)); + err = _gpg_err_code_from_syserror (); + _gpgrt_log_error (_("error forking process: %s\n"), _gpg_strerror (err)); if (infp) - es_fclose (infp); + _gpgrt_fclose (infp); else if (inpipe[1] != -1) close (inpipe[1]); if (inpipe[0] != -1) close (inpipe[0]); if (outfp) - es_fclose (outfp); + _gpgrt_fclose (outfp); else if (outpipe[0] != -1) close (outpipe[0]); if (outpipe[1] != -1) close (outpipe[1]); if (errfp) - es_fclose (errfp); + _gpgrt_fclose (errfp); else if (errpipe[0] != -1) close (errpipe[0]); if (errpipe[1] != -1) @@ -513,10 +493,11 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], if (!*pid) { /* This is the child. */ - gcry_control (GCRYCTL_TERM_SECMEM); - es_fclose (infp); - es_fclose (outfp); - es_fclose (errfp); + /* FIXME: Needs to be done by preexec: + gcry_control (GCRYCTL_TERM_SECMEM); */ + _gpgrt_fclose (infp); + _gpgrt_fclose (outfp); + _gpgrt_fclose (errfp); do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], except, preexec); /*NOTREACHED*/ @@ -541,32 +522,26 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], } - -/* Simplified version of gnupg_spawn_process. This function forks and - then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout - and ERRFD to stderr (any of them may be -1 to connect them to - /dev/null). The arguments for the process are expected in the NULL - terminated array ARGV. The program name itself should not be - included there. Calling gnupg_wait_process is required. - - Returns 0 on success or an error code. */ -gpg_error_t -gnupg_spawn_process_fd (const char *pgmname, const char *argv[], - int infd, int outfd, int errfd, pid_t *pid) +/* Fork and exec the PGMNAME using FDs, see gpgrt-int.h for details. */ +gpg_err_code_t +_gpgrt_spawn_process_fd (const char *pgmname, const char *argv[], + int infd, int outfd, int errfd, pid_t *pid) { gpg_error_t err; *pid = fork (); if (*pid == (pid_t)(-1)) { - err = my_error_from_syserror (); - log_error (_("error forking process: %s\n"), strerror (errno)); + err = _gpg_err_code_from_syserror (); + _gpgrt_log_error (_("error forking process: %s\n"), _gpg_strerror (err)); return err; } if (!*pid) { - gcry_control (GCRYCTL_TERM_SECMEM); + /* FIXME: We need to add a preexec so that a + gcry_control (GCRYCTL_TERM_SECMEM); + can be done. */ /* Run child. */ do_exec (pgmname, argv, infd, outfd, errfd, NULL, NULL); /*NOTREACHED*/ @@ -576,17 +551,17 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], } - - /* Waiting for child processes. - - waitpid(2) may return information about terminated children that we - did not yet request, and there is no portable way to wait for a - specific set of children. - - As a workaround, we store the results of children for later use. - - XXX: This assumes that PIDs are not reused too quickly. */ + * + * waitpid(2) may return information about terminated children that we + * did not yet request, and there is no portable way to wait for a + * specific set of children. + * + * As a workaround, we store the results of children for later use. + * + * XXX: This assumes that PIDs are not reused too quickly. + * FIXME: This is not thread-safe. + */ struct terminated_child { @@ -595,17 +570,17 @@ struct terminated_child struct terminated_child *next; }; -struct terminated_child *terminated_children; +static struct terminated_child *terminated_children; -static gpg_error_t +static gpg_err_code_t store_result (pid_t pid, int exitcode) { struct terminated_child *c; c = xtrymalloc (sizeof *c); if (c == NULL) - return gpg_err_code_from_syserror (); + return _gpg_err_code_from_syserror (); c->pid = pid; c->exitcode = exitcode; @@ -636,9 +611,9 @@ get_result (pid_t pid, int *r_exitcode) } -/* See exechelp.h for a description. */ -gpg_error_t -gnupg_wait_process (const char *pgmname, pid_t pid, int hang, 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) { gpg_err_code_t ec; int i, status; @@ -647,20 +622,16 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) *r_exitcode = -1; if (pid == (pid_t)(-1)) - return gpg_error (GPG_ERR_INV_VALUE); + return GPG_ERR_INV_VALUE; -#ifdef USE_NPTH - i = npth_waitpid (pid, &status, hang? 0:WNOHANG); -#else while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1) && errno == EINTR); -#endif if (i == (pid_t)(-1)) { - ec = gpg_err_code_from_errno (errno); - log_error (_("waiting for process %d to terminate failed: %s\n"), - (int)pid, strerror (errno)); + ec = _gpg_err_code_from_syserror (); + _gpgrt_log_error (_("waiting for process %d to terminate failed: %s\n"), + (int)pid, _gpg_strerror (ec)); } else if (!i) { @@ -668,21 +639,23 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) } else if (WIFEXITED (status) && WEXITSTATUS (status) == 127) { - log_error (_("error running '%s': probably not installed\n"), pgmname); + /* FIXME: This is GnuPG specific. */ + _gpgrt_log_error (_("error running '%s': probably not installed\n"), + pgmname); ec = GPG_ERR_CONFIGURATION; } else if (WIFEXITED (status) && WEXITSTATUS (status)) { if (!r_exitcode) - log_error (_("error running '%s': exit status %d\n"), pgmname, - WEXITSTATUS (status)); + _gpgrt_log_error (_("error running '%s': exit status %d\n"), pgmname, + WEXITSTATUS (status)); else *r_exitcode = WEXITSTATUS (status); ec = GPG_ERR_GENERAL; } else if (!WIFEXITED (status)) { - log_error (_("error running '%s': terminated\n"), pgmname); + _gpgrt_log_error (_("error running '%s': terminated\n"), pgmname); ec = GPG_ERR_GENERAL; } else @@ -692,23 +665,30 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) ec = 0; } - return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec); + return ec; } -/* See exechelp.h for a description. */ -gpg_error_t -gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, - int hang, int *r_exitcodes) + +/* See gpgrt-int.h for a description. + * + * FIXME: What about using a poll like data structure for the pids and + * their exit codes? The whole thing is anyway problematic in a + * threaded processs because waitpid has no association between PIDS + * and threads. + */ +gpg_err_code_t +_gpgrt_wait_processes (const char **pgmnames, pid_t *pids, size_t count, + int hang, int *r_exitcodes) { gpg_err_code_t ec = 0; size_t i, left; int *dummy = NULL; - if (r_exitcodes == NULL) + if (!r_exitcodes) { dummy = r_exitcodes = xtrymalloc (sizeof *r_exitcodes * count); - if (dummy == NULL) - return gpg_err_code_from_syserror (); + if (!dummy) + return _gpg_err_code_from_syserror (); } for (i = 0, left = count; i < count; i++) @@ -716,7 +696,7 @@ gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, int status = -1; if (pids[i] == (pid_t)(-1)) - return my_error (GPG_ERR_INV_VALUE); + return GPG_ERR_INV_VALUE; /* See if there was a previously stored result for this pid. */ if (get_result (pids[i], &status)) @@ -730,18 +710,14 @@ gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, pid_t pid; int status; -#ifdef USE_NPTH - pid = npth_waitpid (-1, &status, hang ? 0 : WNOHANG); -#else while ((pid = waitpid (-1, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1) && errno == EINTR); -#endif if (pid == (pid_t)(-1)) { - ec = gpg_err_code_from_errno (errno); - log_error (_("waiting for processes to terminate failed: %s\n"), - strerror (errno)); + ec = _gpg_err_code_from_syserror (); + _gpgrt_log_error (_("waiting for processes to terminate" + " failed: %s\n"), _gpg_strerror (ec)); break; } else if (!pid) @@ -767,7 +743,7 @@ gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, /* Process PIDS[i] died. */ if (r_exitcodes[i] != (pid_t) -1) { - log_error ("PID %d was reused", pid); + _gpgrt_log_error ("PID %d was reused", pid); ec = GPG_ERR_GENERAL; break; } @@ -784,70 +760,61 @@ gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i]) == 127) { - log_error (_("error running '%s': probably not installed\n"), - pgmnames[i]); + _gpgrt_log_error (_("error running '%s': probably not installed\n"), + pgmnames[i]); ec = GPG_ERR_CONFIGURATION; } else if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i])) { if (dummy) - log_error (_("error running '%s': exit status %d\n"), - pgmnames[i], WEXITSTATUS (r_exitcodes[i])); + _gpgrt_log_error (_("error running '%s': exit status %d\n"), + pgmnames[i], WEXITSTATUS (r_exitcodes[i])); else r_exitcodes[i] = WEXITSTATUS (r_exitcodes[i]); ec = GPG_ERR_GENERAL; } else if (!WIFEXITED (r_exitcodes[i])) { - log_error (_("error running '%s': terminated\n"), pgmnames[i]); + _gpgrt_log_error (_("error running '%s': terminated\n"), pgmnames[i]); ec = GPG_ERR_GENERAL; } } xfree (dummy); - return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec); + return ec; } - -void -gnupg_release_process (pid_t pid) -{ - (void)pid; -} - - -/* Spawn a new process and immediately detach from it. The name of - the program to exec is PGMNAME and its arguments are in ARGV (the - programname is automatically passed as first argument). - Environment strings in ENVP are set. An error is returned if - pgmname is not executable; to make this work it is necessary to - provide an absolute file name. All standard file descriptors are - connected to /dev/null. */ -gpg_error_t -gnupg_spawn_process_detached (const char *pgmname, const char *argv[], - const char *envp[] ) +/* See gpgrt-int.h for a description. FIXME: We should add a prexec + * callback. */ +gpg_err_code_t +_gpgrt_spawn_process_detached (const char *pgmname, const char *argv[], + const char *envp[] ) { + gpg_err_code_t ec; pid_t pid; int i; + /* FIXME: Is this GnuPG specific or should we keep it. */ if (getuid() != geteuid()) - return my_error (GPG_ERR_BUG); + return GPG_ERR_BUG; if (access (pgmname, X_OK)) - return my_error_from_syserror (); + return _gpg_err_code_from_syserror (); pid = fork (); if (pid == (pid_t)(-1)) { - log_error (_("error forking process: %s\n"), strerror (errno)); - return my_error_from_syserror (); + ec = _gpg_err_code_from_syserror (); + _gpgrt_log_error (_("error forking process: %s\n"), _gpg_strerror (ec)); + return ec; } + if (!pid) { pid_t pid2; - gcry_control (GCRYCTL_TERM_SECMEM); + /* gcry_control (GCRYCTL_TERM_SECMEM); */ if (setsid() == -1 || chdir ("/")) _exit (1); @@ -857,31 +824,45 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], if (pid2) _exit (0); /* Let the parent exit immediately. */ - if (envp) - for (i=0; envp[i]; i++) - putenv (xstrdup (envp[i])); + for (i=0; envp && envp[i]; i++) + { + char *p = xtrystrdup (envp[i]); + if (!p) + out_of_core (__LINE__); + putenv (p); + } do_exec (pgmname, argv, -1, -1, -1, NULL, NULL); - /*NOTREACHED*/ } if (waitpid (pid, NULL, 0) == -1) - log_error ("waitpid failed in gnupg_spawn_process_detached: %s", - strerror (errno)); + { + ec = _gpg_err_code_from_syserror (); + _gpgrt_log_error ("waitpid failed in gpgrt_spawn_process_detached: %s", + _gpg_strerror (ec)); + return ec; + } return 0; } /* Kill a process; that is send an appropriate signal to the process. - gnupg_wait_process must be called to actually remove the process + * gnupg_wait_process must be called to actually remove the process from the system. An invalid PID is ignored. */ void -gnupg_kill_process (pid_t pid) +_gpgrt_kill_process (pid_t pid) { if (pid != (pid_t)(-1)) { kill (pid, SIGTERM); } } + + +void +_gpgrt_release_process (pid_t pid) +{ + (void)pid; +} |