[pypy-commit] pypy py3.5: PR #530 from nanjekye (manual merge)

arigo pypy.commits at gmail.com
Sun Apr 2 05:03:50 EDT 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r90918:debef6d067cc
Date: 2017-04-02 11:02 +0200
http://bitbucket.org/pypy/pypy/changeset/debef6d067cc/

Log:	PR #530 from nanjekye (manual merge)

	posix_fallocate and posix_fadvise implementation

diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -222,6 +222,14 @@
     if hasattr(rposix, 'pwrite'):
        interpleveldefs['pwrite'] = 'interp_posix.pwrite'
 
+    if hasattr(rposix, 'posix_fadvise'):
+        interpleveldefs['posix_fadvise'] = 'interp_posix.posix_fadvise'
+        interpleveldefs['posix_fallocate'] = 'interp_posix.posix_fallocate'
+        for _name in ['POSIX_FADV_WILLNEED', 'POSIX_FADV_NORMAL', 'POSIX_FADV_SEQUENTIAL',
+        'POSIX_FADV_RANDOM', 'POSIX_FADV_NOREUSE', 'POSIX_FADV_DONTNEED']:
+            assert getattr(rposix, _name) is not None, "missing %r" % (_name,)
+            interpleveldefs[_name] = 'space.wrap(%d)' % getattr(rposix, _name)
+
     for _name in ["O_CLOEXEC"]:
         if getattr(rposix, _name) is not None:
             interpleveldefs[_name] = 'space.wrap(%d)' % getattr(rposix, _name)
diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -401,6 +401,30 @@
         else:
             return space.newint(res)
 
+ at unwrap_spec(fd=c_int, length=r_longlong, offset=r_longlong)
+def posix_fallocate(space, fd, offset, length):
+    """allocate file space .
+    """
+    while True:
+        try:
+            s = rposix.posix_fallocate(fd, offset, length)
+        except OSError as e:
+            wrap_oserror(space, e, eintr_retry=True)
+        else:
+           return space.newint(s)
+
+ at unwrap_spec(fd=c_int, offset=r_longlong, length=r_longlong, advice=int)
+def posix_fadvise(space, fd, offset, length, advice):
+    """predeclare an access pattern for file data .
+    """
+    while True:
+        try:
+            res = rposix.posix_fadvise(fd, offset, length, advice)
+        except OSError as e:
+            wrap_oserror(space, e, eintr_retry=True)
+        else:
+            return space.newint(res)
+
 # ____________________________________________________________
 
 STAT_FIELDS = unrolling_iterable(enumerate(rposix_stat.STAT_FIELDS))
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -860,6 +860,42 @@
             finally:
                 os.close(fd)
 
