[pypy-commit] pypy py3.5-xattr: Add rposix.(f)listxattr
rlamy
pypy.commits at gmail.com
Tue Dec 19 11:50:33 EST 2017
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.5-xattr
Changeset: r93495:05c458bd2a65
Date: 2017-12-19 16:49 +0000
http://bitbucket.org/pypy/pypy/changeset/05c458bd2a65/
Log: Add rposix.(f)listxattr
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -2603,29 +2603,41 @@
save_err=rffi.RFFI_SAVE_ERRNO)
c_fsetxattr = external('fsetxattr',
[rffi.INT, rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T, rffi.INT],
- rffi.SSIZE_T,
+ rffi.INT,
compilation_info=CConfig._compilation_info_,
save_err=rffi.RFFI_SAVE_ERRNO)
c_setxattr = external('setxattr',
[rffi.CCHARP, rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T, rffi.INT],
- rffi.SSIZE_T,
+ rffi.INT,
compilation_info=CConfig._compilation_info_,
save_err=rffi.RFFI_SAVE_ERRNO)
c_lsetxattr = external('lsetxattr',
[rffi.CCHARP, rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T, rffi.INT],
- rffi.SSIZE_T,
+ rffi.INT,
compilation_info=CConfig._compilation_info_,
save_err=rffi.RFFI_SAVE_ERRNO)
c_fremovexattr = external('fremovexattr',
- [rffi.INT, rffi.CCHARP], rffi.SSIZE_T,
+ [rffi.INT, rffi.CCHARP], rffi.INT,
compilation_info=CConfig._compilation_info_,
save_err=rffi.RFFI_SAVE_ERRNO)
c_removexattr = external('removexattr',
- [rffi.CCHARP, rffi.CCHARP], rffi.SSIZE_T,
+ [rffi.CCHARP, rffi.CCHARP], rffi.INT,
compilation_info=CConfig._compilation_info_,
save_err=rffi.RFFI_SAVE_ERRNO)
c_lremovexattr = external('lremovexattr',
- [rffi.CCHARP, rffi.CCHARP], rffi.SSIZE_T,
+ [rffi.CCHARP, rffi.CCHARP], rffi.INT,
+ compilation_info=CConfig._compilation_info_,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ c_flistxattr = external('flistxattr',
+ [rffi.INT, rffi.CCHARP, rffi.SIZE_T], rffi.SSIZE_T,
+ compilation_info=CConfig._compilation_info_,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ c_listxattr = external('listxattr',
+ [rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T], rffi.SSIZE_T,
+ compilation_info=CConfig._compilation_info_,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ c_llistxattr = external('llistxattr',
+ [rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T], rffi.SSIZE_T,
compilation_info=CConfig._compilation_info_,
save_err=rffi.RFFI_SAVE_ERRNO)
buf_sizes = [256, XATTR_SIZE_MAX]
@@ -2683,3 +2695,39 @@
return handle_posix_error('removexattr', c_removexattr(path, name))
else:
return handle_posix_error('lremovexattr', c_lremovexattr(path, name))
+
+ def _unpack_attrs(attr_string):
+ result = attr_string.split('\0')
+ del result[-1]
+ return result
+
+ def flistxattr(fd):
+ for size in buf_sizes:
+ with rffi.scoped_alloc_buffer(size) as buf:
+ res = c_flistxattr(fd, buf.raw, size)
+ if res < 0:
+ err = get_saved_errno()
+ if err != errno.ERANGE:
+ raise OSError(err, 'flistxattr failed')
+ else:
+ return _unpack_attrs(buf.str(res))
+ else:
+ raise OSError(errno.ERANGE, 'flistxattr failed')
+
+ def listxattr(path, follow_symlinks=True):
+ for size in buf_sizes:
+ with rffi.scoped_alloc_buffer(size) as buf:
+ if follow_symlinks:
+ res = c_listxattr(path, buf.raw, size)
+ else:
+ res = c_llistxattr(path, buf.raw, size)
+ if res < 0:
+ err = get_saved_errno()
+ if err != errno.ERANGE:
+ c_name = 'listxattr' if follow_symlinks else 'llistxattr'
+ raise OSError(err, c_name + 'failed')
+ else:
+ return _unpack_attrs(buf.str(res))
+ else:
+ c_name = 'listxattr' if follow_symlinks else 'llistxattr'
+ raise OSError(errno.ERANGE, c_name + 'failed')
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
@@ -853,27 +853,38 @@
assume(follow_symlinks or not use_fd)
name = 'user.' + name.encode('utf-8')
fname = str(udir.join('xattr_test.txt'))
+ try:
+ os.unlink(fname)
+ except OSError:
+ pass
with open(fname, 'wb'):
pass
if use_fd:
file_id = os.open(fname, os.O_CREAT, 0777)
read, write, delete = rposix.fgetxattr, rposix.fsetxattr, rposix.fremovexattr
+ all_names = rposix.flistxattr
else:
file_id = fname
if follow_symlinks:
read, write, delete = rposix.getxattr, rposix.setxattr, rposix.removexattr
+ all_names = rposix.listxattr
else:
read = lambda *args, **kwargs: rposix.getxattr(*args, follow_symlinks=False, **kwargs)
write = lambda *args, **kwargs: rposix.setxattr(*args, follow_symlinks=False, **kwargs)
delete = lambda *args, **kwargs: rposix.removexattr(*args, follow_symlinks=False, **kwargs)
+ all_names = lambda *args, **kwargs: rposix.listxattr(*args, follow_symlinks=False, **kwargs)
try:
+ init_names = all_names(file_id)
with pytest.raises(OSError):
read(file_id, name)
write(file_id, name, value)
assert read(file_id, name) == value
+ assert set(all_names(file_id)) == set(init_names + [name])
+ assert '' not in all_names(file_id)
delete(file_id, name)
with pytest.raises(OSError):
read(file_id, name)
+ assert set(all_names(file_id)) == set(init_names)
finally:
if use_fd:
os.close(file_id)
More information about the pypy-commit
mailing list