Author: Ronan Lamy <[email protected]>
Branch: follow_symlinks
Changeset: r83573:3facdbc716c2
Date: 2016-04-07 15:56 +0100
http://bitbucket.org/pypy/pypy/changeset/3facdbc716c2/
Log: hg merge 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)
+
[email protected]("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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit