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>
|
||||
|
||||
* 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.
|
||||
(_gpgme_io_write): Ditto.
|
||||
(_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_parent_list );
|
||||
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);
|
||||
|
||||
|
||||
|
@ -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
|
||||
gpgme_op_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only )
|
||||
{
|
||||
GpgmeError rc = 0;
|
||||
int i;
|
||||
|
||||
fail_on_pending_request( c );
|
||||
if ( !c )
|
||||
return mk_error (Invalid_Value);
|
||||
c->pending = 1;
|
||||
|
||||
_gpgme_release_result (c);
|
||||
|
@ -206,6 +206,12 @@ _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal )
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_gpgme_io_kill ( int pid, int hard )
|
||||
{
|
||||
return kill ( pid, hard? SIGKILL : SIGTERM );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Select on the list of fds.
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "rungpg.h"
|
||||
#include "context.h" /*temp hack until we have GpmeData methods to do I/O */
|
||||
#include "io.h"
|
||||
#include "sema.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 running;
|
||||
int exit_status;
|
||||
int exit_signal;
|
||||
|
||||
/* stuff needed for pipemode */
|
||||
struct {
|
||||
@ -117,7 +116,17 @@ struct gpg_object_s {
|
||||
} 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_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]);
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
kill_gpg ( GpgObject gpg )
|
||||
do_reaping (void)
|
||||
{
|
||||
#if 0
|
||||
if ( gpg->running ) {
|
||||
/* still running? Must send a killer */
|
||||
kill ( gpg->pid, SIGTERM);
|
||||
sleep (2);
|
||||
if ( !waitpid (gpg->pid, NULL, WNOHANG) ) {
|
||||
/* pay the murderer better and then forget about it */
|
||||
kill (gpg->pid, SIGKILL);
|
||||
struct reap_s *r, *rlast;
|
||||
static time_t last_check;
|
||||
time_t cur_time = time (NULL);
|
||||
|
||||
/* a race does not matter here */
|
||||
if (!last_check)
|
||||
last_check = time(NULL);
|
||||
|
||||
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
|
||||
|
@ -95,6 +95,7 @@ typedef const char *(*GpgCommandHandler)(void*, GpgStatusCode code,
|
||||
|
||||
GpgmeError _gpgme_gpg_new ( GpgObject *r_gpg );
|
||||
void _gpgme_gpg_release ( GpgObject gpg );
|
||||
void _gpgme_gpg_housecleaning (void);
|
||||
void _gpgme_gpg_enable_pipemode ( GpgObject gpg );
|
||||
GpgmeError _gpgme_gpg_add_arg ( GpgObject gpg, const char *arg );
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -323,6 +323,7 @@ gpgme_register_idle ( void (*fnc)(void) )
|
||||
static void
|
||||
run_idle ()
|
||||
{
|
||||
_gpgme_gpg_housecleaning ();
|
||||
if (idle_function)
|
||||
idle_function ();
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ main (int argc, char **argv )
|
||||
do {
|
||||
err = gpgme_new (&ctx);
|
||||
fail_if_err (err);
|
||||
gpgme_set_armor (ctx, 1);
|
||||
|
||||
err = gpgme_data_new_from_mem ( &in, "Hallo Leute\n", 12, 0 );
|
||||
fail_if_err (err);
|
||||
|
Loading…
Reference in New Issue
Block a user