diff options
Diffstat (limited to 'assuan/assuan-pipe-connect.c')
| -rw-r--r-- | assuan/assuan-pipe-connect.c | 68 | 
1 files changed, 49 insertions, 19 deletions
| diff --git a/assuan/assuan-pipe-connect.c b/assuan/assuan-pipe-connect.c index 32a62191..a0091c6a 100644 --- a/assuan/assuan-pipe-connect.c +++ b/assuan/assuan-pipe-connect.c @@ -41,10 +41,19 @@  #ifdef _ASSUAN_IN_GPGME_BUILD_ASSUAN +/* From GPGME priv-io.h  */ +struct spawn_fd_item_s +{ +  int fd; +  int dup_to; +  int peer_name; +  int arg_loc; +}; + +  int _gpgme_io_pipe (int filedes[2], int inherit_idx);  int _gpgme_io_spawn (const char *path, char **argv, -		     struct spawn_fd_item_s *fd_child_list, -		     struct spawn_fd_item_s *fd_parent_list, pid_t *r_pid); +		     struct spawn_fd_item_s *fd_list, pid_t *r_pid);  #endif  /* Hacks for Slowaris.  */ @@ -566,13 +575,6 @@ socketpair_connect (assuan_context_t *ctx,  #define pipe_connect pipe_connect_gpgme -/* From GPGME priv-io.h  */ -struct spawn_fd_item_s -{ -  int fd; -  int dup_to; -}; -  /* W32 version of the pipe connection code. */  static assuan_error_t  pipe_connect_gpgme (assuan_context_t *ctx, @@ -583,14 +585,25 @@ pipe_connect_gpgme (assuan_context_t *ctx,  {    assuan_error_t err;    int res; +  int idx; +  int nr;    int rp[2];    int wp[2];    char mypidstr[50]; -  struct spawn_fd_item_s child_fds[3]; /* stdin, stdout, terminating -1 */ +  struct spawn_fd_item_s *child_fds;    if (!ctx || !name || !argv || !argv[0])      return _assuan_error (ASSUAN_Invalid_Value); +  /* stdin, stdout, terminating -1 */ +  nr = 3; +  for (idx = 0; fd_child_list[idx] != -1; idx++) +    nr++; + +  child_fds = calloc (nr, sizeof *child_fds); +  if (! child_fds) +    return _assuan_error (ASSUAN_Out_Of_Core); +    /* Actually, GPGME does this for us.  But we plan to reuse this code       in the generic assuan.  */    fix_signals (); @@ -631,19 +644,28 @@ pipe_connect_gpgme (assuan_context_t *ctx,       the old value, changeit, create proces and restore it, is not       thread safe.  */ -  /* Parent list is same as client list.  Note that GPGME will dup nul -     to stderr even if the caller wants to inherit the handle for -     it.  */ +  nr = 0;    /* Server stdout is its write end of our read pipe.  */ -  child_fds[0].fd = rp[1]; -  child_fds[0].dup_to = 1; +  child_fds[nr].fd = rp[1]; +  child_fds[nr].dup_to = 1; +  nr++;    /* Server stdin is its read end of our write pipe.  */ -  child_fds[1].fd = wp[0]; -  child_fds[1].dup_to = 0; -  child_fds[2].fd = -1; +  child_fds[nr].fd = wp[0]; +  child_fds[nr].dup_to = 0; +  nr++; + +  for (idx = 0; fd_child_list[idx] != -1; idx++) +    { +      child_fds[nr].fd = fd_child_list[idx]; +      child_fds[nr].dup_to = -1; +      nr++; +    } + +  child_fds[nr].fd = -1; +  child_fds[nr].dup_to = -1;    /* Start the process.  */ -  res = _gpgme_io_spawn (name, argv, child_fds, child_fds, NULL); +  res = _gpgme_io_spawn (name, argv, child_fds, NULL);    if (res == -1)      {        _assuan_log_printf ("CreateProcess failed: %s\n", strerror (errno)); @@ -653,6 +675,14 @@ pipe_connect_gpgme (assuan_context_t *ctx,        _gpgme_io_close (wp[1]);        return _assuan_error (ASSUAN_General_Error);      } +  else +    { +      /* For W32, the user needs to know the server-local names of the +	 inherited handles.  Return them here.  */ +      for (idx = 0; fd_child_list[idx] != -1; idx++) +	/* We add 2 to skip over the stdin/stdout pair.  */ +	fd_child_list[idx] = child_fds[idx + 2].peer_name; +    }    (*ctx)->pid = 0;  /* We don't use the PID. */ | 
