diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 9eba3bafae0cb6e..eac842ba6a4467f 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1479,7 +1479,7 @@ or `the MSDN `_ on Windo Return a pair of file descriptors ``(r, w)`` usable for reading and writing, respectively. - .. availability:: Unix, macOS >= 27.0, not WASI, not iOS. + .. availability:: Unix, macOS >= 27.0, iOS >= 27.0, not WASI. .. versionadded:: 3.3 diff --git a/Misc/NEWS.d/next/Library/2026-08-05-10-13-23.gh-issue-153711.9g9dVz.rst b/Misc/NEWS.d/next/Library/2026-08-05-10-13-23.gh-issue-153711.9g9dVz.rst new file mode 100644 index 000000000000000..ca825ce6917db9a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-08-05-10-13-23.gh-issue-153711.9g9dVz.rst @@ -0,0 +1,3 @@ +On iOS, add :func:`os.pipe2`, and use the syscalls :manpage:`pipe2 (2)` and +:manpage:`dup3 (2)` internally, when available at both build-time and +run-time. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 0a451b8a833e67e..f0dfb7587e36ff6 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -512,8 +512,8 @@ static const unsigned int _Py_STATX_KNOWN = (STATX_BASIC_STATS | STATX_BTIME # 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_DUP3_RUNTIME __builtin_available(macOS 27.0, *) -# define HAVE_PIPE2_RUNTIME __builtin_available(macOS 27.0, *) +# define HAVE_DUP3_RUNTIME __builtin_available(macOS 27.0, iOS 27.0, tvOS 27.0, watchOS 27.0, visionOS 27.0, *) +# define HAVE_PIPE2_RUNTIME __builtin_available(macOS 27.0, iOS 27.0, tvOS 27.0, watchOS 27.0, visionOS 27.0, *) # define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *) diff --git a/configure b/configure index 7d1003a0e0e985d..67aa776aad9f4dd 100755 --- a/configure +++ b/configure @@ -21681,13 +21681,7 @@ fi # header definition prevents usage - autoconf doesn't use the headers), or # raise an error if used at runtime. Force these symbols off. if test "$ac_sys_system" != "iOS" ; then - ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3" -if test "x$ac_cv_func_dup3" = xyes -then : - printf "%s\n" "#define HAVE_DUP3 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "getentropy" "ac_cv_func_getentropy" + ac_fn_c_check_func "$LINENO" "getentropy" "ac_cv_func_getentropy" if test "x$ac_cv_func_getentropy" = xyes then : printf "%s\n" "#define HAVE_GETENTROPY 1" >>confdefs.h @@ -21698,12 +21692,6 @@ if test "x$ac_cv_func_getgroups" = xyes then : printf "%s\n" "#define HAVE_GETGROUPS 1" >>confdefs.h -fi -ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2" -if test "x$ac_cv_func_pipe2" = xyes -then : - printf "%s\n" "#define HAVE_PIPE2 1" >>confdefs.h - fi ac_fn_c_check_func "$LINENO" "system" "ac_cv_func_system" if test "x$ac_cv_func_system" = xyes @@ -21769,6 +21757,47 @@ fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dup3" >&5 +printf %s "checking for dup3... " >&6; } +if test ${ac_cv_func_dup3+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=dup3 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_dup3=yes +else case e in #( + e) ac_cv_func_dup3=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_dup3" >&5 +printf "%s\n" "$ac_cv_func_dup3" >&6; } + if test "x$ac_cv_func_dup3" = xyes +then : + +printf "%s\n" "#define HAVE_DUP3 1" >>confdefs.h + +fi + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for link" >&5 printf %s "checking for link... " >&6; } if test ${ac_cv_func_link+y} @@ -21810,6 +21839,47 @@ fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pipe2" >&5 +printf %s "checking for pipe2... " >&6; } +if test ${ac_cv_func_pipe2+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=pipe2 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_pipe2=yes +else case e in #( + e) ac_cv_func_pipe2=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_pipe2" >&5 +printf "%s\n" "$ac_cv_func_pipe2" >&6; } + if test "x$ac_cv_func_pipe2" = xyes +then : + +printf "%s\n" "#define HAVE_PIPE2 1" >>confdefs.h + +fi + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for symlink" >&5 printf %s "checking for symlink... " >&6; } if test ${ac_cv_func_symlink+y} diff --git a/configure.ac b/configure.ac index e1d55a7a3cef901..2f3b9ab9a789ec5 100644 --- a/configure.ac +++ b/configure.ac @@ -5577,7 +5577,7 @@ fi # header definition prevents usage - autoconf doesn't use the headers), or # raise an error if used at runtime. Force these symbols off. if test "$ac_sys_system" != "iOS" ; then - AC_CHECK_FUNCS([dup3 getentropy getgroups pipe2 system]) + AC_CHECK_FUNCS([getentropy getgroups system]) fi AC_CHECK_DECL([dirfd], @@ -5590,7 +5590,9 @@ AC_CHECK_DECL([dirfd], # For some functions, having a definition is not sufficient, since # we want to take their address. PY_CHECK_FUNC([chroot], [@%:@include ]) +PY_CHECK_FUNC([dup3], [@%:@include ]) PY_CHECK_FUNC([link], [@%:@include ]) +PY_CHECK_FUNC([pipe2], [@%:@include ]) PY_CHECK_FUNC([symlink], [@%:@include ]) PY_CHECK_FUNC([fchdir], [@%:@include ]) PY_CHECK_FUNC([fsync], [@%:@include ]) diff --git a/pyconfig.h.in b/pyconfig.h.in index d1de60ad757f4da..ebc1976fd5a063c 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -392,7 +392,7 @@ /* Define to 1 if you have the 'dup2' function. */ #undef HAVE_DUP2 -/* Define to 1 if you have the 'dup3' function. */ +/* Define if you have the 'dup3' function. */ #undef HAVE_DUP3 /* Define if you have the '_dyld_shared_cache_contains_path' function. */ @@ -1052,7 +1052,7 @@ /* Define to 1 if you have the 'pipe' function. */ #undef HAVE_PIPE -/* Define to 1 if you have the 'pipe2' function. */ +/* Define if you have the 'pipe2' function. */ #undef HAVE_PIPE2 /* Define to 1 if you have the 'plock' function. */