From 1f19f808dbcfe1cb02e4806a9f583ae9c657b7e5 Mon Sep 17 00:00:00 2001 From: Antonio Radici Date: Sat, 10 Sep 2016 11:48:50 +0100 Subject: [PATCH] Allow the user to interrupt slow IO operations --- imap/command.c | 3 +++ mutt_socket.c | 16 +++++++++++++++- mutt_ssl.c | 13 +++++++++++-- mutt_ssl_gnutls.c | 14 ++++++++------ mx.c | 2 +- sendlib.c | 17 ++++++++++++++++- 6 files changed, 54 insertions(+), 11 deletions(-) diff --git a/imap/command.c b/imap/command.c index 4d34d2426..5177475bd 100644 --- a/imap/command.c +++ b/imap/command.c @@ -242,9 +242,12 @@ int imap_exec (IMAP_DATA* idata, const char* cmdstr, int flags) if (flags & IMAP_CMD_QUEUE) return 0; + // Allow interruptions, particularly useful if there are network problems. + mutt_allow_interrupt (1); do rc = imap_cmd_step (idata); while (rc == IMAP_CMD_CONTINUE); + mutt_allow_interrupt (0); if (rc == IMAP_CMD_NO && (flags & IMAP_CMD_FAIL_OK)) return -2; diff --git a/mutt_socket.c b/mutt_socket.c index a2c489f65..79aa81e8e 100644 --- a/mutt_socket.c +++ b/mutt_socket.c @@ -398,12 +398,19 @@ int raw_socket_read (CONNECTION* conn, char* buf, size_t len) { int rc; + mutt_allow_interrupt (1); if ((rc = read (conn->fd, buf, len)) == -1) { mutt_error (_("Error talking to %s (%s)"), conn->account.host, strerror (errno)); mutt_sleep (2); - } + } else if (errno == EINTR) { + rc = -1; + mutt_error (_("Error talking to %s (%s)"), conn->account.host, + strerror (errno)); + mutt_sleep (2); + } + mutt_allow_interrupt (0); return rc; } @@ -412,12 +419,19 @@ int raw_socket_write (CONNECTION* conn, const char* buf, size_t count) { int rc; + mutt_allow_interrupt (1); if ((rc = write (conn->fd, buf, count)) == -1) { mutt_error (_("Error talking to %s (%s)"), conn->account.host, strerror (errno)); mutt_sleep (2); + } else if (errno == EINTR) { + rc = -1; + mutt_error (_("Error talking to %s (%s)"), conn->account.host, + strerror (errno)); + mutt_sleep (2); } + mutt_allow_interrupt (0); return rc; } diff --git a/mutt_ssl.c b/mutt_ssl.c index 2a9266fd9..d5826acec 100644 --- a/mutt_ssl.c +++ b/mutt_ssl.c @@ -303,8 +303,12 @@ static int ssl_socket_read (CONNECTION* conn, char* buf, size_t len) int rc; rc = SSL_read (data->ssl, buf, len); - if (rc <= 0) + if (rc <= 0 || errno == EINTR) { + if (errno == EINTR) + { + rc = -1; + } data->isopen = 0; ssl_err (data, rc); } @@ -318,8 +322,13 @@ static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len) int rc; rc = SSL_write (data->ssl, buf, len); - if (rc <= 0) + if (rc <= 0 || errno == EINTR) { + if (errno == EINTR) + { + rc = -1; + } ssl_err (data, rc); + } return rc; } diff --git a/mutt_ssl_gnutls.c b/mutt_ssl_gnutls.c index 2084ad04e..4e6a4fd50 100644 --- a/mutt_ssl_gnutls.c +++ b/mutt_ssl_gnutls.c @@ -141,14 +141,16 @@ static int tls_socket_read (CONNECTION* conn, char* buf, size_t len) do { ret = gnutls_record_recv (data->state, buf, len); - if (ret < 0 && gnutls_error_is_fatal(ret) == 1) + if ((ret < 0 && + gnutls_error_is_fatal(ret) == 1) || + ret == GNUTLS_E_INTERRUPTED + ) { mutt_error ("tls_socket_read (%s)", gnutls_strerror (ret)); - mutt_sleep (4); + mutt_sleep (2); return -1; } - } - while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); + } while (ret == GNUTLS_E_AGAIN); return ret; } @@ -171,7 +173,7 @@ static int tls_socket_write (CONNECTION* conn, const char* buf, size_t len) ret = gnutls_record_send (data->state, buf + sent, len - sent); if (ret < 0) { - if (gnutls_error_is_fatal(ret) == 1) + if (gnutls_error_is_fatal(ret) == 1 || ret == GNUTLS_E_INTERRUPTED) { mutt_error ("tls_socket_write (%s)", gnutls_strerror (ret)); mutt_sleep (4); @@ -434,7 +436,7 @@ static int tls_negotiate (CONNECTION * conn) err = gnutls_handshake(data->state); - while (err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED) + while (err == GNUTLS_E_AGAIN) { err = gnutls_handshake(data->state); } diff --git a/mx.c b/mx.c index 414602a60..14149250f 100644 --- a/mx.c +++ b/mx.c @@ -1423,7 +1423,7 @@ MESSAGE *mx_open_new_message (CONTEXT *dest, HEADER *hdr, int flags) /* check for new mail */ int mx_check_mailbox (CONTEXT *ctx, int *index_hint) { - if (!ctx) + if (!ctx || ctx->magic == 0) { dprint (1, (debugfile, "mx_check_mailbox: null or invalid context.\n")); return -1; diff --git a/sendlib.c b/sendlib.c index 2ebf45544..cbc546a6c 100644 --- a/sendlib.c +++ b/sendlib.c @@ -274,6 +274,10 @@ static void encode_base64 (FGETCONV * fc, FILE *fout, int istext) while ((ch = fgetconv (fc)) != EOF) { + if (SigInt == 1) { + SigInt = 0; + return; + } if (istext && ch == '\n' && ch1 != '\r') b64_putc('\r', fout); b64_putc(ch, fout); @@ -287,8 +291,13 @@ static void encode_8bit (FGETCONV *fc, FILE *fout, int istext) { int ch; - while ((ch = fgetconv (fc)) != EOF) + while ((ch = fgetconv (fc)) != EOF) { + if (SigInt == 1) { + SigInt = 0; + return; + } fputc (ch, fout); + } } @@ -465,6 +474,7 @@ int mutt_write_mime_body (BODY *a, FILE *f) else fc = fgetconv_open (fpin, 0, 0, 0); + mutt_allow_interrupt (1); if (a->encoding == ENCQUOTEDPRINTABLE) encode_quoted (fc, f, write_as_text_part (a)); else if (a->encoding == ENCBASE64) @@ -473,10 +483,15 @@ int mutt_write_mime_body (BODY *a, FILE *f) encode_8bit (fc, f, write_as_text_part (a)); else mutt_copy_stream (fpin, f); + mutt_allow_interrupt (0); fgetconv_close (&fc); safe_fclose (&fpin); + if (SigInt == 1) { + SigInt = 0; + return -1; + } return (ferror (f) ? -1 : 0); } -- 2.49.0