reap off gpg processes
This commit is contained in:
parent
a3b341ff45
commit
962bb6af10
@ -1,5 +1,12 @@
|
|||||||
2001-02-13 Werner Koch <wk@gnupg.org>
|
2001-02-13 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* rungpg.c (do_reaping,_gpgme_gpg_housecleaning): New.
|
||||||
|
(_gpgme_gpg_release): Reap children.
|
||||||
|
* io.h, posix-io.c (_gpgme_io_kill): New.
|
||||||
|
* w32-io.c (_gpgme_io_kill): New (dummy).
|
||||||
|
|
||||||
|
* keylist.c (gpgme_op_keylist_start): Cancel a pending request.
|
||||||
|
|
||||||
* posix-io.c (_gpgme_io_read): Add some debug output.
|
* posix-io.c (_gpgme_io_read): Add some debug output.
|
||||||
(_gpgme_io_write): Ditto.
|
(_gpgme_io_write): Ditto.
|
||||||
(_gpgme_io_select): Increased the timeout.
|
(_gpgme_io_select): Increased the timeout.
|
||||||
|
@ -51,6 +51,7 @@ int _gpgme_io_spawn ( const char *path, char **argv,
|
|||||||
struct spawn_fd_item_s *fd_child_list,
|
struct spawn_fd_item_s *fd_child_list,
|
||||||
struct spawn_fd_item_s *fd_parent_list );
|
struct spawn_fd_item_s *fd_parent_list );
|
||||||
int _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal );
|
int _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal );
|
||||||
|
int _gpgme_io_kill ( int pid, int hard );
|
||||||
int _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds);
|
int _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds);
|
||||||
|
|
||||||
|
|
||||||
|
@ -347,13 +347,24 @@ finish_key ( GpgmeCtx ctx )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gpgme_op_keylist_start:
|
||||||
|
* @c: context
|
||||||
|
* @pattern: a GnuPg user ID or NULL for all
|
||||||
|
* @secret_only: List only keys where the secret part is available
|
||||||
|
*
|
||||||
|
* Note that this function also cancels a pending key listing operaton..
|
||||||
|
*
|
||||||
|
* Return value: 0 on success or an errorcode.
|
||||||
|
**/
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only )
|
gpgme_op_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only )
|
||||||
{
|
{
|
||||||
GpgmeError rc = 0;
|
GpgmeError rc = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fail_on_pending_request( c );
|
if ( !c )
|
||||||
|
return mk_error (Invalid_Value);
|
||||||
c->pending = 1;
|
c->pending = 1;
|
||||||
|
|
||||||
_gpgme_release_result (c);
|
_gpgme_release_result (c);
|
||||||
|
@ -206,6 +206,12 @@ _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_gpgme_io_kill ( int pid, int hard )
|
||||||
|
{
|
||||||
|
return kill ( pid, hard? SIGKILL : SIGTERM );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Select on the list of fds.
|
* Select on the list of fds.
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "rungpg.h"
|
#include "rungpg.h"
|
||||||
#include "context.h" /*temp hack until we have GpmeData methods to do I/O */
|
#include "context.h" /*temp hack until we have GpmeData methods to do I/O */
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "sema.h"
|
||||||
|
|
||||||
#include "status-table.h"
|
#include "status-table.h"
|
||||||
|
|
||||||
@ -93,8 +94,6 @@ struct gpg_object_s {
|
|||||||
int pid; /* we can't use pid_t because we don't use it in Windoze */
|
int pid; /* we can't use pid_t because we don't use it in Windoze */
|
||||||
|
|
||||||
int running;
|
int running;
|
||||||
int exit_status;
|
|
||||||
int exit_signal;
|
|
||||||
|
|
||||||
/* stuff needed for pipemode */
|
/* stuff needed for pipemode */
|
||||||
struct {
|
struct {
|
||||||
@ -117,7 +116,17 @@ struct gpg_object_s {
|
|||||||
} cmd;
|
} cmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void kill_gpg ( GpgObject gpg );
|
struct reap_s {
|
||||||
|
struct reap_s *next;
|
||||||
|
pid_t pid;
|
||||||
|
time_t entered;
|
||||||
|
int term_send;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct reap_s *reap_list;
|
||||||
|
DEFINE_STATIC_LOCK (reap_list_lock);
|
||||||
|
|
||||||
|
|
||||||
static void free_argv ( char **argv );
|
static void free_argv ( char **argv );
|
||||||
static void free_fd_data_map ( struct fd_data_map_s *fd_data_map );
|
static void free_fd_data_map ( struct fd_data_map_s *fd_data_map );
|
||||||
|
|
||||||
@ -217,25 +226,80 @@ _gpgme_gpg_release ( GpgObject gpg )
|
|||||||
_gpgme_io_close (gpg->colon.fd[1]);
|
_gpgme_io_close (gpg->colon.fd[1]);
|
||||||
#endif
|
#endif
|
||||||
free_fd_data_map (gpg->fd_data_map);
|
free_fd_data_map (gpg->fd_data_map);
|
||||||
kill_gpg (gpg); /* fixme: should be done asyncronously */
|
if (gpg->running) {
|
||||||
|
int pid = gpg->pid;
|
||||||
|
struct reap_s *r;
|
||||||
|
|
||||||
|
/* resuse the memory, so that we don't need to allocate another
|
||||||
|
* mem block and have to handle errors */
|
||||||
|
assert (sizeof *r < sizeof *gpg );
|
||||||
|
r = (void*)gpg;
|
||||||
|
memset (r, 0, sizeof *r);
|
||||||
|
r->pid = pid;
|
||||||
|
r->entered = time (NULL);
|
||||||
|
LOCK(reap_list_lock);
|
||||||
|
r->next = reap_list;
|
||||||
|
reap_list = r;
|
||||||
|
UNLOCK(reap_list_lock);
|
||||||
|
}
|
||||||
|
else
|
||||||
xfree (gpg);
|
xfree (gpg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
kill_gpg ( GpgObject gpg )
|
do_reaping (void)
|
||||||
{
|
{
|
||||||
#if 0
|
struct reap_s *r, *rlast;
|
||||||
if ( gpg->running ) {
|
static time_t last_check;
|
||||||
/* still running? Must send a killer */
|
time_t cur_time = time (NULL);
|
||||||
kill ( gpg->pid, SIGTERM);
|
|
||||||
sleep (2);
|
/* a race does not matter here */
|
||||||
if ( !waitpid (gpg->pid, NULL, WNOHANG) ) {
|
if (!last_check)
|
||||||
/* pay the murderer better and then forget about it */
|
last_check = time(NULL);
|
||||||
kill (gpg->pid, SIGKILL);
|
|
||||||
|
if (last_check >= cur_time)
|
||||||
|
return; /* we check only every second */
|
||||||
|
|
||||||
|
/* fixme: it would be nice if to have a TRYLOCK here */
|
||||||
|
LOCK (reap_list_lock);
|
||||||
|
for (r=reap_list,rlast=NULL; r ; rlast=r, r=r?r->next:NULL) {
|
||||||
|
int dummy1, dummy2;
|
||||||
|
|
||||||
|
if ( _gpgme_io_waitpid (r->pid, 0, &dummy1, &dummy2) ) {
|
||||||
|
/* process has terminated - remove it from the queue */
|
||||||
|
void *p = r;
|
||||||
|
if (!rlast) {
|
||||||
|
reap_list = r->next;
|
||||||
|
r = reap_list;
|
||||||
}
|
}
|
||||||
gpg->running = 0;
|
else {
|
||||||
|
rlast->next = r->next;
|
||||||
|
r = rlast;
|
||||||
}
|
}
|
||||||
#endif
|
xfree (p);
|
||||||
|
}
|
||||||
|
else if ( !r->term_send ) {
|
||||||
|
if( r->entered+1 >= cur_time ) {
|
||||||
|
_gpgme_io_kill ( r->pid, 0);
|
||||||
|
r->term_send = 1;
|
||||||
|
r->entered = cur_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* give it 5 second before we are going to send the killer */
|
||||||
|
if ( r->entered+5 >= cur_time ) {
|
||||||
|
_gpgme_io_kill (r->pid, 1);
|
||||||
|
r->entered = cur_time; /* just in case we have to repat it */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UNLOCK (reap_list_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gpgme_gpg_housecleaning ()
|
||||||
|
{
|
||||||
|
do_reaping ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -95,6 +95,7 @@ typedef const char *(*GpgCommandHandler)(void*, GpgStatusCode code,
|
|||||||
|
|
||||||
GpgmeError _gpgme_gpg_new ( GpgObject *r_gpg );
|
GpgmeError _gpgme_gpg_new ( GpgObject *r_gpg );
|
||||||
void _gpgme_gpg_release ( GpgObject gpg );
|
void _gpgme_gpg_release ( GpgObject gpg );
|
||||||
|
void _gpgme_gpg_housecleaning (void);
|
||||||
void _gpgme_gpg_enable_pipemode ( GpgObject gpg );
|
void _gpgme_gpg_enable_pipemode ( GpgObject gpg );
|
||||||
GpgmeError _gpgme_gpg_add_arg ( GpgObject gpg, const char *arg );
|
GpgmeError _gpgme_gpg_add_arg ( GpgObject gpg, const char *arg );
|
||||||
GpgmeError _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to );
|
GpgmeError _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to );
|
||||||
|
@ -598,6 +598,17 @@ _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_gpgme_io_kill ( int pid, int hard )
|
||||||
|
{
|
||||||
|
HANDLE proc = fd_to_handle (pid);
|
||||||
|
|
||||||
|
#warning I am not sure how to kill a process
|
||||||
|
/* fixme: figure out how this can be done */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Select on the list of fds.
|
* Select on the list of fds.
|
||||||
|
@ -323,6 +323,7 @@ gpgme_register_idle ( void (*fnc)(void) )
|
|||||||
static void
|
static void
|
||||||
run_idle ()
|
run_idle ()
|
||||||
{
|
{
|
||||||
|
_gpgme_gpg_housecleaning ();
|
||||||
if (idle_function)
|
if (idle_function)
|
||||||
idle_function ();
|
idle_function ();
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ main (int argc, char **argv )
|
|||||||
do {
|
do {
|
||||||
err = gpgme_new (&ctx);
|
err = gpgme_new (&ctx);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
gpgme_set_armor (ctx, 1);
|
||||||
|
|
||||||
err = gpgme_data_new_from_mem ( &in, "Hallo Leute\n", 12, 0 );
|
err = gpgme_data_new_from_mem ( &in, "Hallo Leute\n", 12, 0 );
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
Loading…
Reference in New Issue
Block a user