+    if hasattr(rposix, 'posix_fadvise'):
+        def test_os_posix_fadvise(self):
+            posix, os = self.posix, self.os
+            localdir = os.getcwd()
+            os.mkdir(self.path2 + 'test_os_posix_fadvise')
+            try:
+                fd = os.open(self.path2 + 'test_os_posix_fadvise', os.O_RDONLY)
+                try:
+                    mypath = os.getcwd()
+                    assert posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED) == 0
+                    assert posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_NORMAL) == 0
+                    assert posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_SEQUENTIAL) == 0
+                    assert posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_RANDOM) == 0
+                    assert posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_NOREUSE) == 0
+                    assert posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_DONTNEED) == 0
+                finally:
+                    os.close(fd)
+            finally:
+                os.chdir(localdir)
+
+    if hasattr(rposix, 'posix_fallocate'):
+        def test_os_posix_posix_fallocate(self):
+            posix, os = self.posix, self.os
+            fd = os.open(self.path2 + 'test_os_posix_fallocate', os.O_WRONLY | os.O_CREAT)
+            try:
+                assert posix.posix_fallocate(fd, 0, 10) == 0
+            except OSError as inst:
+                """ ZFS seems not to support fallocate.
+                so skipping solaris-based since it is likely to come with ZFS
+                """
+                if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
+                    raise
+            finally:
+                os.close(fd)
+
+
     def test_largefile(self):
         os = self.posix
         fd = os.open(self.path2 + 'test_largefile',
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -255,6 +255,12 @@
     PRIO_PROCESS = rffi_platform.DefinedConstantInteger('PRIO_PROCESS')
     PRIO_PGRP = rffi_platform.DefinedConstantInteger('PRIO_PGRP')
     PRIO_USER = rffi_platform.DefinedConstantInteger('PRIO_USER')
+    POSIX_FADV_WILLNEED = rffi_platform.DefinedConstantInteger('POSIX_FADV_WILLNEED')
+    POSIX_FADV_NORMAL = rffi_platform.DefinedConstantInteger('POSIX_FADV_NORMAL')
+    POSIX_FADV_SEQUENTIAL = rffi_platform.DefinedConstantInteger('POSIX_FADV_SEQUENTIAL')
+    POSIX_FADV_RANDOM= rffi_platform.DefinedConstantInteger('POSIX_FADV_RANDOM')
+    POSIX_FADV_NOREUSE = rffi_platform.DefinedConstantInteger('POSIX_FADV_NOREUSE')
+    POSIX_FADV_DONTNEED = rffi_platform.DefinedConstantInteger('POSIX_FADV_DONTNEED')
     O_NONBLOCK = rffi_platform.DefinedConstantInteger('O_NONBLOCK')
     OFF_T = rffi_platform.SimpleType('off_t')
     OFF_T_SIZE = rffi_platform.SizeOf('off_t')
@@ -449,7 +455,7 @@
 def close(fd):
     validate_fd(fd)
     handle_posix_error('close', c_close(fd))
-
+    
 c_lseek = external('_lseeki64' if _WIN32 else 'lseek',
                    [rffi.INT, rffi.LONGLONG, rffi.INT], rffi.LONGLONG,
                    macro=_MACRO_ON_POSIX, save_err=rffi.RFFI_SAVE_ERRNO)
@@ -490,6 +496,23 @@
         with rffi.scoped_nonmovingbuffer(data) as buf:
             return handle_posix_error('pwrite', c_pwrite(fd, buf, count, offset))
 
+    c_posix_fallocate = external('posix_fallocate',
+                      [rffi.INT, OFF_T, OFF_T], rffi.INT,
+                      save_err=rffi.RFFI_SAVE_ERRNO)
+    c_posix_fadvise = external('posix_fadvise',
+                       [rffi.INT, OFF_T, OFF_T, rffi.INT], rffi.INT,
+                       save_err=rffi.RFFI_SAVE_ERRNO)
+
+    @enforceargs(int, None, None)
+    def posix_fallocate(fd, offset, length):
+        validate_fd(fd)
+        return handle_posix_error('posix_fallocate', c_posix_fallocate(fd, offset, length))
+
+    @enforceargs(int, None, None, int)
+    def posix_fadvise(fd, offset, length, advice):
+        validate_fd(fd)
+        return handle_posix_error('posix_fadvise', c_posix_fadvise(fd, offset, length, advice))
+
 c_ftruncate = external('ftruncate', [rffi.INT, rffi.LONGLONG], rffi.INT,
                        macro=_MACRO_ON_POSIX, save_err=rffi.RFFI_SAVE_ERRNO)
 c_fsync = external('fsync' if not _WIN32 else '_commit', [rffi.INT], rffi.INT,
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -750,3 +750,38 @@
     finally:
         os.close(fd)
     py.test.raises(OSError, rposix.pwrite, fd, b'ea', 1)
+
+ at rposix_requires('posix_fadvise')
+def test_posix_fadvise():
+    fname = str(udir.join('test_os_posix_fadvise'))
+    localdir = os.getcwd()
+    os.mkdir(fname)
+    try:
+        fd = os.open(fname, os.O_RDONLY, 0777)
+        try:
+            mypath = os.getcwd()
+            assert rposix.posix_fadvise(fd, 0, 0, rposix.POSIX_FADV_WILLNEED) == 0
+            assert rposix.posix_fadvise(fd, 0, 0, rposix.POSIX_FADV_NORMAL) == 0
+            assert rposix.posix_fadvise(fd, 0, 0, rposix.POSIX_FADV_SEQUENTIAL) == 0
+            assert rposix.posix_fadvise(fd, 0, 0, rposix.POSIX_FADV_RANDOM) == 0
+            assert rposix.posix_fadvise(fd, 0, 0, rposix.POSIX_FADV_NOREUSE) == 0
+            assert rposix.posix_fadvise(fd, 0, 0, rposix.POSIX_FADV_DONTNEED) == 0
+        finally:
+            os.close(fd)
+    finally:
+        os.chdir(localdir)
+
+ at rposix_requires('posix_fallocate')
+def test_posix_fallocate():
+    fname = str(udir.join('os_test.txt'))
+    fd = os.open(fname, os.O_WRONLY | os.O_CREAT, 0777)
+    try:
+        assert rposix.posix_fallocate(fd, 0, 10) == 0
+    except OSError as inst:
+        """ ZFS seems not to support fallocate.
+        so skipping solaris-based since it is likely to come with ZFS
+        """
+        if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
+            raise
+    finally:
+        os.close(fd)


More information about the pypy-commit mailing list