Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: 
Changeset: r83689:379d221b82b9
Date: 2016-04-15 17:11 +0100
http://bitbucket.org/pypy/pypy/changeset/379d221b82b9/

Log:    Merged in rposix-for-3 (pull request #427)

        Rposix for 3

diff --git a/rpython/rlib/rposix_stat.py b/rpython/rlib/rposix_stat.py
--- a/rpython/rlib/rposix_stat.py
+++ b/rpython/rlib/rposix_stat.py
@@ -23,6 +23,7 @@
 from rpython.rlib.rarithmetic import intmask
 from rpython.rlib.rposix import (
     replace_os_function, handle_posix_error, _as_bytes0)
+from rpython.rlib import rposix
 
 _WIN32 = sys.platform.startswith('win')
 _LINUX = sys.platform.startswith('linux')
@@ -36,13 +37,12 @@
 #   sub-second timestamps.
 # - TIMESPEC is defined when the "struct stat" contains st_atim field.
 
-if sys.platform.startswith('linux') or sys.platform.startswith('openbsd'):
-    TIMESPEC = platform.Struct('struct timespec',
-                               [('tv_sec', rffi.TIME_T),
-                                ('tv_nsec', rffi.LONG)])
-else:
+try:
+    from rpython.rlib.rposix import TIMESPEC
+except ImportError:
     TIMESPEC = None
 
+
 # all possible fields - some of them are not available on all platforms
 ALL_STAT_FIELDS = [
     ("st_mode",      lltype.Signed),
@@ -300,13 +300,6 @@
     includes=INCLUDES
 )
 
-if TIMESPEC is not None:
-    class CConfig_for_timespec:
-        _compilation_info_ = compilation_info
-        TIMESPEC = TIMESPEC
-    TIMESPEC = lltype.Ptr(
-        platform.configure(CConfig_for_timespec)['TIMESPEC'])
-
 
 def posix_declaration(try_to_add=None):
     global STAT_STRUCT, STATVFS_STRUCT
@@ -322,7 +315,7 @@
                 if _name == originalname:
                     # replace the 'st_atime' field of type rffi.DOUBLE
                     # with a field 'st_atim' of type 'struct timespec'
-                    lst[i] = (timespecname, TIMESPEC.TO)
+                    lst[i] = (timespecname, TIMESPEC)
                     break
 
         _expand(LL_STAT_FIELDS, 'st_atime', 'st_atim')
@@ -512,6 +505,23 @@
         path = traits.as_str0(path)
         return win32_xstat(traits, path, traverse=False)
 
+if rposix.HAVE_FSTATAT:
+    from rpython.rlib.rposix import AT_FDCWD, AT_SYMLINK_NOFOLLOW
+    c_fstatat = rffi.llexternal('fstatat',
+        [rffi.INT, rffi.CCHARP, STAT_STRUCT, rffi.INT], rffi.INT,
+        compilation_info=compilation_info,
+        save_err=rffi.RFFI_SAVE_ERRNO, macro=True)
+
+    def fstatat(pathname, dir_fd=AT_FDCWD, follow_symlinks=True):
+        if follow_symlinks:
+            flags = 0
+        else:
+            flags = AT_SYMLINK_NOFOLLOW
+        with lltype.scoped_alloc(STAT_STRUCT.TO) as stresult:
+            error = c_fstatat(dir_fd, pathname, stresult, flags)
+            handle_posix_error('fstatat', error)
+            return build_stat_result(stresult)
+
 @replace_os_function('fstatvfs')
 def fstatvfs(fd):
     with lltype.scoped_alloc(STATVFS_STRUCT.TO) as stresult:
diff --git a/rpython/rlib/test/test_rposix_stat.py 
b/rpython/rlib/test/test_rposix_stat.py
--- a/rpython/rlib/test/test_rposix_stat.py
+++ b/rpython/rlib/test/test_rposix_stat.py
@@ -56,3 +56,13 @@
         except OSError, e:
             py.test.skip("the underlying os.fstatvfs() failed: %s" % e)
         rposix_stat.fstatvfs(0)
+
+@py.test.mark.skipif("not hasattr(rposix_stat, 'fstatat')")
+def test_fstatat(tmpdir):
+    tmpdir.join('file').write('text')
+    dirfd = os.open(str(tmpdir), os.O_RDONLY)
+    try:
+        result = rposix_stat.fstatat('file', dir_fd=dirfd, 
follow_symlinks=False)
+    finally:
+        os.close(dirfd)
+    assert result.st_atime == tmpdir.join('file').atime()
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to