Author: Joannah Nanjekye <nanjekyejoan...@gmail.com> Branch: superjumbo Changeset: r90914:45f6af71a2e5 Date: 2017-03-27 15:06 +0300 http://bitbucket.org/pypy/pypy/changeset/45f6af71a2e5/
Log: 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) +@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) + +@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') @@ -450,6 +456,12 @@ validate_fd(fd) handle_posix_error('close', c_close(fd)) +def write(fd, data): + count = len(data) + validate_fd(fd) + with rffi.scoped_nonmovingbuffer(data) as buf: + return handle_posix_error('write', c_write(fd, buf, count)) + 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 +502,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,39 @@ finally: os.close(fd) py.test.raises(OSError, rposix.pwrite, fd, b'ea', 1) + +@rposix_requires('posix_fadvise') +def posix_fadvise(): + fname = str(udir.join('test_os_posix_fadvise')) + localdir = os.getcwd() + os.mkdir(self.path2 + 'test_os_posix_fadvise') + 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_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_FADV_DONTNEED) == 0 + finally: + os.close(fd) + finally: + os.chdir(localdir) + py.test.raises(OSError, rposix.posix_fadvise, fd, 0, 0, rPOSIX_FADV_DONTNEED) + +@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit