@@ -412,29 +412,26 @@ extern char *ctermid_r(char *);
412412#ifdef HAVE_STATX
413413/* until we can assume glibc 2.28 at runtime, we must weakly link */
414414# pragma weak statx
415- /* provide constants introduced later than statx itself */
416- # ifndef STATX_MNT_ID
417- # define STATX_MNT_ID 0x00001000U
418- # endif
419- # ifndef STATX_DIOALIGN
420- # define STATX_DIOALIGN 0x00002000U
421- # endif
422- # ifndef STATX_MNT_ID_UNIQUE
423- # define STATX_MNT_ID_UNIQUE 0x00004000U
424- # endif
425- # ifndef STATX_SUBVOL
426- # define STATX_SUBVOL 0x00008000U
427- # endif
428- # ifndef STATX_WRITE_ATOMIC
429- # define STATX_WRITE_ATOMIC 0x00010000U
430- # endif
431- # ifndef STATX_DIO_READ_ALIGN
432- # define STATX_DIO_READ_ALIGN 0x00020000U
433- # endif
434- # define _Py_STATX_KNOWN (STATX_BASIC_STATS | STATX_BTIME | STATX_MNT_ID | \
435- STATX_DIOALIGN | STATX_MNT_ID_UNIQUE | \
436- STATX_SUBVOL | STATX_WRITE_ATOMIC | \
437- STATX_DIO_READ_ALIGN)
415+ static const unsigned int _Py_STATX_KNOWN = (STATX_BASIC_STATS | STATX_BTIME
416+ #ifdef STATX_MNT_ID
417+ | STATX_MNT_ID
418+ #endif
419+ #ifdef STATX_DIOALIGN
420+ | STATX_DIOALIGN
421+ #endif
422+ #ifdef STATX_MNT_ID_UNIQUE
423+ | STATX_MNT_ID_UNIQUE
424+ #endif
425+ #ifdef STATX_SUBVOL
426+ | STATX_SUBVOL
427+ #endif
428+ #ifdef STATX_WRITE_ATOMIC
429+ | STATX_WRITE_ATOMIC
430+ #endif
431+ #ifdef STATX_DIO_READ_ALIGN
432+ | STATX_DIO_READ_ALIGN
433+ #endif
434+ );
438435#endif /* HAVE_STATX */
439436
440437
@@ -3319,14 +3316,11 @@ typedef struct {
33193316 PyObject_HEAD
33203317 double atime_sec , btime_sec , ctime_sec , mtime_sec ;
33213318 dev_t rdev , dev ;
3322- /* Assertions in posixmodule_exec rely on struct statx being at the end. */
33233319 struct statx stx ;
33243320} Py_statx_result ;
33253321
33263322#define M (attr , type , offset , doc ) \
33273323 {attr, type, offset, Py_READONLY, PyDoc_STR(doc)}
3328- #define MO (attr , type , offset , doc ) \
3329- M(#attr, type, offsetof(Py_statx_result, stx) + offset, doc)
33303324#define MM (attr , type , member , doc ) \
33313325 M(#attr, type, offsetof(Py_statx_result, stx.stx_##member), doc)
33323326#define MX (attr , type , member , doc ) \
@@ -3355,78 +3349,64 @@ static PyMemberDef pystatx_result_members[] = {
33553349 MM (stx_dev_major , Py_T_UINT , dev_major , "containing device major number" ),
33563350 MM (stx_dev_minor , Py_T_UINT , dev_minor , "containing device minor number" ),
33573351 MX (st_dev , Py_T_ULONGLONG , dev , "device" ),
3358- /* We may be building against old kernel API headers that do not have the
3359- names of these members, so access them by offset. The reserved space in
3360- struct statx was originally defined as arrays of u64, so later members
3361- of other types must use getters to avoid a strict aliasing violation. */
3362- MO (stx_mnt_id , Py_T_ULONGLONG , 144 , "mount ID" ),
3363- MO (stx_subvol , Py_T_ULONGLONG , 160 , "subvolume ID" ),
3352+ #ifdef STATX_MNT_ID
3353+ MM (stx_mnt_id , Py_T_ULONGLONG , mnt_id , "mount ID" ),
3354+ #endif
3355+ #ifdef STATX_DIOALIGN
3356+ MM (stx_dio_mem_align , Py_T_UINT , dio_mem_align ,
3357+ "direct I/O memory buffer alignment" ),
3358+ MM (stx_dio_offset_align , Py_T_UINT , dio_offset_align ,
3359+ "direct I/O file offset alignment" ),
3360+ #endif
3361+ #ifdef STATX_SUBVOL
3362+ MM (stx_subvol , Py_T_ULONGLONG , subvol , "subvolume ID" ),
3363+ #endif
3364+ #ifdef STATX_WRITE_ATOMIC
3365+ MM (stx_atomic_write_unit_min , Py_T_UINT , atomic_write_unit_min ,
3366+ "minimum size for direct I/O with torn-write protection" ),
3367+ MM (stx_atomic_write_unit_max , Py_T_UINT , atomic_write_unit_max ,
3368+ "maximum size for direct I/O with torn-write protection" ),
3369+ MM (stx_atomic_write_unit_max_opt , Py_T_UINT , atomic_write_unit_max_opt ,
3370+ "maximum optimized size for direct I/O with torn-write protection" ),
3371+ MM (stx_atomic_write_segments_max , Py_T_UINT , atomic_write_segments_max ,
3372+ "maximum iovecs for direct I/O with torn-write protection" ),
3373+ #endif
3374+ #ifdef STATX_DIO_READ_ALIGN
3375+ MM (stx_dio_read_offset_align , Py_T_UINT , dio_read_offset_align ,
3376+ "direct I/O file offset alignment for reads" ),
3377+ #endif
33643378 {NULL },
33653379};
33663380
33673381#undef MX
33683382#undef MM
3369- #undef MO
33703383#undef M
33713384
3372- static PyObject *
3373- pystatx_result_get_u32 (PyObject * op , void * context ) {
3374- Py_statx_result * self = (Py_statx_result * ) op ;
3375- uint16_t offset = (uintptr_t )context ;
3376- uint32_t val ;
3377- memcpy (& val , (void * )self + offset , sizeof (val ));
3378- return PyLong_FromUInt32 (val );
3379- }
3380-
33813385static PyObject *
33823386pystatx_result_get_nsec (PyObject * op , void * context )
33833387{
3384- Py_statx_result * self = (Py_statx_result * ) op ;
33853388 uint16_t offset = (uintptr_t )context ;
3386- struct statx_timestamp val ;
3387- memcpy (& val , (void * )self + offset , sizeof (val ));
3389+ struct statx_timestamp * ts = (void * )op + offset ;
33883390 _posixstate * state = PyType_GetModuleState (Py_TYPE (op ));
33893391 assert (state != NULL );
3390- return stat_nanosecond_timestamp (state , val . tv_sec , val . tv_nsec );
3392+ return stat_nanosecond_timestamp (state , ts -> tv_sec , ts -> tv_nsec );
33913393}
33923394
33933395/* The low 16 bits of the context pointer are the offset from the start of
33943396 Py_statx_result to the struct statx member. */
3395- #define OFFSET_CONTEXT (offset ) (void *)(offsetof(Py_statx_result, stx) + offset)
3396- #define MEMBER_CONTEXT (name ) OFFSET_CONTEXT(offsetof(struct statx, stx_##name))
3397-
3398- #define G (attr , type , doc , context ) \
3399- {attr, pystatx_result_get_##type, NULL, PyDoc_STR(doc), context}
34003397#define GM (attr , type , member , doc ) \
3401- G(#attr, type, doc, MEMBER_CONTEXT(member))
3402- #define GO (attr , type , offset , doc ) \
3403- G(#attr, type, doc, OFFSET_CONTEXT(offset))
3398+ {#attr, pystatx_result_get_##type, NULL, PyDoc_STR(doc), \
3399+ (void *)(offsetof(Py_statx_result, stx.stx_##member))}
34043400
34053401static PyGetSetDef pystatx_result_getset [] = {
34063402 GM (st_atime_ns , nsec , atime , "time of last access in nanoseconds" ),
34073403 GM (st_birthtime_ns , nsec , btime , "time of creation in nanoseconds" ),
34083404 GM (st_ctime_ns , nsec , ctime , "time of last change in nanoseconds" ),
34093405 GM (st_mtime_ns , nsec , mtime , "time of last modification in nanoseconds" ),
3410- GO (stx_dio_mem_align , u32 , 152 , "direct I/O memory buffer alignment" ),
3411- GO (stx_dio_offset_align , u32 , 156 , "direct I/O file offset alignment" ),
3412- GO (stx_atomic_write_unit_min , u32 , 168 ,
3413- "minimum size for direct I/O with torn-write protection" ),
3414- GO (stx_atomic_write_unit_max , u32 , 172 ,
3415- "maximum size for direct I/O with torn-write protection" ),
3416- GO (stx_atomic_write_segments_max , u32 , 176 ,
3417- "maximum iovecs for direct I/O with torn-write protection" ),
3418- GO (stx_dio_read_offset_align , u32 , 180 ,
3419- "direct I/O file offset alignment for reads" ),
3420- GO (stx_atomic_write_unit_max_opt , u32 , 184 ,
3421- "maximum optimized size for direct I/O with torn-write protection" ),
34223406 {NULL },
34233407};
34243408
3425- #undef GO
34263409#undef GM
3427- #undef G
3428- #undef MEMBER_CONTEXT
3429- #undef OFFSET_CONTEXT
34303410
34313411static PyObject *
34323412pystatx_result_repr (PyObject * op ) {
@@ -18269,12 +18249,24 @@ all_ins(PyObject *m)
1826918249 if (PyModule_AddIntMacro (m , STATX_BLOCKS )) return -1 ;
1827018250 if (PyModule_AddIntMacro (m , STATX_BASIC_STATS )) return -1 ;
1827118251 if (PyModule_AddIntMacro (m , STATX_BTIME )) return -1 ;
18252+ #ifdef STATX_MNT_ID
1827218253 if (PyModule_AddIntMacro (m , STATX_MNT_ID )) return -1 ;
18254+ #endif
18255+ #ifdef STATX_DIOALIGN
1827318256 if (PyModule_AddIntMacro (m , STATX_DIOALIGN )) return -1 ;
18257+ #endif
18258+ #ifdef STATX_MNT_ID_UNIQUE
1827418259 if (PyModule_AddIntMacro (m , STATX_MNT_ID_UNIQUE )) return -1 ;
18260+ #endif
18261+ #ifdef STATX_SUBVOL
1827518262 if (PyModule_AddIntMacro (m , STATX_SUBVOL )) return -1 ;
18263+ #endif
18264+ #ifdef STATX_WRITE_ATOMIC
1827618265 if (PyModule_AddIntMacro (m , STATX_WRITE_ATOMIC )) return -1 ;
18266+ #endif
18267+ #ifdef STATX_DIO_READ_ALIGN
1827718268 if (PyModule_AddIntMacro (m , STATX_DIO_READ_ALIGN )) return -1 ;
18269+ #endif
1827818270 /* STATX_ALL intentionally omitted because it is deprecated */
1827918271 if (PyModule_AddIntMacro (m , AT_STATX_SYNC_AS_STAT )) return -1 ;
1828018272 if (PyModule_AddIntMacro (m , AT_STATX_FORCE_SYNC )) return -1 ;
@@ -18554,47 +18546,6 @@ posixmodule_exec(PyObject *m)
1855418546#endif
1855518547
1855618548#ifdef HAVE_STATX
18557- #ifndef NDEBUG
18558- /* struct statx may be extended in the future. Assert that our definition
18559- of struct statx is large enough for all the members we expose to Python.
18560- These asserts rely on struct statx being the last member of
18561- Py_statx_result. If you hit these asserts, upgrade your kernel
18562- userspace API and/or libc headers. */
18563- for (const PyMemberDef * m = pystatx_result_members ; m -> name != NULL ; ++ m ) {
18564- Py_ssize_t size ;
18565- switch (m -> type ) {
18566- case Py_T_USHORT :
18567- size = 2 ;
18568- break ;
18569- case Py_T_UINT :
18570- size = 4 ;
18571- break ;
18572- case Py_T_ULONGLONG :
18573- case Py_T_DOUBLE :
18574- size = 8 ;
18575- break ;
18576- default :
18577- assert (false);
18578- }
18579- assert (m -> offset + size <= (Py_ssize_t )sizeof (Py_statx_result ));
18580- }
18581-
18582- for (const PyGetSetDef * m = pystatx_result_getset ; m -> name != NULL ; ++ m ) {
18583- uint16_t offset = (uintptr_t )m -> closure ;
18584- Py_ssize_t size ;
18585- if (m -> get == pystatx_result_get_u32 ) {
18586- size = 4 ;
18587- }
18588- else if (m -> get == pystatx_result_get_nsec ) {
18589- size = sizeof (struct statx_timestamp );
18590- }
18591- else {
18592- assert (false);
18593- }
18594- assert (offset + size <= (Py_ssize_t )sizeof (Py_statx_result ));
18595- }
18596- #endif /* !NDEBUG */
18597-
1859818549 if (statx == NULL ) {
1859918550 PyObject * dct = PyModule_GetDict (m );
1860018551 if (dct == NULL ) {
0 commit comments