diff options
Diffstat (limited to 'gpgme/rungpg.c')
-rw-r--r-- | gpgme/rungpg.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 261c71f7..b042d7b7 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -145,6 +145,38 @@ static int command_cb ( void *opaque, char *buffer, size_t length, size_t *nread ); +static void +close_notify_handler ( int fd, void *opaque ) +{ + GpgObject gpg = opaque; + + assert (fd != -1); + if (gpg->status.fd[0] == fd ) + gpg->status.fd[0] = -1; + else if (gpg->status.fd[1] == fd ) + gpg->status.fd[1] = -1; + else if (gpg->colon.fd[0] == fd ) + gpg->colon.fd[0] = -1; + else if (gpg->colon.fd[1] == fd ) + gpg->colon.fd[1] = -1; + else if (gpg->fd_data_map) { + int i; + + for (i=0; gpg->fd_data_map[i].data; i++ ) { + if ( gpg->fd_data_map[i].fd == fd ) { + gpg->fd_data_map[i].fd = -1; + break; + } + if ( gpg->fd_data_map[i].peer_fd == fd ) { + gpg->fd_data_map[i].peer_fd = -1; + break; + } + } + } +} + + + GpgmeError _gpgme_gpg_new ( GpgObject *r_gpg ) @@ -179,6 +211,13 @@ _gpgme_gpg_new ( GpgObject *r_gpg ) rc = mk_error (Pipe_Error); goto leave; } + if ( _gpgme_io_set_close_notify (gpg->status.fd[0], + close_notify_handler, gpg) + || _gpgme_io_set_close_notify (gpg->status.fd[1], + close_notify_handler, gpg) ) { + rc = mk_error (General_Error); + goto leave; + } gpg->status.eof = 0; _gpgme_gpg_add_arg ( gpg, "--status-fd" ); { @@ -211,11 +250,6 @@ _gpgme_gpg_release ( GpgObject gpg ) free_argv (gpg->argv); xfree (gpg->cmd.keyword); - #if 0 - /* fixme: We need a way to communicate back closed fds, so that we - * don't do it a second time. One way to do it is by using a global - * table of open fds associated with gpg objects - but this requires - * additional locking. */ if (gpg->status.fd[0] != -1 ) _gpgme_io_close (gpg->status.fd[0]); if (gpg->status.fd[1] != -1 ) @@ -224,7 +258,6 @@ _gpgme_gpg_release ( GpgObject gpg ) _gpgme_io_close (gpg->colon.fd[0]); if (gpg->colon.fd[1] != -1 ) _gpgme_io_close (gpg->colon.fd[1]); - #endif free_fd_data_map (gpg->fd_data_map); if (gpg->running) { int pid = gpg->pid; @@ -246,6 +279,7 @@ _gpgme_gpg_release ( GpgObject gpg ) xfree (gpg); } + static void do_reaping (void) { @@ -438,6 +472,12 @@ _gpgme_gpg_set_colon_line_handler ( GpgObject gpg, xfree (gpg->colon.buffer); gpg->colon.buffer = NULL; return mk_error (Pipe_Error); } + if ( _gpgme_io_set_close_notify (gpg->colon.fd[0], + close_notify_handler, gpg) + || _gpgme_io_set_close_notify (gpg->colon.fd[1], + close_notify_handler, gpg) ) { + return mk_error (General_Error); + } gpg->colon.eof = 0; gpg->colon.fnc = fnc; gpg->colon.fnc_value = fnc_value; @@ -512,12 +552,10 @@ free_fd_data_map ( struct fd_data_map_s *fd_data_map ) return; for (i=0; fd_data_map[i].data; i++ ) { -#if 0 /* fixme -> see gpg_release */ if ( fd_data_map[i].fd != -1 ) _gpgme_io_close (fd_data_map[i].fd); if ( fd_data_map[i].peer_fd != -1 ) _gpgme_io_close (fd_data_map[i].peer_fd); -#endif /* don't release data because this is only a reference */ } xfree (fd_data_map); @@ -652,6 +690,13 @@ build_argv ( GpgObject gpg ) free_argv (argv); return mk_error (Pipe_Error); } + if ( _gpgme_io_set_close_notify (fds[0], + close_notify_handler, gpg) + || _gpgme_io_set_close_notify (fds[1], + close_notify_handler, + gpg)) { + return mk_error (General_Error); + } /* if the data_type is FD, we have to do a dup2 here */ if (fd_data_map[datac].inbound) { fd_data_map[datac].fd = fds[0]; |