aboutsummaryrefslogtreecommitdiffstats
path: root/src/spawn-posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/spawn-posix.c')
-rw-r--r--src/spawn-posix.c393
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;
+}