Author: Joannah Nanjekye <nanjekyejoan...@gmail.com> Branch: pread/pwrite Changeset: r90383:9762c2f4cd64 Date: 2017-02-18 21:03 +0300 http://bitbucket.org/pypy/pypy/changeset/9762c2f4cd64/
Log: pread/pwrite 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 @@ -206,6 +206,11 @@ interpleveldefs['get_blocking'] = 'interp_posix.get_blocking' interpleveldefs['set_blocking'] = 'interp_posix.set_blocking' + 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 @@ -269,7 +269,7 @@ raise wrap_oserror(space, e) else: return space.newbytes(s) - + @unwrap_spec(fd=c_int) def write(space, fd, w_data): """Write a string to a file descriptor. Return the number of bytes @@ -282,6 +282,25 @@ else: return space.wrap(res) +@unwrap_spec(fd=c_int, length=int, offset=int) +def pread(space, fd, length, offset): + try: + s = rposix.pread(fd, length, offset) + except OSError as e: + raise wrap_oserror(space, e) + else: + return space.newbytes(s) + +@unwrap_spec(fd=c_int, offset=int) +def pwrite(space, fd, w_data, offset): + data = space.getarg_w('y*', w_data) + try: + res = rposix.pwrite(fd, data.as_str(), offset) + except OSError as e: + raise wrap_oserror(space, e) + else: + return space.wrap(res) + @unwrap_spec(fd=c_int) def close(space, fd): """Close a file descriptor (for low level IO).""" 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 @@ -833,6 +833,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, os.SEEK_SET) + 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, os.SEEK_SET) + 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 @@ -485,6 +485,31 @@ def sync(): c_sync() +c_pread = external('pread', + [rffi.INT, rffi.VOIDP, rffi.SIZE_T , rffi.LONGLONG], rffi.SSIZE_T, + save_err=rffi.RFFI_SAVE_ERRNO) +c_pwrite = external('pwrite', + [rffi.INT, rffi.VOIDP, rffi.SIZE_T, rffi.LONGLONG], rffi.SSIZE_T, + save_err=rffi.RFFI_SAVE_ERRNO) + +@replace_os_function('pread') +@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))) + +@replace_os_function('pwrite') +@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_chdir = external('chdir', [rffi.CCHARP], rffi.INT, _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit