diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 3f0b91af4d0a86f..823ca90bc55c189 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3544,10 +3544,14 @@ features: .. seealso:: The :manpage:`statx(2)` man page. - .. availability:: Linux >= 4.11 with glibc >= 2.28. + .. availability:: Linux >= 4.11. .. versionadded:: 3.15 + .. versionchanged:: 3.16 + The function is also available when Python is built against a libc + that lacks ``statx()``, such as glibc older than 2.28. + .. class:: statx_result @@ -3576,7 +3580,7 @@ features: 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 + .. availability:: Linux >= 4.11 and build-time kernel userspace API headers >= 6.11. .. attribute:: stx_atomic_write_unit_max @@ -3586,7 +3590,7 @@ features: 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 + .. availability:: Linux >= 4.11 and build-time kernel userspace API headers >= 6.11. .. attribute:: stx_atomic_write_unit_max_opt @@ -3596,7 +3600,7 @@ features: 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 + .. availability:: Linux >= 4.11 and build-time kernel userspace API headers >= 6.16. .. attribute:: stx_atomic_write_unit_min @@ -3606,7 +3610,7 @@ features: 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 + .. availability:: Linux >= 4.11 and build-time kernel userspace API headers >= 6.11. .. attribute:: stx_attributes @@ -3680,7 +3684,7 @@ features: 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 + .. availability:: Linux >= 4.11 and build-time kernel userspace API headers >= 6.1. .. attribute:: stx_dio_offset_align @@ -3690,7 +3694,7 @@ features: 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 + .. availability:: Linux >= 4.11 and build-time kernel userspace API headers >= 6.1. .. attribute:: stx_dio_read_offset_align @@ -3700,7 +3704,7 @@ features: 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 + .. availability:: Linux >= 4.11 and build-time kernel userspace API headers >= 6.14. .. attribute:: stx_gid @@ -3729,7 +3733,7 @@ features: 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 + .. availability:: Linux >= 4.11 and build-time kernel userspace API headers >= 5.8. .. attribute:: stx_mode @@ -3789,7 +3793,7 @@ features: 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 + .. availability:: Linux >= 4.11 and build-time kernel userspace API headers >= 6.10. .. attribute:: stx_uid @@ -3801,7 +3805,7 @@ features: .. seealso:: The :manpage:`statx(2)` man page. - .. availability:: Linux >= 4.11 with glibc >= 2.28. + .. availability:: Linux >= 4.11. .. versionadded:: 3.15 @@ -3830,7 +3834,7 @@ features: flags may be available even when their corresponding members in :class:`statx_result` are not available. - .. availability:: Linux >= 4.11 with glibc >= 2.28. + .. availability:: Linux >= 4.11. .. versionadded:: 3.15 @@ -3840,7 +3844,7 @@ features: up-to-date information even when doing so is expensive (for example, requiring a round trip to the server for a file on a network filesystem). - .. availability:: Linux >= 4.11 with glibc >= 2.28. + .. availability:: Linux >= 4.11. .. versionadded:: 3.15 @@ -3849,7 +3853,7 @@ features: A flag for the :func:`os.statx` function. Requests that the kernel return cached information if possible. - .. availability:: Linux >= 4.11 with glibc >= 2.28. + .. availability:: Linux >= 4.11. .. versionadded:: 3.15 @@ -3861,7 +3865,7 @@ features: In the absence of the other two flags, the kernel will generally return information as fresh as :func:`os.stat` would return. - .. availability:: Linux >= 4.11 with glibc >= 2.28. + .. availability:: Linux >= 4.11. .. versionadded:: 3.15 diff --git a/Misc/NEWS.d/next/Library/2026-10-08-22-52-48.gh-issue-153400.4NsKKN.rst b/Misc/NEWS.d/next/Library/2026-10-08-22-52-48.gh-issue-153400.4NsKKN.rst new file mode 100644 index 000000000000000..3e6061dfcc5450e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-08-22-52-48.gh-issue-153400.4NsKKN.rst @@ -0,0 +1,2 @@ +On Linux, :func:`os.statx` falls back to the raw syscall when the libc Python is built against does not provide the +wrapper function. This makes it possible for this function to be available on interpreters built against a libc older than glibc 2.28. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 3c3e46e065f3ea7..c182374ed273578 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -188,7 +188,7 @@ os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw return return_value; } -#if defined(HAVE_STATX) +#if defined(_Py_HAVE_STATX) PyDoc_STRVAR(os_statx__doc__, "statx($module, /, path, mask, *, flags=0, dir_fd=None,\n" @@ -320,7 +320,7 @@ os_statx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw return return_value; } -#endif /* defined(HAVE_STATX) */ +#endif /* defined(_Py_HAVE_STATX) */ PyDoc_STRVAR(os_access__doc__, "access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n" @@ -13763,4 +13763,4 @@ os__emscripten_log(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py #ifndef OS__EMSCRIPTEN_LOG_METHODDEF #define OS__EMSCRIPTEN_LOG_METHODDEF #endif /* !defined(OS__EMSCRIPTEN_LOG_METHODDEF) */ -/*[clinic end generated code: output=8bf88a95035a0188 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1981d42f50f6a5fa input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 301afe1fa27be68..9e8a000e7bc0482 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -90,6 +90,9 @@ #ifdef HAVE_SYS_STAT_H # include #endif +#if defined(__linux__) && !defined(HAVE_STRUCT_STATX) && defined(HAVE_LINUX_STAT_H) +# include // struct statx on older libc versions +#endif #ifdef HAVE_SYS_WAIT_H # include // WNOHANG @@ -420,9 +423,31 @@ extern char *ctermid_r(char *); # define STRUCT_STAT struct stat #endif -#ifdef HAVE_STATX +#if defined(__linux__) && defined(__NR_statx) && \ + (defined(HAVE_STRUCT_STATX) || \ + (defined(HAVE_LINUX_STAT_H) && defined(STATX_BASIC_STATS))) +# define _Py_HAVE_STATX +#endif + +#if defined(_Py_HAVE_STATX) && defined(HAVE_STATX) /* until we can assume glibc 2.28 at runtime, we must weakly link */ # pragma weak statx +#endif + +#ifdef _Py_HAVE_STATX +/* These Linux UAPI flags may be missing from older libc headers. Including + linux/fcntl.h alongside fcntl.h would redefine libc structures. */ +# ifndef AT_NO_AUTOMOUNT +# define AT_NO_AUTOMOUNT 0x800 +# endif +# ifndef AT_EMPTY_PATH +# define AT_EMPTY_PATH 0x1000 +# endif +# ifndef AT_STATX_SYNC_AS_STAT +# define AT_STATX_SYNC_AS_STAT 0x0000 +# define AT_STATX_FORCE_SYNC 0x2000 +# define AT_STATX_DONT_SYNC 0x4000 +# endif static const unsigned int _Py_STATX_KNOWN = (STATX_BASIC_STATS | STATX_BTIME #ifdef STATX_MNT_ID | STATX_MNT_ID @@ -443,7 +468,7 @@ static const unsigned int _Py_STATX_KNOWN = (STATX_BASIC_STATS | STATX_BTIME | STATX_DIO_READ_ALIGN #endif ); -#endif /* HAVE_STATX */ +#endif /* _Py_HAVE_STATX */ #if !defined(EX_OK) && defined(EXIT_SUCCESS) @@ -1235,7 +1260,7 @@ typedef struct { #endif newfunc statresult_new_orig; PyObject *StatResultType; -#ifdef HAVE_STATX +#ifdef _Py_HAVE_STATX PyObject *StatxResultType; #endif PyObject *StatVFSResultType; @@ -2620,7 +2645,7 @@ _posix_clear(PyObject *module) Py_CLEAR(state->SchedParamType); #endif Py_CLEAR(state->StatResultType); -#ifdef HAVE_STATX +#ifdef _Py_HAVE_STATX Py_CLEAR(state->StatxResultType); #endif Py_CLEAR(state->StatVFSResultType); @@ -2648,7 +2673,7 @@ _posix_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->SchedParamType); #endif Py_VISIT(state->StatResultType); -#ifdef HAVE_STATX +#ifdef _Py_HAVE_STATX Py_VISIT(state->StatxResultType); #endif Py_VISIT(state->StatVFSResultType); @@ -3337,7 +3362,7 @@ os_lstat_impl(PyObject *module, path_t *path, int dir_fd) } -#ifdef HAVE_STATX +#ifdef _Py_HAVE_STATX typedef struct { PyObject_HEAD dev_t rdev, dev; @@ -3693,12 +3718,21 @@ os_statx_impl(PyObject *module, path_t *path, unsigned int mask, int flags, } int result; - Py_BEGIN_ALLOW_THREADS + int statx_dir_fd = path->is_fd ? path->fd : dir_fd; + const char *statx_path = path->is_fd ? "" : path->narrow; if (path->is_fd) { - result = statx(path->fd, "", flags | AT_EMPTY_PATH, mask, &v->stx); + flags |= AT_EMPTY_PATH; } - else { - result = statx(dir_fd, path->narrow, flags, mask, &v->stx); + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_STATX + if (statx != NULL) { + result = statx(statx_dir_fd, statx_path, flags, mask, &v->stx); + } + else +#endif + { + result = syscall(__NR_statx, statx_dir_fd, statx_path, flags, mask, + &v->stx); } Py_END_ALLOW_THREADS @@ -3713,7 +3747,7 @@ os_statx_impl(PyObject *module, path_t *path, unsigned int mask, int flags, assert(!PyErr_Occurred()); return (PyObject *)v; } -#endif /* HAVE_STATX */ +#endif /* _Py_HAVE_STATX */ /*[clinic input] @@ -18808,7 +18842,7 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, AT_NO_AUTOMOUNT)) return -1; #endif -#ifdef HAVE_STATX +#ifdef _Py_HAVE_STATX if (PyModule_AddIntMacro(m, STATX_TYPE)) return -1; if (PyModule_AddIntMacro(m, STATX_MODE)) return -1; if (PyModule_AddIntMacro(m, STATX_NLINK)) return -1; @@ -18845,7 +18879,7 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, AT_STATX_FORCE_SYNC)) return -1; if (PyModule_AddIntMacro(m, AT_STATX_DONT_SYNC)) return -1; /* STATX_ATTR_* constants are in the stat module */ -#endif /* HAVE_STATX */ +#endif /* _Py_HAVE_STATX */ #if defined(__APPLE__) if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1; @@ -19126,21 +19160,10 @@ posixmodule_exec(PyObject *m) } #endif -#ifdef HAVE_STATX - if (statx == NULL) { - PyObject* dct = PyModule_GetDict(m); - if (dct == NULL) { - return -1; - } - if (PyDict_PopString(dct, "statx", NULL) < 0) { - return -1; - } - } - else { - state->StatxResultType = PyType_FromModuleAndSpec(m, &pystatx_result_spec, NULL); - if (PyModule_AddObjectRef(m, "statx_result", state->StatxResultType) < 0) { - return -1; - } +#ifdef _Py_HAVE_STATX + state->StatxResultType = PyType_FromModuleAndSpec(m, &pystatx_result_spec, NULL); + if (PyModule_AddObjectRef(m, "statx_result", state->StatxResultType) < 0) { + return -1; } #endif diff --git a/Tools/build/check_capi_macros_ignored.txt b/Tools/build/check_capi_macros_ignored.txt index 008eba4b4171433..091fa9bd846681c 100644 --- a/Tools/build/check_capi_macros_ignored.txt +++ b/Tools/build/check_capi_macros_ignored.txt @@ -344,6 +344,7 @@ HAVE_LINUX_QRTR_H HAVE_LINUX_RANDOM_H HAVE_LINUX_SCHED_H HAVE_LINUX_SOUNDCARD_H +HAVE_LINUX_STAT_H HAVE_LINUX_TIPC_H HAVE_LINUX_VM_SOCKETS_H HAVE_LINUX_WAIT_H @@ -540,6 +541,7 @@ HAVE_STROPTS_H HAVE_STRSIGNAL HAVE_STRUCT_PASSWD_PW_GECOS HAVE_STRUCT_PASSWD_PW_PASSWD +HAVE_STRUCT_STATX HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN diff --git a/configure b/configure index 607f43db23360df..b459344b826830f 100755 --- a/configure +++ b/configure @@ -12019,6 +12019,12 @@ if test "x$ac_cv_header_linux_sched_h" = xyes then : printf "%s\n" "#define HAVE_LINUX_SCHED_H 1" >>confdefs.h +fi +ac_fn_c_check_header_compile "$LINENO" "linux/stat.h" "ac_cv_header_linux_stat_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_stat_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_STAT_H 1" >>confdefs.h + fi ac_fn_c_check_header_compile "$LINENO" "linux/tipc.h" "ac_cv_header_linux_tipc_h" "$ac_includes_default" if test "x$ac_cv_header_linux_tipc_h" = xyes @@ -26805,11 +26811,35 @@ printf "%s\n" "#define HAVE_SIGINFO_T_SI_BAND 1" >>confdefs.h fi -if test "$ac_cv_func_statx" = yes; then +case $ac_sys_system in #( + Linux*) : + + # Older libc headers may lack struct statx even when the kernel headers + # provide it for use with the syscall. + ac_fn_c_check_type "$LINENO" "struct statx" "ac_cv_type_struct_statx" "#include +" +if test "x$ac_cv_type_struct_statx" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STATX 1" >>confdefs.h + + +fi + + # Some systems have the definitions of the mask bits without having the # corresponding members in struct statx. Check for members added after Linux - # 4.11 (when statx itself was added). - ac_fn_c_check_member "$LINENO" "struct statx" "stx_mnt_id" "ac_cv_member_struct_statx_stx_mnt_id" "$ac_includes_default" + # 4.11 (when statx itself was added). stx_dio_offset_align was added with + # stx_dio_mem_align; stx_atomic_write_unit_max and + # stx_atomic_write_segments_max were added with stx_atomic_write_unit_min. + # The mask bit for stx_atomic_write_unit_max_opt predates that member. + ac_fn_c_check_member "$LINENO" "struct statx" "stx_mnt_id" "ac_cv_member_struct_statx_stx_mnt_id" " + #include + #if !defined(HAVE_STRUCT_STATX) && defined(HAVE_LINUX_STAT_H) + # include + #endif + +" if test "x$ac_cv_member_struct_statx_stx_mnt_id" = xyes then : @@ -26817,8 +26847,13 @@ printf "%s\n" "#define HAVE_STRUCT_STATX_STX_MNT_ID 1" >>confdefs.h fi +ac_fn_c_check_member "$LINENO" "struct statx" "stx_dio_mem_align" "ac_cv_member_struct_statx_stx_dio_mem_align" " + #include + #if !defined(HAVE_STRUCT_STATX) && defined(HAVE_LINUX_STAT_H) + # include + #endif - ac_fn_c_check_member "$LINENO" "struct statx" "stx_dio_mem_align" "ac_cv_member_struct_statx_stx_dio_mem_align" "$ac_includes_default" +" if test "x$ac_cv_member_struct_statx_stx_dio_mem_align" = xyes then : @@ -26826,9 +26861,13 @@ printf "%s\n" "#define HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN 1" >>confdefs.h fi +ac_fn_c_check_member "$LINENO" "struct statx" "stx_subvol" "ac_cv_member_struct_statx_stx_subvol" " + #include + #if !defined(HAVE_STRUCT_STATX) && defined(HAVE_LINUX_STAT_H) + # include + #endif - # stx_dio_offset_align was added together with stx_dio_mem_align - ac_fn_c_check_member "$LINENO" "struct statx" "stx_subvol" "ac_cv_member_struct_statx_stx_subvol" "$ac_includes_default" +" if test "x$ac_cv_member_struct_statx_stx_subvol" = xyes then : @@ -26836,8 +26875,13 @@ printf "%s\n" "#define HAVE_STRUCT_STATX_STX_SUBVOL 1" >>confdefs.h fi +ac_fn_c_check_member "$LINENO" "struct statx" "stx_atomic_write_unit_min" "ac_cv_member_struct_statx_stx_atomic_write_unit_min" " + #include + #if !defined(HAVE_STRUCT_STATX) && defined(HAVE_LINUX_STAT_H) + # include + #endif - ac_fn_c_check_member "$LINENO" "struct statx" "stx_atomic_write_unit_min" "ac_cv_member_struct_statx_stx_atomic_write_unit_min" "$ac_includes_default" +" if test "x$ac_cv_member_struct_statx_stx_atomic_write_unit_min" = xyes then : @@ -26845,10 +26889,13 @@ printf "%s\n" "#define HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN 1" >>confdefs fi +ac_fn_c_check_member "$LINENO" "struct statx" "stx_dio_read_offset_align" "ac_cv_member_struct_statx_stx_dio_read_offset_align" " + #include + #if !defined(HAVE_STRUCT_STATX) && defined(HAVE_LINUX_STAT_H) + # include + #endif - # stx_atomic_write_unit_max and stx_atomic_write_segments_max were added - # together with stx_atomic_write_unit_min - ac_fn_c_check_member "$LINENO" "struct statx" "stx_dio_read_offset_align" "ac_cv_member_struct_statx_stx_dio_read_offset_align" "$ac_includes_default" +" if test "x$ac_cv_member_struct_statx_stx_dio_read_offset_align" = xyes then : @@ -26856,11 +26903,13 @@ printf "%s\n" "#define HAVE_STRUCT_STATX_STX_DIO_READ_OFFSET_ALIGN 1" >>confdefs fi +ac_fn_c_check_member "$LINENO" "struct statx" "stx_atomic_write_unit_max_opt" "ac_cv_member_struct_statx_stx_atomic_write_unit_max_opt" " + #include + #if !defined(HAVE_STRUCT_STATX) && defined(HAVE_LINUX_STAT_H) + # include + #endif - # stx_atomic_write_unit_max_opt was added in Linux 6.16, but is controlled by - # the STATX_WRITE_ATOMIC mask bit added in Linux 6.11, so having the mask bit - # doesn't imply having the member. - ac_fn_c_check_member "$LINENO" "struct statx" "stx_atomic_write_unit_max_opt" "ac_cv_member_struct_statx_stx_atomic_write_unit_max_opt" "$ac_includes_default" +" if test "x$ac_cv_member_struct_statx_stx_atomic_write_unit_max_opt" = xyes then : @@ -26869,7 +26918,10 @@ printf "%s\n" "#define HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT 1" >>conf fi -fi + ;; #( + *) : + ;; +esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for time.h that defines altzone" >&5 printf %s "checking for time.h that defines altzone... " >&6; } diff --git a/configure.ac b/configure.ac index 775b8b4e6038773..c2890faa9a7dccb 100644 --- a/configure.ac +++ b/configure.ac @@ -3194,7 +3194,7 @@ AC_DEFINE([STDC_HEADERS], [1], AC_CHECK_HEADERS([ \ alloca.h asm/types.h bluetooth.h conio.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/limits.h linux/memfd.h \ - linux/netfilter_ipv4.h linux/random.h linux/soundcard.h linux/sched.h \ + linux/netfilter_ipv4.h linux/random.h linux/soundcard.h linux/sched.h linux/stat.h \ linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h \ poll.h process.h pthread.h pthread_np.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ @@ -6275,23 +6275,30 @@ AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_passwd], [], [], [[ # Issue #21085: In Cygwin, siginfo_t does not have si_band field. AC_CHECK_MEMBERS([siginfo_t.si_band], [], [], [[@%:@include ]]) -if test "$ac_cv_func_statx" = yes; then +AS_CASE([$ac_sys_system], [Linux*], [ + # Older libc headers may lack struct statx even when the kernel headers + # provide it for use with the syscall. + AC_CHECK_TYPES([struct statx], [], [], [[#include ]]) + # Some systems have the definitions of the mask bits without having the # corresponding members in struct statx. Check for members added after Linux - # 4.11 (when statx itself was added). - AC_CHECK_MEMBERS([struct statx.stx_mnt_id]) - AC_CHECK_MEMBERS([struct statx.stx_dio_mem_align]) - # stx_dio_offset_align was added together with stx_dio_mem_align - AC_CHECK_MEMBERS([struct statx.stx_subvol]) - AC_CHECK_MEMBERS([struct statx.stx_atomic_write_unit_min]) - # stx_atomic_write_unit_max and stx_atomic_write_segments_max were added - # together with stx_atomic_write_unit_min - AC_CHECK_MEMBERS([struct statx.stx_dio_read_offset_align]) - # stx_atomic_write_unit_max_opt was added in Linux 6.16, but is controlled by - # the STATX_WRITE_ATOMIC mask bit added in Linux 6.11, so having the mask bit - # doesn't imply having the member. - AC_CHECK_MEMBERS([struct statx.stx_atomic_write_unit_max_opt]) -fi + # 4.11 (when statx itself was added). stx_dio_offset_align was added with + # stx_dio_mem_align; stx_atomic_write_unit_max and + # stx_atomic_write_segments_max were added with stx_atomic_write_unit_min. + # The mask bit for stx_atomic_write_unit_max_opt predates that member. + AC_CHECK_MEMBERS([ + struct statx.stx_mnt_id, + struct statx.stx_dio_mem_align, + struct statx.stx_subvol, + struct statx.stx_atomic_write_unit_min, + struct statx.stx_dio_read_offset_align, + struct statx.stx_atomic_write_unit_max_opt], [], [], [[ + #include + #if !defined(HAVE_STRUCT_STATX) && defined(HAVE_LINUX_STAT_H) + # include + #endif + ]]) +]) AC_CACHE_CHECK([for time.h that defines altzone], [ac_cv_header_time_altzone], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], [[return altzone;]])], diff --git a/pyconfig.h.in b/pyconfig.h.in index 0c8c7989a95f972..23115656421e443 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -871,6 +871,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_SOUNDCARD_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_STAT_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_TIPC_H @@ -1447,6 +1450,9 @@ /* Define to 1 if 'pw_passwd' is a member of 'struct passwd'. */ #undef HAVE_STRUCT_PASSWD_PW_PASSWD +/* Define to 1 if the system has the type 'struct statx'. */ +#undef HAVE_STRUCT_STATX + /* Define to 1 if 'stx_atomic_write_unit_max_opt' is a member of 'struct statx'. */ #undef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT