]> granicus.if.org Git - neomutt/commitdiff
Allow the user to interrupt slow IO operations
authorAntonio Radici <antonio@dyne.org>
Sat, 10 Sep 2016 10:48:50 +0000 (11:48 +0100)
committerRichard Russon <rich@flatcap.org>
Sat, 10 Sep 2016 11:05:35 +0000 (12:05 +0100)
imap/command.c
mutt_socket.c
mutt_ssl.c
mutt_ssl_gnutls.c
mx.c
sendlib.c

index 4d34d2426fa2cca7ce053a47e8fa9e2c81ebb223..5177475bd2af890154c068d7b6fed54b90ba8ca6 100644 (file)
@@ -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;
index a2c489f657e30c3343a3c8d444d968fe46f801a3..79aa81e8e82d75eaa4f8faf6751be1021fdddaf8 100644 (file)
@@ -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;
 }
index 2a9266fd9d2443611bd192f7475a7b49b082ec56..d5826acecb665724cee109d4b18712dadbded9de 100644 (file)
@@ -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;
 }
index 2084ad04e0ca2ef27d77e7c57b336cd539adc898..4e6a4fd504e8604d89bf51ff90e4c2d202ed374d 100644 (file)
@@ -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 414602a60af7d7d04b674d05ef9a9806eb9ac3ac..14149250f3acd729aa1a47e783d568f03ed50b8b 100644 (file)
--- 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;
index 2ebf45544060463eab891e93fde0364edddb54bb..cbc546a6c158225ff9c6fdb6d4a77cec7e906fdf 100644 (file)
--- 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);
 }