@@ -504,6 +504,8 @@ static const unsigned int _Py_STATX_KNOWN = (STATX_BASIC_STATS | STATX_BTIME
504504# define HAVE_MKFIFOAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)
505505# define HAVE_MKNODAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)
506506# define HAVE_PTSNAME_R_RUNTIME __builtin_available(macOS 10.13.4, iOS 11.3, tvOS 11.3, watchOS 4.3, *)
507+ # define HAVE_DUP3_RUNTIME __builtin_available(macOS 27.0, iOS 27.0, tvOS 27.0, watchOS 27.0, *)
508+ # define HAVE_PIPE2_RUNTIME __builtin_available(macOS 27.0, iOS 27.0, tvOS 27.0, watchOS 27.0, *)
507509
508510# define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
509511
@@ -589,6 +591,14 @@ static const unsigned int _Py_STATX_KNOWN = (STATX_BASIC_STATS | STATX_BTIME
589591# define HAVE_PTSNAME_R_RUNTIME (ptsname_r != NULL)
590592# endif
591593
594+ # ifdef HAVE_DUP3
595+ # define HAVE_DUP3_RUNTIME (dup3 != NULL)
596+ # endif
597+
598+ # ifdef HAVE_PIPE2
599+ # define HAVE_PIPE2_RUNTIME (pipe2 != NULL)
600+ # endif
601+
592602#endif
593603
594604#ifdef HAVE_FUTIMESAT
@@ -619,6 +629,8 @@ static const unsigned int _Py_STATX_KNOWN = (STATX_BASIC_STATS | STATX_BTIME
619629# define HAVE_MKFIFOAT_RUNTIME 1
620630# define HAVE_MKNODAT_RUNTIME 1
621631# define HAVE_PTSNAME_R_RUNTIME 1
632+ # define HAVE_DUP3_RUNTIME 1
633+ # define HAVE_PIPE2_RUNTIME 1
622634#endif
623635
624636
@@ -11910,17 +11922,22 @@ os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
1191011922
1191111923#ifdef HAVE_DUP3
1191211924 if (!inheritable && dup3_works != 0) {
11913- Py_BEGIN_ALLOW_THREADS
11914- res = dup3(fd, fd2, O_CLOEXEC);
11915- Py_END_ALLOW_THREADS
11916- if (res < 0) {
11917- if (dup3_works == -1)
11918- dup3_works = (errno != ENOSYS);
11919- if (dup3_works) {
11920- posix_error();
11921- return -1;
11925+ if (HAVE_DUP3_RUNTIME) {
11926+ Py_BEGIN_ALLOW_THREADS
11927+ res = dup3(fd, fd2, O_CLOEXEC);
11928+ Py_END_ALLOW_THREADS
11929+ if (res < 0) {
11930+ if (dup3_works == -1)
11931+ dup3_works = (errno != ENOSYS);
11932+ if (dup3_works) {
11933+ posix_error();
11934+ return -1;
11935+ }
1192211936 }
1192311937 }
11938+ else {
11939+ dup3_works = 0;
11940+ }
1192411941 }
1192511942
1192611943 if (inheritable || dup3_works == 0)
@@ -12779,9 +12796,13 @@ os_pipe_impl(PyObject *module)
1277912796#else
1278012797
1278112798#ifdef HAVE_PIPE2
12782- Py_BEGIN_ALLOW_THREADS
12783- res = pipe2(fds, O_CLOEXEC);
12784- Py_END_ALLOW_THREADS
12799+ res = -1;
12800+ errno = ENOSYS;
12801+ if (HAVE_PIPE2_RUNTIME) {
12802+ Py_BEGIN_ALLOW_THREADS
12803+ res = pipe2(fds, O_CLOEXEC);
12804+ Py_END_ALLOW_THREADS
12805+ }
1278512806
1278612807 if (res != 0 && errno == ENOSYS)
1278712808 {
@@ -18811,6 +18832,18 @@ posixmodule_exec(PyObject *m)
1881118832 }
1881218833#endif
1881318834
18835+ #if defined(HAVE_PIPE2)
18836+ if (HAVE_PIPE2_RUNTIME) {} else {
18837+ PyObject *dct = PyModule_GetDict(m);
18838+ if (dct == NULL) {
18839+ return -1;
18840+ }
18841+ if (PyDict_PopString(dct, "pipe2", NULL) < 0) {
18842+ return -1;
18843+ }
18844+ }
18845+ #endif
18846+
1881418847#ifdef HAVE_STATX
1881518848 if (statx == NULL) {
1881618849 PyObject* dct = PyModule_GetDict(m);
0 commit comments