]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-129539: Reorganize posixmodule.c header (#129558)
authorVictor Stinner <vstinner@python.org>
Sun, 2 Feb 2025 09:16:48 +0000 (10:16 +0100)
committerGitHub <noreply@github.com>
Sun, 2 Feb 2025 09:16:48 +0000 (09:16 +0000)
Add sections: Python includes, system includes, etc.

Add a comment explaining why an include is needed.

Modules/posixmodule.c

index b3b5572e1cfa30fba39fd856dac38165bcb90880..6dfe73017abf9df8a6d6cd3560954a035f1c9fa7 100644 (file)
@@ -7,6 +7,8 @@
    of the compiler used.  Different compilers define their own feature
    test macro, e.g. '_MSC_VER'. */
 
+// --- Python includes ------------------------------------------------------
+
 #include "Python.h"
 
 #ifdef __VXWORKS__
 #include "pycore_time.h"          // _PyLong_FromTime_t()
 #include "pycore_typeobject.h"    // _PyType_AddMethod()
 
-#ifdef HAVE_UNISTD_H
-#  include <unistd.h>             // symlink()
-#endif
-
-#ifdef MS_WINDOWS
-#  include <windows.h>
-#  if !defined(MS_WINDOWS_GAMES) || defined(MS_WINDOWS_DESKTOP)
-#    include <pathcch.h>
-#  endif
-#  include <winioctl.h>
-#  include <lmcons.h>             // UNLEN
-#  include "osdefs.h"             // SEP
-#  include <aclapi.h>             // SetEntriesInAcl
-#  include <sddl.h>               // SDDL_REVISION_1
-#  if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
-#    define HAVE_SYMLINK
-#  endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */
-#endif
-
 #ifndef MS_WINDOWS
-#  include "posixmodule.h"
+#  include "posixmodule.h"        // _PyLong_FromUid()
 #else
-#  include "pycore_fileutils_windows.h"
-#  include "winreparse.h"
+#  include "pycore_fileutils_windows.h" // _Py_GetFileInformationByName()
+#  include "osdefs.h"             // SEP
+#  include "winreparse.h"         // _Py_REPARSE_DATA_BUFFER
 #endif
 
-#if !defined(EX_OK) && defined(EXIT_SUCCESS)
-#  define EX_OK EXIT_SUCCESS
+
+// --- System includes ------------------------------------------------------
+
+#include <stdio.h>                // ctermid()
+#include <stdlib.h>               // system()
+
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>             // symlink()
 #endif
 
 #ifdef __APPLE__
- /* Needed for the implementation of os.statvfs */
  /* Needed for the implementation of os.statvfs */
 #  include <sys/param.h>
 #  include <sys/mount.h>
 #endif
 
-/* On android API level 21, 'AT_EACCESS' is not declared although
- * HAVE_FACCESSAT is defined. */
-#ifdef __ANDROID__
-#  undef HAVE_FACCESSAT
-#endif
-
-#include <stdio.h>                // ctermid()
-#include <stdlib.h>               // system()
 #ifdef HAVE_SYS_TIME_H
 #  include <sys/time.h>           // futimes()
 #endif
+
 #ifdef HAVE_SYS_PIDFD_H
 #  include <sys/pidfd.h>          // PIDFD_NONBLOCK
 #endif
 
-
-// SGI apparently needs this forward declaration
-#ifdef HAVE__GETPTY
-#  include <sys/types.h>          // mode_t
-   extern char * _getpty(int *, int, mode_t, int);
-#endif
-
 #ifdef __EMSCRIPTEN__
-#include "emscripten.h" // emscripten_debugger()
-#endif
-
-/*
- * A number of APIs are available on macOS from a certain macOS version.
- * To support building with a new SDK while deploying to older versions
- * the availability test is split into two:
- *   - HAVE_<FUNCTION>:  The configure check for compile time availability
- *   - HAVE_<FUNCTION>_RUNTIME: Runtime check for availability
- *
- * The latter is always true when not on macOS, or when using a compiler
- * that does not support __has_builtin (older versions of Xcode).
- *
- * Due to compiler restrictions there is one valid use of HAVE_<FUNCTION>_RUNTIME:
- *    if (HAVE_<FUNCTION>_RUNTIME) { ... }
- *
- * In mixing the test with other tests or using negations will result in compile
- * errors.
- */
-#if defined(__APPLE__)
-
-#include <mach/mach.h>
-
-#if defined(__has_builtin)
-#if __has_builtin(__builtin_available)
-#define HAVE_BUILTIN_AVAILABLE 1
-#endif
-#endif
-
-#ifdef HAVE_BUILTIN_AVAILABLE
-#  define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_FCHOWNAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_LINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_FDOPENDIR_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_MKDIRAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_RENAMEAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_UNLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_OPENAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_READLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_SYMLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
-#  define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
-#  define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
-#  define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
-#  define HAVE_MKFIFOAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)
-#  define HAVE_MKNODAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)
-#  define HAVE_PTSNAME_R_RUNTIME __builtin_available(macOS 10.13.4, iOS 11.3, tvOS 11.3, watchOS 4.3, *)
-
-#  define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
-
-#else /* Xcode 8 or earlier */
-
-   /* __builtin_available is not present in these compilers, but
-    * some of the symbols might be weak linked (10.10 SDK or later
-    * deploying on 10.9.
-    *
-    * Fall back to the older style of availability checking for
-    * symbols introduced in macOS 10.10.
-    */
-
-#  ifdef HAVE_FSTATAT
-#    define HAVE_FSTATAT_RUNTIME (fstatat != NULL)
-#  endif
-
-#  ifdef HAVE_FACCESSAT
-#    define HAVE_FACCESSAT_RUNTIME (faccessat != NULL)
-#  endif
-
-#  ifdef HAVE_FCHMODAT
-#    define HAVE_FCHMODAT_RUNTIME (fchmodat != NULL)
-#  endif
-
-#  ifdef HAVE_FCHOWNAT
-#    define HAVE_FCHOWNAT_RUNTIME (fchownat != NULL)
-#  endif
-
-#  ifdef HAVE_LINKAT
-#    define HAVE_LINKAT_RUNTIME (linkat != NULL)
-#  endif
-
-#  ifdef HAVE_FDOPENDIR
-#    define HAVE_FDOPENDIR_RUNTIME (fdopendir != NULL)
-#  endif
-
-#  ifdef HAVE_MKDIRAT
-#    define HAVE_MKDIRAT_RUNTIME (mkdirat != NULL)
-#  endif
-
-#  ifdef HAVE_RENAMEAT
-#    define HAVE_RENAMEAT_RUNTIME (renameat != NULL)
-#  endif
-
-#  ifdef HAVE_UNLINKAT
-#    define HAVE_UNLINKAT_RUNTIME (unlinkat != NULL)
-#  endif
-
-#  ifdef HAVE_OPENAT
-#    define HAVE_OPENAT_RUNTIME (openat != NULL)
-#  endif
-
-#  ifdef HAVE_READLINKAT
-#    define HAVE_READLINKAT_RUNTIME (readlinkat != NULL)
-#  endif
-
-#  ifdef HAVE_SYMLINKAT
-#    define HAVE_SYMLINKAT_RUNTIME (symlinkat != NULL)
-#  endif
-
-#  ifdef HAVE_UTIMENSAT
-#    define HAVE_UTIMENSAT_RUNTIME (utimensat != NULL)
-#  endif
-
-#  ifdef HAVE_FUTIMENS
-#    define HAVE_FUTIMENS_RUNTIME (futimens != NULL)
-#  endif
-
-#  ifdef HAVE_PWRITEV
-#    define HAVE_PWRITEV_RUNTIME (pwritev != NULL)
-#  endif
-
-#  ifdef HAVE_MKFIFOAT
-#    define HAVE_MKFIFOAT_RUNTIME (mkfifoat != NULL)
-#  endif
-
-#  ifdef HAVE_MKNODAT
-#    define HAVE_MKNODAT_RUNTIME (mknodat != NULL)
-#  endif
-
-#  ifdef HAVE_PTSNAME_R
-#    define HAVE_PTSNAME_R_RUNTIME (ptsname_r != NULL)
-#  endif
-
-#endif
-
-#ifdef HAVE_FUTIMESAT
-/* Some of the logic for weak linking depends on this assertion */
-# error "HAVE_FUTIMESAT unexpectedly defined"
-#endif
-
-#else
-#  define HAVE_FSTATAT_RUNTIME 1
-#  define HAVE_FACCESSAT_RUNTIME 1
-#  define HAVE_FCHMODAT_RUNTIME 1
-#  define HAVE_FCHOWNAT_RUNTIME 1
-#  define HAVE_LINKAT_RUNTIME 1
-#  define HAVE_FDOPENDIR_RUNTIME 1
-#  define HAVE_MKDIRAT_RUNTIME 1
-#  define HAVE_RENAMEAT_RUNTIME 1
-#  define HAVE_UNLINKAT_RUNTIME 1
-#  define HAVE_OPENAT_RUNTIME 1
-#  define HAVE_READLINKAT_RUNTIME 1
-#  define HAVE_SYMLINKAT_RUNTIME 1
-#  define HAVE_FUTIMENS_RUNTIME 1
-#  define HAVE_UTIMENSAT_RUNTIME 1
-#  define HAVE_PWRITEV_RUNTIME 1
-#  define HAVE_MKFIFOAT_RUNTIME 1
-#  define HAVE_MKNODAT_RUNTIME 1
-#  define HAVE_PTSNAME_R_RUNTIME 1
+#  include "emscripten.h"         // emscripten_debugger()
 #endif
 
-
-PyDoc_STRVAR(posix__doc__,
-"This module provides access to operating system functionality that is\n\
-standardized by the C Standard and the POSIX standard (a thinly\n\
-disguised Unix interface).  Refer to the library manual and\n\
-corresponding Unix manual entries for more information on calls.");
-
-
 #ifdef HAVE_SYS_UIO_H
 #  include <sys/uio.h>
 #endif
 
 #ifdef HAVE_SYS_TYPES_H
-/* Should be included before <sys/sysmacros.h> on HP-UX v3 */
+   /* Should be included before <sys/sysmacros.h> on HP-UX v3 */
 #  include <sys/types.h>
-#endif /* HAVE_SYS_TYPES_H */
-
+#endif
 #ifdef HAVE_SYS_SYSMACROS_H
-/* GNU C Library: major(), minor(), makedev() */
+   /* GNU C Library: major(), minor(), makedev() */
 #  include <sys/sysmacros.h>
 #endif
 
 #ifdef HAVE_SYS_STAT_H
 #  include <sys/stat.h>
-#endif /* HAVE_SYS_STAT_H */
+#endif
 
 #ifdef HAVE_SYS_WAIT_H
 #  include <sys/wait.h>           // WNOHANG
 #endif
+
 #ifdef HAVE_LINUX_WAIT_H
 #  include <linux/wait.h>         // P_PIDFD
 #endif
@@ -284,54 +94,34 @@ corresponding Unix manual entries for more information on calls.");
 #endif
 
 #ifdef HAVE_FCNTL_H
-#  include <fcntl.h>
+#  include <fcntl.h>              // fcntl()
 #endif
 
 #ifdef HAVE_GRP_H
-#  include <grp.h>
+#  include <grp.h>                // setgroups()
 #endif
 
 #ifdef HAVE_SYSEXITS_H
-#  include <sysexits.h>
+#  include <sysexits.h>           // EX_OK
 #endif
 
 #ifdef HAVE_SYS_LOADAVG_H
-#  include <sys/loadavg.h>
+#  include <sys/loadavg.h>        // getloadavg()
 #endif
 
 #ifdef HAVE_SYS_SENDFILE_H
-#  include <sys/sendfile.h>
+#  include <sys/sendfile.h>       // sendfile()
 #endif
 
 #if defined(__APPLE__)
-#  include <copyfile.h>
+#  include <copyfile.h>           // fcopyfile()
 #endif
 
 #ifdef HAVE_SCHED_H
-#  include <sched.h>
+#  include <sched.h>              // sched_setscheduler()
 #endif
-
 #ifdef HAVE_LINUX_SCHED_H
-#  include <linux/sched.h>
-#endif
-
-#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
-#  undef HAVE_SCHED_SETAFFINITY
-#endif
-
-#if defined(HAVE_SYS_XATTR_H)
-#  if defined(HAVE_LINUX_LIMITS_H) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
-#    define USE_XATTRS
-#    include <linux/limits.h>  // Needed for XATTR_SIZE_MAX on musl libc.
-#  endif
-#  if defined(__CYGWIN__)
-#    define USE_XATTRS
-#    include <cygwin/limits.h>  // Needed for XATTR_SIZE_MAX and XATTR_LIST_MAX.
-#  endif
-#endif
-
-#ifdef USE_XATTRS
-#  include <sys/xattr.h>
+#  include <linux/sched.h>        // SCHED_IDLE, SCHED_RR
 #endif
 
 #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
@@ -357,36 +147,141 @@ corresponding Unix manual entries for more information on calls.");
 #endif
 
 #ifdef HAVE_LINUX_RANDOM_H
-#  include <linux/random.h>
+#  include <linux/random.h>       // GRND_RANDOM
 #endif
 #ifdef HAVE_GETRANDOM_SYSCALL
-#  include <sys/syscall.h>
+#  include <sys/syscall.h>        // syscall()
 #endif
 
-#ifdef HAVE_WINDOWS_CONSOLE_IO
-#  define TERMSIZE_USE_CONIO
-#elif defined(HAVE_SYS_IOCTL_H)
-#  include <sys/ioctl.h>
-#  if defined(HAVE_TERMIOS_H)
-#    include <termios.h>
-#  endif
-#  if defined(TIOCGWINSZ)
-#    define TERMSIZE_USE_IOCTL
-#  endif
-#endif /* HAVE_WINDOWS_CONSOLE_IO */
+#ifdef HAVE_POSIX_SPAWN
+#  include <spawn.h>              // posix_spawn()
+#endif
 
-/* Various compilers have only certain posix functions */
-/* XXX Gosh I wish these were all moved into pyconfig.h */
-#if defined(__WATCOMC__) && !defined(__QNX__)           /* Watcom compiler */
-#  define HAVE_OPENDIR    1
-#  define HAVE_SYSTEM     1
-#  include <process.h>
-#elif defined( _MSC_VER)
-  /* Microsoft compiler */
-#  if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM)
-#    define HAVE_GETPPID    1
-#  endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_APP | MS_WINDOWS_SYSTEM */
-#  if defined(MS_WINDOWS_DESKTOP)
+#ifdef HAVE_UTIME_H
+#  include <utime.h>              // utime()
+#endif
+
+#ifdef HAVE_SYS_UTIME_H
+#  include <sys/utime.h>
+#  define HAVE_UTIME_H /* pretend we do for the rest of this file */
+#endif
+
+#ifdef HAVE_SYS_TIMES_H
+#  include <sys/times.h>          // times()
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_UTSNAME_H
+#  include <sys/utsname.h>        // uname()
+#endif
+
+/* memfd_create is either defined in sys/mman.h or sys/memfd.h
+ * linux/memfd.h defines additional flags
+ */
+#ifdef HAVE_SYS_MMAN_H
+#  include <sys/mman.h>           // memfd_create()
+#endif
+#ifdef HAVE_SYS_MEMFD_H
+#  include <sys/memfd.h>          // memfd_create()
+#endif
+#ifdef HAVE_LINUX_MEMFD_H
+#  include <linux/memfd.h>        // memfd_create(), MFD_CLOEXEC
+#endif
+
+#ifdef HAVE_SYS_EVENTFD_H
+#  include <sys/eventfd.h>        // eventfd()
+#endif
+
+#ifdef HAVE_SYS_TIMERFD_H
+#  include <sys/timerfd.h>        // timerfd_create()
+#endif
+
+#ifdef _Py_MEMORY_SANITIZER
+#  include <sanitizer/msan_interface.h> // __msan_unpoison()
+#endif
+
+
+// --- More complex system includes -----------------------------------------
+
+#ifdef MS_WINDOWS
+#  include <windows.h>
+#  if !defined(MS_WINDOWS_GAMES) || defined(MS_WINDOWS_DESKTOP)
+#    include <pathcch.h>          // PathCchSkipRoot()
+#  endif
+#  include <aclapi.h>             // SetEntriesInAcl
+#  include <lmcons.h>             // UNLEN
+#  include <sddl.h>               // SDDL_REVISION_1
+#  include <winioctl.h>           // FSCTL_GET_REPARSE_POINT
+#  if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
+#    define HAVE_SYMLINK
+#  endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */
+#endif
+
+
+#ifdef _MSC_VER
+#  ifdef HAVE_DIRECT_H
+#    include <direct.h>
+#  endif
+#  ifdef HAVE_IO_H
+#    include <io.h>
+#  endif
+#  ifdef HAVE_PROCESS_H
+#    include <process.h>          // getpid(), _cwait()
+#  endif
+#  include <malloc.h>
+#endif /* _MSC_VER */
+
+
+#ifdef HAVE__GETPTY
+#  include <sys/types.h>          // mode_t
+   // SGI apparently needs this forward declaration
+   extern char * _getpty(int *, int, mode_t, int);
+#endif
+
+
+#if defined(HAVE_SYS_XATTR_H)
+#  if defined(HAVE_LINUX_LIMITS_H) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
+#    define USE_XATTRS
+#    include <linux/limits.h>  // Needed for XATTR_SIZE_MAX on musl libc.
+#  endif
+#  if defined(__CYGWIN__)
+#    define USE_XATTRS
+#    include <cygwin/limits.h>  // Needed for XATTR_SIZE_MAX and XATTR_LIST_MAX.
+#  endif
+#endif
+#ifdef USE_XATTRS
+#  include <sys/xattr.h>          // fgetxattr()
+#endif
+
+
+#ifdef HAVE_WINDOWS_CONSOLE_IO
+#  define TERMSIZE_USE_CONIO
+#elif defined(HAVE_SYS_IOCTL_H)
+#  include <sys/ioctl.h>          // ioctl(), TIOCGWINSZ
+#  if defined(HAVE_TERMIOS_H)
+#    include <termios.h>
+#  endif
+#  if defined(TIOCGWINSZ)
+#    define TERMSIZE_USE_IOCTL
+#  endif
+#endif
+
+
+/* Various compilers have only certain posix functions */
+/* XXX Gosh I wish these were all moved into pyconfig.h */
+#if defined(__WATCOMC__) && !defined(__QNX__)           /* Watcom compiler */
+#  define HAVE_OPENDIR    1
+#  define HAVE_SYSTEM     1
+#  include <process.h>
+#elif defined( _MSC_VER)
+  /* Microsoft compiler */
+#  if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM)
+#    define HAVE_GETPPID    1
+#  endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_APP | MS_WINDOWS_SYSTEM */
+#  if defined(MS_WINDOWS_DESKTOP)
 #    define HAVE_GETLOGIN   1
 #  endif /* MS_WINDOWS_DESKTOP */
 #  if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
@@ -400,23 +295,15 @@ corresponding Unix manual entries for more information on calls.");
 #  define HAVE_PIPE       1
 #  define HAVE_FSYNC      1
 #  define fsync _commit
-#endif  /* ! __WATCOMC__ || __QNX__ */
-
-/*[clinic input]
-# one of the few times we lie about this name!
-module os
-[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
+#endif
 
-#ifndef _MSC_VER
 
-#if defined(__sgi)&&_COMPILER_VERSION>=700
+#if !defined(_MSC_VER) && defined(__sgi) && _COMPILER_VERSION>=700
 /* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
    (default) */
-extern char        *ctermid_r(char *);
+extern char *ctermid_r(char *);
 #endif
 
-#endif /* !_MSC_VER */
 
 #if defined(__VXWORKS__)
 #  include <vxCpuLib.h>
@@ -430,33 +317,9 @@ extern char        *ctermid_r(char *);
 #  endif
 #endif /* __VXWORKS__ */
 
-#ifdef HAVE_POSIX_SPAWN
-#  include <spawn.h>
-#endif
-
-#ifdef HAVE_UTIME_H
-#  include <utime.h>
-#endif /* HAVE_UTIME_H */
-
-#ifdef HAVE_SYS_UTIME_H
-#  include <sys/utime.h>
-#  define HAVE_UTIME_H /* pretend we do for the rest of this file */
-#endif /* HAVE_SYS_UTIME_H */
-
-#ifdef HAVE_SYS_TIMES_H
-#  include <sys/times.h>
-#endif /* HAVE_SYS_TIMES_H */
-
-#ifdef HAVE_SYS_PARAM_H
-#  include <sys/param.h>
-#endif /* HAVE_SYS_PARAM_H */
-
-#ifdef HAVE_SYS_UTSNAME_H
-#  include <sys/utsname.h>
-#endif /* HAVE_SYS_UTSNAME_H */
 
 #ifdef HAVE_DIRENT_H
-#  include <dirent.h>
+#  include <dirent.h>             // opendir()
 #  define NAMLEN(dirent) strlen((dirent)->d_name)
 #else
 #  if defined(__WATCOMC__) && !defined(__QNX__)
@@ -477,18 +340,20 @@ extern char        *ctermid_r(char *);
 #  endif
 #endif
 
-#ifdef _MSC_VER
-#  ifdef HAVE_DIRECT_H
-#    include <direct.h>
-#  endif
-#  ifdef HAVE_IO_H
-#    include <io.h>
+
+#if defined(MAJOR_IN_MKDEV)
+#  include <sys/mkdev.h>
+#else
+#  if defined(MAJOR_IN_SYSMACROS)
+#    include <sys/sysmacros.h>
 #  endif
-#  ifdef HAVE_PROCESS_H
-#    include <process.h>
+#  if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
+#    include <sys/mkdev.h>
 #  endif
-#  include <malloc.h>
-#endif /* _MSC_VER */
+#endif
+
+
+// --- Macros ---------------------------------------------------------------
 
 #ifndef MAXPATHLEN
 #  if defined(PATH_MAX) && PATH_MAX > 1024
@@ -498,6 +363,7 @@ extern char        *ctermid_r(char *);
 #  endif
 #endif /* MAXPATHLEN */
 
+
 #ifdef UNION_WAIT
    /* Emulate some macros on systems that have a union instead of macros */
 #  ifndef WIFEXITED
@@ -517,12 +383,14 @@ extern char        *ctermid_r(char *);
 #  define WAIT_STATUS_INT(s) (s)
 #endif /* UNION_WAIT */
 
+
 /* Don't use the "_r" form if we don't need it (also, won't have a
    prototype for it, at least on Solaris -- maybe others as well?). */
 #if defined(HAVE_CTERMID_R)
 #  define USE_CTERMID_R
 #endif
 
+
 /* choose the appropriate stat and fstat functions and return structs */
 #undef STAT
 #undef FSTAT
@@ -539,25 +407,19 @@ extern char        *ctermid_r(char *);
 #  define STRUCT_STAT struct stat
 #endif
 
-#if defined(MAJOR_IN_MKDEV)
-#  include <sys/mkdev.h>
-#else
-#  if defined(MAJOR_IN_SYSMACROS)
-#    include <sys/sysmacros.h>
-#  endif
-#  if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
-#    include <sys/mkdev.h>
-#  endif
+
+#if !defined(EX_OK) && defined(EXIT_SUCCESS)
+#  define EX_OK EXIT_SUCCESS
 #endif
 
-#ifdef MS_WINDOWS
-#  define INITFUNC PyInit_nt
-#  define MODNAME "nt"
-#  define MODNAME_OBJ &_Py_ID(nt)
-#else
-#  define INITFUNC PyInit_posix
-#  define MODNAME "posix"
-#  define MODNAME_OBJ &_Py_ID(posix)
+#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
+#  undef HAVE_SCHED_SETAFFINITY
+#endif
+
+/* On android API level 21, 'AT_EACCESS' is not declared although
+ * HAVE_FACCESSAT is defined. */
+#ifdef __ANDROID__
+#  undef HAVE_FACCESSAT
 #endif
 
 #if defined(__sun)
@@ -565,33 +427,195 @@ extern char        *ctermid_r(char *);
 #  define HAVE_STRUCT_STAT_ST_FSTYPE 1
 #endif
 
-/* memfd_create is either defined in sys/mman.h or sys/memfd.h
- * linux/memfd.h defines additional flags
+
+// --- Apple __builtin_available() macros -----------------------------------
+
+/*
+ * A number of APIs are available on macOS from a certain macOS version.
+ * To support building with a new SDK while deploying to older versions
+ * the availability test is split into two:
+ *   - HAVE_<FUNCTION>:  The configure check for compile time availability
+ *   - HAVE_<FUNCTION>_RUNTIME: Runtime check for availability
+ *
+ * The latter is always true when not on macOS, or when using a compiler
+ * that does not support __has_builtin (older versions of Xcode).
+ *
+ * Due to compiler restrictions there is one valid use of HAVE_<FUNCTION>_RUNTIME:
+ *    if (HAVE_<FUNCTION>_RUNTIME) { ... }
+ *
+ * In mixing the test with other tests or using negations will result in compile
+ * errors.
  */
-#ifdef HAVE_SYS_MMAN_H
-#  include <sys/mman.h>
+#if defined(__APPLE__)
+
+#include <mach/mach.h>
+
+#if defined(__has_builtin)
+#if __has_builtin(__builtin_available)
+#define HAVE_BUILTIN_AVAILABLE 1
 #endif
-#ifdef HAVE_SYS_MEMFD_H
-#  include <sys/memfd.h>
 #endif
-#ifdef HAVE_LINUX_MEMFD_H
-#  include <linux/memfd.h>
+
+#ifdef HAVE_BUILTIN_AVAILABLE
+#  define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_FCHOWNAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_LINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_FDOPENDIR_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_MKDIRAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_RENAMEAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_UNLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_OPENAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_READLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_SYMLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
+#  define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
+#  define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
+#  define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
+#  define HAVE_MKFIFOAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)
+#  define HAVE_MKNODAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)
+#  define HAVE_PTSNAME_R_RUNTIME __builtin_available(macOS 10.13.4, iOS 11.3, tvOS 11.3, watchOS 4.3, *)
+
+#  define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
+
+#else /* Xcode 8 or earlier */
+
+   /* __builtin_available is not present in these compilers, but
+    * some of the symbols might be weak linked (10.10 SDK or later
+    * deploying on 10.9.
+    *
+    * Fall back to the older style of availability checking for
+    * symbols introduced in macOS 10.10.
+    */
+
+#  ifdef HAVE_FSTATAT
+#    define HAVE_FSTATAT_RUNTIME (fstatat != NULL)
+#  endif
+
+#  ifdef HAVE_FACCESSAT
+#    define HAVE_FACCESSAT_RUNTIME (faccessat != NULL)
+#  endif
+
+#  ifdef HAVE_FCHMODAT
+#    define HAVE_FCHMODAT_RUNTIME (fchmodat != NULL)
+#  endif
+
+#  ifdef HAVE_FCHOWNAT
+#    define HAVE_FCHOWNAT_RUNTIME (fchownat != NULL)
+#  endif
+
+#  ifdef HAVE_LINKAT
+#    define HAVE_LINKAT_RUNTIME (linkat != NULL)
+#  endif
+
+#  ifdef HAVE_FDOPENDIR
+#    define HAVE_FDOPENDIR_RUNTIME (fdopendir != NULL)
+#  endif
+
+#  ifdef HAVE_MKDIRAT
+#    define HAVE_MKDIRAT_RUNTIME (mkdirat != NULL)
+#  endif
+
+#  ifdef HAVE_RENAMEAT
+#    define HAVE_RENAMEAT_RUNTIME (renameat != NULL)
+#  endif
+
+#  ifdef HAVE_UNLINKAT
+#    define HAVE_UNLINKAT_RUNTIME (unlinkat != NULL)
+#  endif
+
+#  ifdef HAVE_OPENAT
+#    define HAVE_OPENAT_RUNTIME (openat != NULL)
+#  endif
+
+#  ifdef HAVE_READLINKAT
+#    define HAVE_READLINKAT_RUNTIME (readlinkat != NULL)
+#  endif
+
+#  ifdef HAVE_SYMLINKAT
+#    define HAVE_SYMLINKAT_RUNTIME (symlinkat != NULL)
+#  endif
+
+#  ifdef HAVE_UTIMENSAT
+#    define HAVE_UTIMENSAT_RUNTIME (utimensat != NULL)
+#  endif
+
+#  ifdef HAVE_FUTIMENS
+#    define HAVE_FUTIMENS_RUNTIME (futimens != NULL)
+#  endif
+
+#  ifdef HAVE_PWRITEV
+#    define HAVE_PWRITEV_RUNTIME (pwritev != NULL)
+#  endif
+
+#  ifdef HAVE_MKFIFOAT
+#    define HAVE_MKFIFOAT_RUNTIME (mkfifoat != NULL)
+#  endif
+
+#  ifdef HAVE_MKNODAT
+#    define HAVE_MKNODAT_RUNTIME (mknodat != NULL)
+#  endif
+
+#  ifdef HAVE_PTSNAME_R
+#    define HAVE_PTSNAME_R_RUNTIME (ptsname_r != NULL)
+#  endif
+
 #endif
 
-/* eventfd() */
-#ifdef HAVE_SYS_EVENTFD_H
-#  include <sys/eventfd.h>
+#ifdef HAVE_FUTIMESAT
+/* Some of the logic for weak linking depends on this assertion */
+# error "HAVE_FUTIMESAT unexpectedly defined"
 #endif
 
-/* timerfd_create() */
-#ifdef HAVE_SYS_TIMERFD_H
-#  include <sys/timerfd.h>
+#else
+#  define HAVE_FSTATAT_RUNTIME 1
+#  define HAVE_FACCESSAT_RUNTIME 1
+#  define HAVE_FCHMODAT_RUNTIME 1
+#  define HAVE_FCHOWNAT_RUNTIME 1
+#  define HAVE_LINKAT_RUNTIME 1
+#  define HAVE_FDOPENDIR_RUNTIME 1
+#  define HAVE_MKDIRAT_RUNTIME 1
+#  define HAVE_RENAMEAT_RUNTIME 1
+#  define HAVE_UNLINKAT_RUNTIME 1
+#  define HAVE_OPENAT_RUNTIME 1
+#  define HAVE_READLINKAT_RUNTIME 1
+#  define HAVE_SYMLINKAT_RUNTIME 1
+#  define HAVE_FUTIMENS_RUNTIME 1
+#  define HAVE_UTIMENSAT_RUNTIME 1
+#  define HAVE_PWRITEV_RUNTIME 1
+#  define HAVE_MKFIFOAT_RUNTIME 1
+#  define HAVE_MKNODAT_RUNTIME 1
+#  define HAVE_PTSNAME_R_RUNTIME 1
 #endif
 
-#ifdef _Py_MEMORY_SANITIZER
-#  include <sanitizer/msan_interface.h>
+
+// --- os module ------------------------------------------------------------
+
+#ifdef MS_WINDOWS
+#  define INITFUNC PyInit_nt
+#  define MODNAME "nt"
+#  define MODNAME_OBJ &_Py_ID(nt)
+#else
+#  define INITFUNC PyInit_posix
+#  define MODNAME "posix"
+#  define MODNAME_OBJ &_Py_ID(posix)
 #endif
 
+/*[clinic input]
+# one of the few times we lie about this name!
+module os
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
+
+PyDoc_STRVAR(posix__doc__,
+"This module provides access to operating system functionality that is\n\
+standardized by the C Standard and the POSIX standard (a thinly\n\
+disguised Unix interface).  Refer to the library manual and\n\
+corresponding Unix manual entries for more information on calls.");
+
+
+// --- Functions ------------------------------------------------------------
+
 #ifdef HAVE_FORK
 static void
 run_at_forkers(PyObject *lst, int reverse)