diff options
Diffstat (limited to '')
-rw-r--r-- | assuan/assuan-connect.c | 127 |
1 files changed, 112 insertions, 15 deletions
diff --git a/assuan/assuan-connect.c b/assuan/assuan-connect.c index 37d426255..abc5d74e2 100644 --- a/assuan/assuan-connect.c +++ b/assuan/assuan-connect.c @@ -18,17 +18,56 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#ifdef HAVE_CONFIG_H #include <config.h> +#endif + #include <stdlib.h> #include <stdio.h> #include <string.h> #include <signal.h> #include <unistd.h> +#include <errno.h> #include <sys/types.h> #include <sys/wait.h> #include "assuan-defs.h" +#ifdef _POSIX_OPEN_MAX +#define MAX_OPEN_FDS _POSIX_OPEN_MAX +#else +#define MAX_OPEN_FDS 20 +#endif + +#ifdef HAVE_JNLIB_LOGGING +#define LOGERROR1(a,b) log_error ((a), (b)) +#else +#define LOGERROR1(a,b) fprintf (stderr, (a), (b)) +#endif + + + +static int +writen ( int fd, const char *buffer, size_t length ) +{ + while (length) + { + int nwritten = write (fd, buffer, length); + + if (nwritten < 0) + { + if (errno == EINTR) + continue; + return -1; /* write error */ + } + length -= nwritten; + buffer += nwritten; + } + return 0; /* okay */ +} + + + /* Connect to a server over a pipe, creating the assuan context and returning it in CTX. The server filename is NAME, the argument vector in ARGV. */ @@ -41,8 +80,8 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[]) int wp[2]; int fd[2]; - if (!name || !argv || !argv[0]) - return ASSUAN_General_Error; + if (!ctx || !name || !argv || !argv[0]) + return ASSUAN_Invalid_Value; if (!fixed_signals) { @@ -69,7 +108,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[]) close (rp[1]); return ASSUAN_General_Error; } - + fd[0] = rp[0]; /* Our inbound is read end of read pipe. */ fd[1] = wp[1]; /* Our outbound is write end of write pipe. */ @@ -82,6 +121,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[]) close (wp[1]); return err; } + (*ctx)->is_server = 0; (*ctx)->pid = fork (); if ((*ctx)->pid < 0) @@ -96,25 +136,80 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[]) if ((*ctx)->pid == 0) { - close (rp[0]); - close (wp[1]); + int i, n; + char errbuf[512]; +#ifdef HAVE_JNLIB_LOGGING + int log_fd = log_get_fd (); +#endif + /* close all files which will not be duped but keep stderr + and log_stream for now */ + n = sysconf (_SC_OPEN_MAX); + if (n < 0) + n = MAX_OPEN_FDS; + for (i=0; i < n; i++) + { + if (i != fileno (stderr) +#ifdef HAVE_JNLIB_LOGGING + && i != log_fd +#endif + && i != rp[1] && i != wp[0]) + close(i); + } + errno = 0; + + /* Dup handles and to stdin/stdout and exec */ if (rp[1] != STDOUT_FILENO) - { - dup2 (rp[1], STDOUT_FILENO); /* Child's outbound is write end of read pipe. */ - close (rp[1]); - } + { + if (dup2 (rp[1], STDOUT_FILENO) == -1) + { + LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno)); + _exit (4); + } + close (rp[1]); + } if (wp[0] != STDIN_FILENO) - { - dup2 (wp[0], STDIN_FILENO); /* Child's inbound is read end of write pipe. */ - close (wp[0]); - } - execv (name, argv); - _exit (1); + { + if (dup2 (wp[0], STDIN_FILENO) == -1) + { + LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno)); + _exit (4); + } + close (wp[0]); + } + + execv (name, argv); + /* oops - use the pipe to tell the parent about it */ + snprintf (errbuf, sizeof(errbuf)-1, "ERR %d can't exec `%s': %.50s\n", + ASSUAN_Problem_Starting_Server, name, strerror (errno)); + errbuf[sizeof(errbuf)-1] = 0; + writen (1, errbuf, strlen (errbuf)); + _exit (4); } close (rp[1]); close (wp[0]); _assuan_read_line (*ctx); /* FIXME: Handshake. */ + +#if 0 /* old stuff */ + inbound.eof = 0; + inbound.linelen = 0; + inbound.attic.linelen = 0; + + /* The server is available - read the greeting */ + rc = read_from_agent (&okay); + if (rc) + { + log_error ("can't connect to the agent: %s\n", gnupg_strerror (rc)); + } + else if (!okay) + { + log_error ("can't connect to the agent: %s\n", inbound.line); + rc = seterr (No_Agent); + } + else +#endif + + return 0; } @@ -133,3 +228,5 @@ assuan_get_pid (ASSUAN_CONTEXT ctx) { return ctx ? ctx->pid : -1; } + + |