diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 50f6886c89df9e..8f7b9ac15a0d22 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3411,133 +3411,248 @@ features: Information about a file returned by :func:`os.statx`. - :class:`!statx_result` has all the attributes that :class:`~stat_result` has - on Linux, making it :term:`duck-typing` compatible, but - :class:`!statx_result` is not a subclass of :class:`~stat_result` and cannot - be used as a tuple. - - :class:`!statx_result` has the following additional attributes: + :class:`!statx_result` has the following attributes: .. attribute:: stx_mask Bitmask of :const:`STATX_* ` constants specifying the information retrieved, which may differ from what was requested. - .. attribute:: stx_attributes_mask + .. attribute:: stx_atime - Bitmask of :const:`STATX_ATTR_* ` constants - specifying the attributes bits supported for this file. + Time of most recent access expressed in seconds. + + Equal to ``None`` if :data:`STATX_ATIME` is missing from + :attr:`~statx_result.stx_mask`. + + .. attribute:: stx_atime_ns + + Time of most recent access expressed in nanoseconds as an integer. + + Equal to ``None`` if :data:`STATX_ATIME` is missing from + :attr:`~statx_result.stx_mask`. + + .. attribute:: stx_atomic_write_segments_max + + Maximum iovecs for direct I/O with torn-write protection. + + Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from + :attr:`~statx_result.stx_mask`. + + .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel + userspace API headers >= 6.11. + + .. attribute:: stx_atomic_write_unit_min + + Minimum size for direct I/O with torn-write protection. + + Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from + :attr:`~statx_result.stx_mask`. + + .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel + userspace API headers >= 6.11. + + .. attribute:: stx_atomic_write_unit_max + + Maximum size for direct I/O with torn-write protection. + + Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from + :attr:`~statx_result.stx_mask`. + + .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel + userspace API headers >= 6.11. + + .. attribute:: stx_atomic_write_unit_max_opt + + Maximum optimized size for direct I/O with torn-write protection. + + Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from + :attr:`~statx_result.stx_mask`. + + .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel + userspace API headers >= 6.16. .. attribute:: stx_attributes Bitmask of :const:`STATX_ATTR_* ` constants specifying the attributes of this file. - .. attribute:: stx_dev_major + .. attribute:: stx_attributes_mask - Major number of the device on which this file resides. + A mask indicating which bits in :attr:`stx_attributes` are supported by + the VFS and the filesystem. - .. attribute:: stx_dev_minor + .. attribute:: stx_blksize - Minor number of the device on which this file resides. + "Preferred" blocksize for efficient file system I/O. Writing to a file in + smaller chunks may cause an inefficient read-modify-rewrite. - .. attribute:: stx_rdev_major + .. attribute:: stx_blocks - Major number of the device this file represents. + Number of 512-byte blocks allocated for file. + This may be smaller than :attr:`stx_size`/512 when the file has holes. - .. attribute:: stx_rdev_minor + Equal to ``None`` if :data:`STATX_BLOCKS` is missing from + :attr:`~statx_result.stx_mask`. - Minor number of the device this file represents. + .. attribute:: stx_btime - .. attribute:: stx_mnt_id + Time of file creation expressed in seconds. - Mount identifier. + Equal to ``None`` if :data:`STATX_BTIME` is missing from + :attr:`~statx_result.stx_mask`. - Equal to ``None`` if :data:`STATX_MNT_ID` is missing from - :attr:`~os.statx_result.stx_mask`. + .. attribute:: stx_btime_ns - .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel - userspace API headers >= 5.8. + Time of file creation expressed in nanoseconds as an integer. - .. attribute:: stx_dio_mem_align + Equal to ``None`` if :data:`STATX_BTIME` is missing from + :attr:`~statx_result.stx_mask`. - Direct I/O memory buffer alignment requirement. + .. attribute:: stx_ctime - Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from - :attr:`~os.statx_result.stx_mask`. + Time of most recent metadata change expressed in seconds. - .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel - userspace API headers >= 6.1. + Equal to ``None`` if :data:`STATX_CTIME` is missing from + :attr:`~statx_result.stx_mask`. + + .. attribute:: stx_ctime_ns + + Time of most recent metadata change expressed in nanoseconds as an + integer. + + Equal to ``None`` if :data:`STATX_CTIME` is missing from + :attr:`~statx_result.stx_mask`. + + .. attribute:: stx_dev + + Identifier of the device on which this file resides. + + .. attribute:: stx_dev_major + + Major number of the device on which this file resides. + + .. attribute:: stx_dev_minor + + Minor number of the device on which this file resides. .. attribute:: stx_dio_offset_align Direct I/O file offset alignment requirement. Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from - :attr:`~os.statx_result.stx_mask`. + :attr:`~statx_result.stx_mask`. .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel userspace API headers >= 6.1. - .. attribute:: stx_subvol + .. attribute:: stx_dio_mem_align - Subvolume identifier. + Direct I/O memory buffer alignment requirement. - Equal to ``None`` if :data:`STATX_SUBVOL` is missing from - :attr:`~os.statx_result.stx_mask`. + Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from + :attr:`~statx_result.stx_mask`. .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel - userspace API headers >= 6.10. + userspace API headers >= 6.1. - .. attribute:: stx_atomic_write_unit_min + .. attribute:: stx_dio_read_offset_align - Minimum size for direct I/O with torn-write protection. + Direct I/O file offset alignment requirement for reads. - Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from - :attr:`~os.statx_result.stx_mask`. + Equal to ``None`` if :data:`STATX_DIO_READ_ALIGN` is missing from + :attr:`~statx_result.stx_mask`. .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel - userspace API headers >= 6.11. + userspace API headers >= 6.14. - .. attribute:: stx_atomic_write_unit_max + .. attribute:: stx_gid - Maximum size for direct I/O with torn-write protection. + Group identifier of the file owner. - Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from - :attr:`~os.statx_result.stx_mask`. + Equal to ``None`` if :data:`STATX_GID` is missing from + :attr:`~statx_result.stx_mask`. - .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel - userspace API headers >= 6.11. + .. attribute:: stx_ino - .. attribute:: stx_atomic_write_unit_max_opt + Inode number. - Maximum optimized size for direct I/O with torn-write protection. + Equal to ``None`` if :data:`STATX_INO` is missing from + :attr:`~statx_result.stx_mask`. - Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from - :attr:`~os.statx_result.stx_mask`. + .. attribute:: stx_mnt_id + + Mount identifier. + + Equal to ``None`` if :data:`STATX_MNT_ID` is missing from + :attr:`~statx_result.stx_mask`. .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel - userspace API headers >= 6.16. + userspace API headers >= 5.8. - .. attribute:: stx_atomic_write_segments_max + .. attribute:: stx_mode - Maximum iovecs for direct I/O with torn-write protection. + File mode: file type and file mode bits (permissions). - Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from - :attr:`~os.statx_result.stx_mask`. + .. attribute:: stx_mtime - .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel - userspace API headers >= 6.11. + Time of most recent content modification expressed in seconds. - .. attribute:: stx_dio_read_offset_align + Equal to ``None`` if :data:`STATX_MTIME` is missing from + :attr:`~statx_result.stx_mask`. - Direct I/O file offset alignment requirement for reads. + .. attribute:: stx_mtime_ns - Equal to ``None`` if :data:`STATX_DIO_READ_ALIGN` is missing from - :attr:`~os.statx_result.stx_mask`. + Time of most recent content modification expressed in nanoseconds as an + integer. + + Equal to ``None`` if :data:`STATX_MTIME` is missing from + :attr:`~statx_result.stx_mask`. + + .. attribute:: stx_nlink + + Number of hard links. + + Equal to ``None`` if :data:`STATX_NLINK` is missing from + :attr:`~statx_result.stx_mask`. + + .. attribute:: stx_rdev + + Type of device if an inode device. + + .. attribute:: stx_rdev_major + + Major number of the device this file represents. + + .. attribute:: stx_rdev_minor + + Minor number of the device this file represents. + + .. attribute:: stx_size + + Size of the file in bytes, if it is a regular file or a symbolic link. + The size of a symbolic link is the length of the pathname it contains, + without a terminating null byte. + + Equal to ``None`` if :data:`STATX_SIZE` is missing from + :attr:`~statx_result.stx_mask`. + + .. attribute:: stx_subvol + + Subvolume identifier. + + Equal to ``None`` if :data:`STATX_SUBVOL` is missing from + :attr:`~statx_result.stx_mask`. .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel - userspace API headers >= 6.14. + userspace API headers >= 6.10. + + .. attribute:: stx_uid + + User identifier of the file owner. + + Equal to ``None`` if :data:`STATX_UID` is missing from + :attr:`~statx_result.stx_mask`. .. seealso:: The :manpage:`statx(2)` man page. diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 8503a4c7f973fc..22e9cfde06f877 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -438,7 +438,7 @@ os * Add :func:`os.statx` on Linux kernel versions 4.11 and later with glibc versions 2.28 and later. - (Contributed by Jeffrey Bosboom in :gh:`83714`.) + (Contributed by Jeffrey Bosboom and Victor Stinner in :gh:`83714`.) os.path diff --git a/Lib/test/test_os/test_os.py b/Lib/test/test_os/test_os.py index 67599537736c8f..9a40c5c2a1f1f3 100644 --- a/Lib/test/test_os/test_os.py +++ b/Lib/test/test_os/test_os.py @@ -750,8 +750,8 @@ def check_statx_attributes(self, filename): result = os.statx(filename, maximal_mask) basic_result = os.stat(filename) - time_attributes = ('st_atime', 'st_mtime', 'st_ctime', 'st_birthtime') - # gh-83714: st_birthtime can be None on tmpfs even if STATX_BTIME mask + time_attributes = ('stx_atime', 'stx_btime', 'stx_ctime', 'stx_mtime') + # gh-83714: stx_btime can be None on tmpfs even if STATX_BTIME mask # is used time_attributes = [name for name in time_attributes if getattr(result, name) is not None] @@ -759,43 +759,44 @@ def check_statx_attributes(self, filename): # Check that valid attributes match os.stat. requirements = ( - ('st_mode', os.STATX_TYPE | os.STATX_MODE), - ('st_nlink', os.STATX_NLINK), - ('st_uid', os.STATX_UID), - ('st_gid', os.STATX_GID), - ('st_atime', os.STATX_ATIME), - ('st_atime_ns', os.STATX_ATIME), - ('st_mtime', os.STATX_MTIME), - ('st_mtime_ns', os.STATX_MTIME), - ('st_ctime', os.STATX_CTIME), - ('st_ctime_ns', os.STATX_CTIME), - ('st_ino', os.STATX_INO), - ('st_size', os.STATX_SIZE), - ('st_blocks', os.STATX_BLOCKS), - ('st_birthtime', os.STATX_BTIME), - ('st_birthtime_ns', os.STATX_BTIME), + ('stx_mode', os.STATX_TYPE | os.STATX_MODE), + ('stx_nlink', os.STATX_NLINK), + ('stx_uid', os.STATX_UID), + ('stx_gid', os.STATX_GID), + ('stx_atime', os.STATX_ATIME), + ('stx_atime_ns', os.STATX_ATIME), + ('stx_mtime', os.STATX_MTIME), + ('stx_mtime_ns', os.STATX_MTIME), + ('stx_ctime', os.STATX_CTIME), + ('stx_ctime_ns', os.STATX_CTIME), + ('stx_ino', os.STATX_INO), + ('stx_size', os.STATX_SIZE), + ('stx_blocks', os.STATX_BLOCKS), + ('stx_birthtime', os.STATX_BTIME), + ('stx_birthtime_ns', os.STATX_BTIME), # unconditionally valid members - ('st_blksize', 0), - ('st_rdev', 0), - ('st_dev', 0), + ('stx_blksize', 0), + ('stx_rdev', 0), + ('stx_dev', 0), ) for name, bits in requirements: - if result.stx_mask & bits == bits and hasattr(basic_result, name): + st_name = "st_" + name[4:] + if result.stx_mask & bits == bits and hasattr(basic_result, st_name): x = getattr(result, name) - b = getattr(basic_result, name) + b = getattr(basic_result, st_name) self.assertEqual(type(x), type(b)) if isinstance(x, float): self.assertAlmostEqual(x, b, msg=name) else: self.assertEqual(x, b, msg=name) - self.assertEqual(result.stx_rdev_major, os.major(result.st_rdev)) - self.assertEqual(result.stx_rdev_minor, os.minor(result.st_rdev)) - self.assertEqual(result.stx_dev_major, os.major(result.st_dev)) - self.assertEqual(result.stx_dev_minor, os.minor(result.st_dev)) + self.assertEqual(result.stx_rdev_major, os.major(result.stx_rdev)) + self.assertEqual(result.stx_rdev_minor, os.minor(result.stx_rdev)) + self.assertEqual(result.stx_dev_major, os.major(result.stx_dev)) + self.assertEqual(result.stx_dev_minor, os.minor(result.stx_dev)) members = [name for name in dir(result) - if name.startswith('st_') or name.startswith('stx_')] + if name.startswith('stx_')] for name in members: try: setattr(result, name, 1) diff --git a/Lib/test/test_os/test_posix.py b/Lib/test/test_os/test_posix.py index 905f0201253951..de24719a1ca455 100644 --- a/Lib/test/test_os/test_posix.py +++ b/Lib/test/test_os/test_posix.py @@ -1672,17 +1672,22 @@ def test_chown_dir_fd(self): with self.prepare_file() as (dir_fd, name, fullname): posix.chown(name, os.getuid(), os.getgid(), dir_fd=dir_fd) - def check_statlike_dir_fd(self, func): + def check_statlike_dir_fd(self, func, prefix): with self.prepare() as (dir_fd, name, fullname): with open(fullname, 'w') as outfile: outfile.write("testline\n") self.addCleanup(posix.unlink, fullname) + def get(result, attr): + return getattr(result, prefix + attr) + s1 = func(fullname) s2 = func(name, dir_fd=dir_fd) - self.assertEqual((s1.st_dev, s1.st_ino), (s2.st_dev, s2.st_ino)) + self.assertEqual((get(s1, "dev"), get(s1, "ino")), + (get(s2, "dev"), get(s2, "ino"))) s2 = func(fullname, dir_fd=None) - self.assertEqual((s1.st_dev, s1.st_ino), (s2.st_dev, s2.st_ino)) + self.assertEqual((get(s1, "dev"), get(s1, "ino")), + (get(s2, "dev"), get(s2, "ino"))) self.assertRaisesRegex(TypeError, 'should be integer or None, not', func, name, dir_fd=posix.getcwd()) @@ -1700,13 +1705,13 @@ def check_statlike_dir_fd(self, func): @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()") def test_stat_dir_fd(self): - self.check_statlike_dir_fd(posix.stat) + self.check_statlike_dir_fd(posix.stat, prefix="st_") @unittest.skipUnless(hasattr(posix, 'statx'), "test needs os.statx()") def test_statx_dir_fd(self): def func(path, **kwargs): return posix.statx(path, os.STATX_INO, **kwargs) - self.check_statlike_dir_fd(func) + self.check_statlike_dir_fd(func, prefix="stx_") @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()") def test_utime_dir_fd(self): diff --git a/Misc/NEWS.d/next/Library/2025-09-18-21-25-41.gh-issue-83714.TQjDWZ.rst b/Misc/NEWS.d/next/Library/2025-09-18-21-25-41.gh-issue-83714.TQjDWZ.rst index 7229a361147ee2..3653eb9a114a35 100644 --- a/Misc/NEWS.d/next/Library/2025-09-18-21-25-41.gh-issue-83714.TQjDWZ.rst +++ b/Misc/NEWS.d/next/Library/2025-09-18-21-25-41.gh-issue-83714.TQjDWZ.rst @@ -1,2 +1,2 @@ -Implement :func:`os.statx` on Linux kernel versions 4.11 and later with -glibc versions 2.28 and later. Contributed by Jeffrey Bosboom. +Implement :func:`os.statx` on Linux kernel versions 4.11 and later with glibc +versions 2.28 and later. Contributed by Jeffrey Bosboom and Victor Stinner. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d0b9eed8c8208b..433acdcb538f11 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -3330,17 +3330,17 @@ typedef struct { static PyMemberDef pystatx_result_members[] = { MM(stx_mask, Py_T_UINT, mask, "member validity mask"), - MM(st_blksize, Py_T_UINT, blksize, "blocksize for filesystem I/O"), + MM(stx_blksize, Py_T_UINT, blksize, "blocksize for filesystem I/O"), MM(stx_attributes, Py_T_ULONGLONG, attributes, "Linux inode attribute bits"), - MM(st_mode, Py_T_USHORT, mode, "protection bits"), + MM(stx_mode, Py_T_USHORT, mode, "protection bits"), MM(stx_attributes_mask, Py_T_ULONGLONG, attributes_mask, "Mask of supported bits in stx_attributes"), MM(stx_rdev_major, Py_T_UINT, rdev_major, "represented device major number"), MM(stx_rdev_minor, Py_T_UINT, rdev_minor, "represented device minor number"), - MX(st_rdev, Py_T_ULONGLONG, rdev, "device type (if inode device)"), + MX(stx_rdev, Py_T_ULONGLONG, rdev, "device type (if inode device)"), MM(stx_dev_major, Py_T_UINT, dev_major, "containing device major number"), MM(stx_dev_minor, Py_T_UINT, dev_minor, "containing device minor number"), - MX(st_dev, Py_T_ULONGLONG, dev, "device"), + MX(stx_dev, Py_T_ULONGLONG, dev, "device"), {NULL}, }; @@ -3349,7 +3349,7 @@ static PyMemberDef pystatx_result_members[] = { #undef M -#define STATX_GET_UINT(ATTR, MEMBER, MASK) \ +#define STATX_GET_UINT(ATTR, MASK) \ static PyObject* \ pystatx_result_get_##ATTR(PyObject *op, void *Py_UNUSED(context)) \ { \ @@ -3357,36 +3357,31 @@ static PyMemberDef pystatx_result_members[] = { if (!(self->stx.stx_mask & MASK)) { \ Py_RETURN_NONE; \ } \ - unsigned long value = self->stx.MEMBER; \ + unsigned long value = self->stx.ATTR; \ return PyLong_FromUnsignedLong(value); \ } -STATX_GET_UINT(st_uid, stx_uid, STATX_UID) -STATX_GET_UINT(st_gid, stx_gid, STATX_GID) -STATX_GET_UINT(st_nlink, stx_nlink, STATX_NLINK) +STATX_GET_UINT(stx_uid, STATX_UID) +STATX_GET_UINT(stx_gid, STATX_GID) +STATX_GET_UINT(stx_nlink, STATX_NLINK) #ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN -STATX_GET_UINT(stx_dio_mem_align, stx_dio_mem_align, STATX_DIOALIGN) -STATX_GET_UINT(stx_dio_offset_align, stx_dio_offset_align, STATX_DIOALIGN) +STATX_GET_UINT(stx_dio_mem_align, STATX_DIOALIGN) +STATX_GET_UINT(stx_dio_offset_align, STATX_DIOALIGN) #endif #ifdef HAVE_STRUCT_STATX_STX_DIO_READ_OFFSET_ALIGN -STATX_GET_UINT(stx_dio_read_offset_align, stx_dio_read_offset_align, - STATX_DIO_READ_ALIGN) +STATX_GET_UINT(stx_dio_read_offset_align, STATX_DIO_READ_ALIGN) #endif #ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN -STATX_GET_UINT(stx_atomic_write_unit_min, stx_atomic_write_unit_min, - STATX_WRITE_ATOMIC) -STATX_GET_UINT(stx_atomic_write_unit_max, stx_atomic_write_unit_max, - STATX_WRITE_ATOMIC) -STATX_GET_UINT(stx_atomic_write_segments_max, stx_atomic_write_segments_max, - STATX_WRITE_ATOMIC) +STATX_GET_UINT(stx_atomic_write_unit_min, STATX_WRITE_ATOMIC) +STATX_GET_UINT(stx_atomic_write_unit_max, STATX_WRITE_ATOMIC) +STATX_GET_UINT(stx_atomic_write_segments_max, STATX_WRITE_ATOMIC) #endif #ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT -STATX_GET_UINT(stx_atomic_write_unit_max_opt, stx_atomic_write_unit_max_opt, - STATX_WRITE_ATOMIC) +STATX_GET_UINT(stx_atomic_write_unit_max_opt, STATX_WRITE_ATOMIC) #endif -#define STATX_GET_ULONGLONG(ATTR, MEMBER, MASK) \ +#define STATX_GET_ULONGLONG(ATTR, MASK) \ static PyObject* \ pystatx_result_get_##ATTR(PyObject *op, void *Py_UNUSED(context)) \ { \ @@ -3394,18 +3389,18 @@ STATX_GET_UINT(stx_atomic_write_unit_max_opt, stx_atomic_write_unit_max_opt, if (!(self->stx.stx_mask & MASK)) { \ Py_RETURN_NONE; \ } \ - unsigned long long value = self->stx.MEMBER; \ + unsigned long long value = self->stx.ATTR; \ return PyLong_FromUnsignedLongLong(value); \ } -STATX_GET_ULONGLONG(st_blocks, stx_blocks, STATX_BLOCKS) -STATX_GET_ULONGLONG(st_ino, stx_ino, STATX_INO) -STATX_GET_ULONGLONG(st_size, stx_size, STATX_SIZE) +STATX_GET_ULONGLONG(stx_blocks, STATX_BLOCKS) +STATX_GET_ULONGLONG(stx_ino, STATX_INO) +STATX_GET_ULONGLONG(stx_size, STATX_SIZE) #ifdef HAVE_STRUCT_STATX_STX_MNT_ID -STATX_GET_ULONGLONG(stx_mnt_id, stx_mnt_id, STATX_MNT_ID) +STATX_GET_ULONGLONG(stx_mnt_id, STATX_MNT_ID) #endif #ifdef HAVE_STRUCT_STATX_STX_SUBVOL -STATX_GET_ULONGLONG(stx_subvol, stx_subvol, STATX_SUBVOL) +STATX_GET_ULONGLONG(stx_subvol, STATX_SUBVOL) #endif @@ -3421,10 +3416,10 @@ STATX_GET_ULONGLONG(stx_subvol, stx_subvol, STATX_SUBVOL) return PyFloat_FromDouble(sec); \ } -STATX_GET_DOUBLE(st_atime, atime_sec, STATX_ATIME) -STATX_GET_DOUBLE(st_birthtime, btime_sec, STATX_BTIME) -STATX_GET_DOUBLE(st_ctime, ctime_sec, STATX_CTIME) -STATX_GET_DOUBLE(st_mtime, mtime_sec, STATX_MTIME) +STATX_GET_DOUBLE(stx_atime, atime_sec, STATX_ATIME) +STATX_GET_DOUBLE(stx_btime, btime_sec, STATX_BTIME) +STATX_GET_DOUBLE(stx_ctime, ctime_sec, STATX_CTIME) +STATX_GET_DOUBLE(stx_mtime, mtime_sec, STATX_MTIME) #define STATX_GET_NSEC(ATTR, MEMBER, MASK) \ static PyObject* \ @@ -3440,29 +3435,29 @@ STATX_GET_DOUBLE(st_mtime, mtime_sec, STATX_MTIME) return stat_nanosecond_timestamp(state, ts->tv_sec, ts->tv_nsec); \ } -STATX_GET_NSEC(st_atime_ns, stx_atime, STATX_ATIME) -STATX_GET_NSEC(st_birthtime_ns, stx_btime, STATX_BTIME) -STATX_GET_NSEC(st_ctime_ns, stx_ctime, STATX_CTIME) -STATX_GET_NSEC(st_mtime_ns, stx_mtime, STATX_MTIME) +STATX_GET_NSEC(stx_atime_ns, stx_atime, STATX_ATIME) +STATX_GET_NSEC(stx_btime_ns, stx_btime, STATX_BTIME) +STATX_GET_NSEC(stx_ctime_ns, stx_ctime, STATX_CTIME) +STATX_GET_NSEC(stx_mtime_ns, stx_mtime, STATX_MTIME) #define G(attr, doc) \ {#attr, pystatx_result_get_##attr, NULL, PyDoc_STR(doc), NULL} static PyGetSetDef pystatx_result_getset[] = { - G(st_nlink, "number of hard links"), - G(st_uid, "user ID of owner"), - G(st_gid, "group ID of owner"), - G(st_ino, "inode"), - G(st_size, "total size, in bytes"), - G(st_blocks, "number of blocks allocated"), - G(st_atime, "time of last access"), - G(st_atime_ns, "time of last access in nanoseconds"), - G(st_birthtime, "time of creation"), - G(st_birthtime_ns, "time of creation in nanoseconds"), - G(st_ctime, "time of last change"), - G(st_ctime_ns, "time of last change in nanoseconds"), - G(st_mtime, "time of last modification"), - G(st_mtime_ns, "time of last modification in nanoseconds"), + G(stx_nlink, "number of hard links"), + G(stx_uid, "user ID of owner"), + G(stx_gid, "group ID of owner"), + G(stx_ino, "inode"), + G(stx_size, "total size, in bytes"), + G(stx_blocks, "number of blocks allocated"), + G(stx_atime, "time of last access"), + G(stx_atime_ns, "time of last access in nanoseconds"), + G(stx_btime, "time of creation"), + G(stx_btime_ns, "time of creation in nanoseconds"), + G(stx_ctime, "time of last change"), + G(stx_ctime_ns, "time of last change in nanoseconds"), + G(stx_mtime, "time of last modification"), + G(stx_mtime_ns, "time of last modification in nanoseconds"), #ifdef HAVE_STRUCT_STATX_STX_MNT_ID G(stx_mnt_id, "mount ID"), #endif