]> code.delx.au - offlineimap/commitdiff
Apply darwin.patch from Vincent Beffara
authorJohn Goerzen <jgoerzen@complete.org>
Thu, 1 May 2008 20:20:56 +0000 (15:20 -0500)
committerJohn Goerzen <jgoerzen@complete.org>
Thu, 1 May 2008 20:20:56 +0000 (15:20 -0500)
fixes #20

 04/27/2008 09:34 AM - Vincent Beffara

    * File darwin.patch added

OK, I finally installed an IMAPS server on my iMac, so I could test a
little further. For some reason, fixing the read() method in
imaplibutil.py did not seem to work (it hung on connecting to the
server) - however, modifying the file imapserver.py similarly to the
non-SSL case fixed the crash.

I also reduced the chunk size to 100k instead of 1M, as 1M seemed to
still trigger the memory error in some cases. Ah, and I added a
platform test, so that the patch does essentially nothing on
non-Darwin machines ...

So, still no guarantee, but the attached patch works for me. Any
comments ?

(If noone here screams in horror at my code, I will include the patch
into the Fink package and see what happens there.)

offlineimap/imapserver.py

index 4e37ece334e6cfc8dad8a566e24d9b24034cce37..2f0119ee38117c434837b9f3cc8afb928ec9add6 100644 (file)
@@ -23,6 +23,9 @@ from threading import *
 import thread, hmac, os
 import base64
 
+from StringIO import StringIO
+from platform import system
+
 try:
     # do we have a recent pykerberos?
     have_gss = False
@@ -60,10 +63,42 @@ class UsefulIMAP4(UsefulIMAPMixIn, imaplib.IMAP4):
     def open(self, host = '', port = imaplib.IMAP4_PORT):
         imaplibutil.new_open(self, host, port)
 
+    # This is a hack around Darwin's implementation of realloc() (which
+    # Python uses inside the socket code). On Darwin, we split the
+    # message into 100k chunks, which should be small enough - smaller
+    # might start seriously hurting performance ...
+
+    def read(self, size):
+        if system() == 'Darwin':
+            read = 0
+            io = StringIO()
+            while read < size:
+                data = self.file.read(min(size-read,100000))
+                read += len(data)
+                io.write(data)
+            return io.getvalue()
+        else:
+            return self.file.read(size)
+
 class UsefulIMAP4_SSL(UsefulIMAPMixIn, imaplibutil.WrappedIMAP4_SSL):
     def open(self, host = '', port = imaplib.IMAP4_SSL_PORT):
         imaplibutil.new_open_ssl(self, host, port)
 
+    # This is the same hack as above, to be used in the case of an SSL
+    # connexion.
+
+    def read(self, size):
+        if system() == 'Darwin':
+            read = 0
+            io = StringIO()
+            while read < size:
+                data = self.sslobj.read(min(size-read,100000))
+                read += len(data)
+                io.write(data)
+            return io.getvalue()
+        else:
+            return self.sslobj.read(size)
+
 class UsefulIMAP4_Tunnel(UsefulIMAPMixIn, imaplibutil.IMAP4_Tunnel): pass
 
 class IMAPServer: