[pypy-commit] pypy py3.5: Merged in nanjekye/pypy/jumbo (pull request #528)

arigo pypy.commits at gmail.com
Mon Mar 13 12:30:29 EDT 2017


Author: Armin Rigo <armin.rigo at gmail.com>
Branch: py3.5
Changeset: r90661:f90ac97e3a04
Date: 2017-03-13 16:29 +0000
http://bitbucket.org/pypy/pypy/changeset/f90ac97e3a04/

Log:	Merged in nanjekye/pypy/jumbo (pull request #528)

	Pread/pwrite attribute on py3.5

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
@@ -217,6 +217,11 @@
     if sys.platform.startswith('linux'): #hasattr(rposix, 'sendfile'):
         interpleveldefs['sendfile'] = 'interp_posix.sendfile'
 
+    if hasattr(rposix, 'pread'):
+        interpleveldefs['pread'] = 'interp_posix.pread'
+    if hasattr(rposix, 'pwrite'):
+       interpleveldefs['pwrite'] = 'interp_posix.pwrite'
+
     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
@@ -376,6 +376,31 @@
         except OSError as e:
             wrap_oserror(space, e, eintr_retry=True)
 
+ at unwrap_spec(fd=c_int, length=int, offset=r_longlong)
+def pread(space, fd, length, offset):
+    """Read a string to a file descriptor at a given offset.
+    """
+    while True:
+        try:
+            s = rposix.pread(fd, length, offset)
+        except OSError as e:
+            wrap_oserror(space, e, eintr_retry=True)
+        else:
+           return space.newbytes(s)
+
+ at unwrap_spec(fd=c_int, offset=r_longlong)
+def pwrite(space, fd, w_data, offset):
+    """Write a string to a file descriptor at a given offset.
+    """
+    data = space.getarg_w('y*', w_data)
+    while True:
+        try:
+            res = rposix.pwrite(fd, data.as_str(), offset)
+        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
@@ -836,6 +836,30 @@
                     os.chdir(localdir)
             raises(ValueError, os.fchdir, -1)
 
+    if hasattr(rposix, 'pread'):
+        def test_os_pread(self):
+            os = self.posix
+            fd = os.open(self.path2 + 'test_os_pread', os.O_RDWR | os.O_CREAT)
+            try:
+                os.write(fd, b'test')
+                os.lseek(fd, 0, 0)
+                assert os.pread(fd, 2, 1) == b'es'
+                assert os.read(fd, 2) == b'te'
+            finally:
+                os.close(fd)
+
+    if hasattr(rposix, 'pwrite'):
+        def test_os_pwrite(self):
+            os = self.posix
+            fd = os.open(self.path2 + 'test_os_pwrite', os.O_RDWR | os.O_CREAT)
+            try:
+                os.write(fd, b'test')
+                os.lseek(fd, 0, 0)
+                os.pwrite(fd, b'xx', 1)
+                assert os.read(fd, 4) == b'txxt'
+            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
@@ -464,6 +464,29 @@
             how = SEEK_END
     return handle_posix_error('lseek', c_lseek(fd, pos, how))
 
+c_pread = external('pread',
+                  [rffi.INT, rffi.VOIDP, rffi.SIZE_T , OFF_T], rffi.SSIZE_T,
+                  save_err=rffi.RFFI_SAVE_ERRNO)
+c_pwrite = external('pwrite',
+                   [rffi.INT, rffi.VOIDP, rffi.SIZE_T, OFF_T], rffi.SSIZE_T,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+
+ at enforceargs(int, int, None)
+def pread(fd, count, offset):
+    if count < 0:
+        raise OSError(errno.EINVAL, None)
+    validate_fd(fd)
+    with rffi.scoped_alloc_buffer(count) as buf:
+        void_buf = rffi.cast(rffi.VOIDP, buf.raw)
+        return buf.str(handle_posix_error('pread', c_pread(fd, void_buf, count, offset)))
+        
+ at enforceargs(int, None, None)
+def pwrite(fd, data, offset):
+    count = len(data)
+    validate_fd(fd)
+    with rffi.scoped_nonmovingbuffer(data) as buf:
+        return handle_posix_error('pwrite', c_pwrite(fd, buf, count, offset))
+
 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
@@ -676,7 +676,7 @@
     prio = rposix.getpriority(rposix.PRIO_PROCESS, 0)
     rposix.setpriority(rposix.PRIO_PROCESS, 0, prio)
     py.test.raises(OSError, rposix.getpriority, rposix.PRIO_PGRP, 123456789)
-
+    
 if sys.platform != 'win32':
     def test_sendfile():
         from rpython.rlib import rsocket
@@ -723,3 +723,30 @@
         os.close(fd)
         s2.close()
         s1.close()
+        
+ at rposix_requires('pread')
+def test_pread():
+    fname = str(udir.join('os_test.txt'))
+    fd = os.open(fname, os.O_RDWR | os.O_CREAT)
+    try:
+        assert fd >= 0
+        os.write(fd, b'Hello world')
+        os.lseek(fd, 0, 0)
+        assert rposix.pread(fd, 2, 1) == b'el'
+    finally:
+        os.close(fd)
+    py.test.raises(OSError, rposix.pread, fd, 2, 1)
+
+ at rposix_requires('pwrite')
+def test_pwrite():
+    fname = str(udir.join('os_test.txt'))
+    fd = os.open(fname, os.O_RDWR | os.O_CREAT, 0777)
+    try:
+        assert fd >= 0
+        os.write(fd, b'Hello world')
+        os.lseek(fd, 0, 0)
+        rposix.pwrite(fd, b'ea', 1)
+        assert os.read(fd, 4) == b'Heal'
+    finally:
+        os.close(fd)
+    py.test.raises(OSError, rposix.pwrite, fd, b'ea', 1)


More information about the pypy-commit mailing list