[PATCH 3/4] Catch KeyboardInterrupts and raise them

Sebastian Spaeth Sebastian at SSpaeth.de
Wed Dec 22 14:27:19 UTC 2010


This was previously not important as most of the code was never run in the main thread and thus never got to see KeyboardInterrupts.
In preparation for true singlethreaded mode, we need to protect against KeyboardInterrupts and raise them to the top, cleanly exiting after a ctrl-c.

Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
 offlineimap/accounts.py           |    6 ++++++
 offlineimap/folder/Base.py        |    8 ++++++++
 offlineimap/folder/LocalStatus.py |    3 +++
 offlineimap/init.py               |   14 +++++++-------
 offlineimap/repository/Base.py    |    3 ++-
 5 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/offlineimap/accounts.py b/offlineimap/accounts.py
index 236bba3..e28c7eb 100644
--- a/offlineimap/accounts.py
+++ b/offlineimap/accounts.py
@@ -187,6 +187,8 @@ class AccountSynchronizationMixin:
             try:
                 try:
                     self.sync(siglistener)
+                except (KeyboardInterrupt, SystemExit):
+                    raise
                 except:
                     self.ui.warn("Error occured attempting to sync account " + self.name \
                                  + ": " + str(sys.exc_info()[1]))
@@ -201,6 +203,8 @@ class AccountSynchronizationMixin:
             try:
                 try:
                     self.sync(siglistener)
+                except (KeyboardInterrupt, SystemExit):
+                    raise
                 except:
                     self.ui.warn("Error occured attempting to sync account " + self.name \
                                  + ": " + str(sys.exc_info()[1]))
@@ -370,6 +374,8 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos,
         localfolder.syncmessagesto(statusfolder)
         statusfolder.save()
         localrepos.restore_atime()
+    except (KeyboardInterrupt, SystemExit):
+        raise
     except:
         ui.warn("ERROR in syncfolder for %s folder %s: %s" % \
                 (accountname,remotefolder.getvisiblename(),sys.exc_info()[1]))
diff --git a/offlineimap/folder/Base.py b/offlineimap/folder/Base.py
index d489c11..e1bdf0a 100644
--- a/offlineimap/folder/Base.py
+++ b/offlineimap/folder/Base.py
@@ -289,6 +289,8 @@ class BaseFolder:
                     self.savemessage(newuid, message, flags, rtime)
                     self.deletemessage(uid)
                     uid = newuid
+        except (KeyboardInterrupt):
+            raise
         except:
             self.ui.warn("ERROR attempting to copy message " + str(uid) \
                  + " for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
@@ -394,6 +396,8 @@ class BaseFolder:
 
         try:
             self.syncmessagesto_neguid(dest, applyto)
+        except (KeyboardInterrupt):
+            raise
         except:
             self.ui.warn("ERROR attempting to handle negative uids " \
                 + "for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
@@ -403,6 +407,8 @@ class BaseFolder:
 
         try:
             self.syncmessagesto_delete(dest, applyto)
+        except (KeyboardInterrupt):
+            raise
         except:
             self.ui.warn("ERROR attempting to delete messages " \
                 + "for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
@@ -413,6 +419,8 @@ class BaseFolder:
 
         try:
             self.syncmessagesto_flags(dest, applyto)
+        except (KeyboardInterrupt):
+            raise
         except:
             self.ui.warn("ERROR attempting to sync flags " \
                 + "for account " + self.getaccountname() + ":" + str(sys.exc_info()[1]))
diff --git a/offlineimap/folder/LocalStatus.py b/offlineimap/folder/LocalStatus.py
index 157989d..3195886 100644
--- a/offlineimap/folder/LocalStatus.py
+++ b/offlineimap/folder/LocalStatus.py
@@ -108,7 +108,10 @@ class LocalStatusFolder(BaseFolder):
                     fd = os.open(os.path.dirname(self.filename), os.O_RDONLY)
                     os.fsync(fd)
                     os.close(fd)
+                except (KeyboardInterrupt):
+                    raise
                 except:
+                    #TODO, we should catch a specific Exception here, not ALL. But which?
                     pass
 
         finally:
diff --git a/offlineimap/init.py b/offlineimap/init.py
index d895737..828d696 100644
--- a/offlineimap/init.py
+++ b/offlineimap/init.py
@@ -329,14 +329,14 @@ class OfflineImap:
                                            'siglisteners': siglisteners})
             t.setDaemon(1)
             t.start()
-        except:
-            ui.mainException()
-    
-        try:
-            threadutil.exitnotifymonitorloop(threadutil.threadexited)
-        except SystemExit:
+            offlineimap.threadutil.exitnotifymonitorloop(offlineimap.threadutil.threadexited)
+
+        except KeyboardInterrupt:
+            ui.terminate(1, errormsg = 'CTRL-C pressed, aborting...')
+            return
+        except (SystemExit):
             raise
         except:
-            ui.mainException()  # Also expected to terminate.
+            ui.mainException()
 
         
diff --git a/offlineimap/repository/Base.py b/offlineimap/repository/Base.py
index 0f4dd76..cec9c61 100644
--- a/offlineimap/repository/Base.py
+++ b/offlineimap/repository/Base.py
@@ -163,10 +163,11 @@ class BaseRepository(CustomConfig.ConfigHelperMixin):
                     dest.makefolder(key)
                     for copyfolder in copyfolders:
                         copyfolder.makefolder(key.replace(dest.getsep(), copyfolder.getsep()))
+                except (KeyboardInterrupt):
+                    raise
                 except:
                     getglobalui().warn("ERROR Attempting to make folder " \
                         + key + ":"  +str(sys.exc_info()[1]))
-                
 
         #
         # Find deleted folders.
-- 
1.7.1




More information about the OfflineIMAP-project mailing list