Commits

Martin Matusiak committed 1a0bf77

implement os.truncate

  • Participants
  • Parent commits 6fcd3a9
  • Branches py3.3

Comments (0)

Files changed (3)

File pypy/module/posix/__init__.py

         interpleveldefs['fchmod'] = 'interp_posix.fchmod'
     if hasattr(os, 'ftruncate'):
         interpleveldefs['ftruncate'] = 'interp_posix.ftruncate'
+        interpleveldefs['truncate'] = 'interp_posix.truncate'
     if hasattr(os, 'fsync'):
         interpleveldefs['fsync'] = 'interp_posix.fsync'
     if hasattr(os, 'fdatasync'):

File pypy/module/posix/interp_posix.py

 
 @unwrap_spec(fd=c_int, length=r_longlong)
 def ftruncate(space, fd, length):
-    """Truncate a file to a specified length."""
+    """Truncate a file (by file descriptor) to a specified length."""
     try:
         os.ftruncate(fd, length)
     except IOError, e:
     except OSError, e:
         raise wrap_oserror(space, e)
 
+def truncate(space, w_path, w_length):
+    """Truncate a file to a specified length."""
+    allocated_fd = False
+    fd = -1
+    try:
+        if space.isinstance_w(w_path, space.w_int):
+            w_fd = w_path
+        else:
+            w_fd = open(space, w_path, os.O_RDWR | os.O_CREAT)
+            allocated_fd = True
+
+        fd = space.c_filedescriptor_w(w_fd)
+        length = space.int_w(w_length)
+        return ftruncate(space, fd, length)
+
+    finally:
+        if allocated_fd and fd != -1:
+            close(space, fd)
+
 def fsync(space, w_fd):
     """Force write of file with filedescriptor to disk."""
     fd = space.c_filedescriptor_w(w_fd)

File pypy/module/posix/test/test_posix2.py

                 data = f.read()
                 assert data == "who cares?"
 
+    if hasattr(os, 'ftruncate'):
+        def test_truncate(self):
+            posix = self.posix
+            dest = self.path
+
+            def mkfile(dest, size=4):
+                with open(dest, 'wb') as f:
+                    f.write(b'd' * size)
+
+            # Check invalid inputs
+            mkfile(dest)
+            raises(OSError, posix.truncate, dest, -1)
+            raises(OSError, posix.truncate, 1, 1)
+            raises(TypeError, posix.truncate, dest, None)
+            raises(TypeError, posix.truncate, None, None)
+
+            # Truncate via file descriptor
+            mkfile(dest)
+            with open(dest, 'wb') as f:
+                posix.truncate(f.fileno(), 1)
+            assert 1 == posix.stat(dest).st_size
+
+            # Truncate via filename
+            mkfile(dest)
+            posix.truncate(dest, 1)
+            assert 1 == posix.stat(dest).st_size
+
     try:
         os.getlogin()
     except (AttributeError, OSError):