[pypy-svn] r17370 - in pypy/dist/pypy: lib module/__builtin__ module/__builtin__/test

arigo at codespeak.net arigo at codespeak.net
Thu Sep 8 16:27:08 CEST 2005


Author: arigo
Date: Thu Sep  8 16:27:07 2005
New Revision: 17370

Modified:
   pypy/dist/pypy/lib/_osfilewrapper.py
   pypy/dist/pypy/module/__builtin__/importing.py
   pypy/dist/pypy/module/__builtin__/test/test_import.py
Log:
Don't crash trying to write .pyc files, just ignore the error and
try hard not to leave a broken .pyc file behind.

Test.



Modified: pypy/dist/pypy/lib/_osfilewrapper.py
==============================================================================
--- pypy/dist/pypy/lib/_osfilewrapper.py	(original)
+++ pypy/dist/pypy/lib/_osfilewrapper.py	Thu Sep  8 16:27:07 2005
@@ -27,6 +27,9 @@
             # os.write will raise an error itself
             writecount += os.write(self.fd, buf[writecount:])
 
+    def seek(self, position):
+        os.lseek(self.fd, position, 0)
+
     def close(self):
         os.close(self.fd)
 

Modified: pypy/dist/pypy/module/__builtin__/importing.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/importing.py	(original)
+++ pypy/dist/pypy/module/__builtin__/importing.py	Thu Sep  8 16:27:07 2005
@@ -488,13 +488,35 @@
         #print "indeed writing", cpathname
     try:
         w_str = space.call_method(w_marshal, 'dumps', space.wrap(co))
+        strbuf = space.str_w(w_str)
     except OperationError:
         #print "Problem while marshalling %s, skipping" % cpathname
         return
-    fd = os.open(cpathname, BIN_WRITEMASK, 0666)
-    osfile = OsFileWrapper(fd)
-    _w_long(osfile, pyc_magic)
-    _w_long(osfile, mtime)
-    strbuf = space.str_w(w_str)
-    osfile.write(strbuf)
-    os.close(fd)
+    #
+    # Careful here: we must not crash nor leave behind something that looks
+    # too much like a valid pyc file but really isn't one.
+    #
+    try:
+        fd = os.open(cpathname, BIN_WRITEMASK, 0666)
+    except OSError:
+        return    # cannot create file
+    try:
+        osfile = OsFileWrapper(fd)
+        try:
+            # will patch the header later; write zeroes until we are sure that
+            # the rest of the file is valid
+            _w_long(osfile, 0)   # pyc_magic
+            _w_long(osfile, 0)   # mtime
+            osfile.write(strbuf)
+
+            # should be ok (XXX or should call os.fsync() to be sure?)
+            osfile.seek(0)
+            _w_long(osfile, pyc_magic)
+            _w_long(osfile, mtime)
+        finally:
+            osfile.close()
+    except OSError:
+        try:
+            os.unlink(pathname)
+        except OSError:
+            pass

Modified: pypy/dist/pypy/module/__builtin__/test/test_import.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/test/test_import.py	(original)
+++ pypy/dist/pypy/module/__builtin__/test/test_import.py	Thu Sep  8 16:27:07 2005
@@ -52,6 +52,7 @@
              __init__ = "import sys, pkg_substituted\n"
                         "sys.modules[__name__] = pkg_substituted")
     setuppkg("pkg_substituted", mod='')
+    p = setuppkg("readonly", x='')
 
     # create compiled/x.py and a corresponding pyc file
     p = setuppkg("compiled", x = "x = 84")
@@ -229,6 +230,18 @@
         import compiled.x
         assert compiled.x == sys.modules.get('compiled.x')
 
+    def test_cannot_write_pyc(self):
+        import sys, os
+        p = os.path.join(sys.path[-1], 'readonly')
+        try:
+            os.chmod(p, 0555)
+        except:
+            skip("cannot chmod() the test directory to read-only")
+        try:
+            import readonly.x    # cannot write x.pyc, but should not crash
+        finally:
+            os.chmod(p, 0775)
+
 def _getlong(data):
     x = marshal.dumps(data)
     return x[-4:]



More information about the Pypy-commit mailing list