diff options
author | Jeffrey Stedfast <fejj@ximian.com> | 2002-06-28 08:07:00 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2002-06-28 08:07:00 +0800 |
commit | 292847cc9694ae7041af1390f4d1956d23f20c6a (patch) | |
tree | 731344705172355707ab8e36884bfbc36be0ad9e /camel/camel-gpg-context.c | |
parent | 46bba132c7e353a3bba252ddf4f484b0c237ac46 (diff) | |
download | gsoc2013-evolution-292847cc9694ae7041af1390f4d1956d23f20c6a.tar.gz gsoc2013-evolution-292847cc9694ae7041af1390f4d1956d23f20c6a.tar.zst gsoc2013-evolution-292847cc9694ae7041af1390f4d1956d23f20c6a.zip |
Loop on our reads while errno is EINTR or EAGAIN. Also make sure to
2002-06-27 Jeffrey Stedfast <fejj@ximian.com>
* camel-gpg-context.c (gpg_ctx_op_step): Loop on our reads while
errno is EINTR or EAGAIN. Also make sure to completely read stdout
and stderr by keeping better state.
(gpg_ctx_parse_status): In the case of a NODATA response from gpg,
try to use the diagnostics that gpg may have written to its
stderr.
(gpg_verify): Check that the gpg process has not exited.
(gpg_ctx_op_wait): Make sure we haven't already exited (as by
gpg_ctx_op_is_exited()) and if we have, retrieve the exit status
from the gpg context.
svn path=/trunk/; revision=17320
Diffstat (limited to 'camel/camel-gpg-context.c')
-rw-r--r-- | camel/camel-gpg-context.c | 70 |
1 files changed, 51 insertions, 19 deletions
diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c index 7d5f167d64..c847b9c66a 100644 --- a/camel/camel-gpg-context.c +++ b/camel/camel-gpg-context.c @@ -249,6 +249,9 @@ struct _GpgCtx { GByteArray *diagnostics; + int exit_status; + + unsigned int exited:1; unsigned int complete:1; unsigned int seen_eof1:1; unsigned int seen_eof2:1; @@ -262,7 +265,7 @@ struct _GpgCtx { unsigned int validsig:1; unsigned int trust:3; - unsigned int padding:19; + unsigned int padding:18; }; static struct _GpgCtx * @@ -279,6 +282,8 @@ gpg_ctx_new (CamelSession *session, const char *path) gpg->seen_eof1 = FALSE; gpg->seen_eof2 = FALSE; gpg->pid = (pid_t) -1; + gpg->exit_status = 0; + gpg->exited = FALSE; gpg->path = g_strdup (path); gpg->userid = NULL; @@ -1100,16 +1105,38 @@ gpg_ctx_op_complete (struct _GpgCtx *gpg) return gpg->complete && gpg->seen_eof1 && gpg->seen_eof2; } +static gboolean +gpg_ctx_op_is_exited (struct _GpgCtx *gpg) +{ + pid_t retval; + int status; + + if (gpg->exited) + return TRUE; + + retval = waitpid (gpg->pid, &status, WNOHANG); + if (retval == gpg->pid) { + gpg->exit_status = status; + gpg->exited = TRUE; + return TRUE; + } + + return FALSE; +} + static void gpg_ctx_op_cancel (struct _GpgCtx *gpg) { pid_t retval; int status; + if (gpg->exited) + return; + kill (gpg->pid, SIGTERM); sleep (1); retval = waitpid (gpg->pid, &status, WNOHANG); - if (retval == 0) { + if (retval == (pid_t) 0) { /* no more mr nice guy... */ kill (gpg->pid, SIGKILL); sleep (1); @@ -1124,25 +1151,30 @@ gpg_ctx_op_wait (struct _GpgCtx *gpg) pid_t retval; int status; - sigemptyset (&mask); - sigaddset (&mask, SIGALRM); - sigprocmask (SIG_BLOCK, &mask, &omask); - alarm (1); - retval = waitpid (gpg->pid, &status, 0); - alarm (0); - sigprocmask (SIG_SETMASK, &omask, NULL); - - if (retval == (pid_t) -1 && errno == EINTR) { - /* The child is hanging: send a friendly reminder. */ - kill (gpg->pid, SIGTERM); - sleep (1); - retval = waitpid (gpg->pid, &status, WNOHANG); - if (retval == (pid_t) 0) { - /* Still hanging; use brute force. */ - kill (gpg->pid, SIGKILL); + if (!gpg->exited) { + sigemptyset (&mask); + sigaddset (&mask, SIGALRM); + sigprocmask (SIG_BLOCK, &mask, &omask); + alarm (1); + retval = waitpid (gpg->pid, &status, 0); + alarm (0); + sigprocmask (SIG_SETMASK, &omask, NULL); + + if (retval == (pid_t) -1 && errno == EINTR) { + /* The child is hanging: send a friendly reminder. */ + kill (gpg->pid, SIGTERM); sleep (1); retval = waitpid (gpg->pid, &status, WNOHANG); + if (retval == (pid_t) 0) { + /* Still hanging; use brute force. */ + kill (gpg->pid, SIGKILL); + sleep (1); + retval = waitpid (gpg->pid, &status, WNOHANG); + } } + } else { + status = gpg->exit_status; + retval = gpg->pid; } if (retval != (pid_t) -1 && WIFEXITED (status)) @@ -1282,7 +1314,7 @@ gpg_verify (CamelCipherContext *context, CamelCipherHash hash, goto exception; } - while (!gpg_ctx_op_complete (gpg)) { + while (!gpg_ctx_op_complete (gpg) && !gpg_ctx_op_is_exited (gpg)) { if (camel_operation_cancel_check (NULL)) { camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Cancelled.")); |