]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-95174: Handle missing dup() and constants in WASI (GH-95229)
authorChristian Heimes <christian@python.org>
Tue, 26 Jul 2022 09:16:51 +0000 (11:16 +0200)
committerGitHub <noreply@github.com>
Tue, 26 Jul 2022 09:16:51 +0000 (11:16 +0200)
- check for ``dup()`` libc function
- handle missing ``F_DUPFD`` in ``dup2()`` replacement function
- add workaround for WASI libc bug in MSG_TRUNC
- ESHUTDOWN is missing, use EPIPE instead
- POLLPRI is missing, define as 0 (no-op)

12 files changed:
Misc/NEWS.d/next/Build/2022-07-25-08-59-35.gh-issue-95174.g8woUW.rst [new file with mode: 0644]
Modules/clinic/posixmodule.c.h
Modules/errnomodule.c
Modules/posixmodule.c
Modules/selectmodule.c
Modules/socketmodule.c
PC/pyconfig.h
Python/dup2.c
Python/fileutils.c
configure
configure.ac
pyconfig.h.in

diff --git a/Misc/NEWS.d/next/Build/2022-07-25-08-59-35.gh-issue-95174.g8woUW.rst b/Misc/NEWS.d/next/Build/2022-07-25-08-59-35.gh-issue-95174.g8woUW.rst
new file mode 100644 (file)
index 0000000..05f2995
--- /dev/null
@@ -0,0 +1,2 @@
+Python now detects missing ``dup`` function in WASI and works around some
+missing :mod:`errno`, :mod:`select`, and :mod:`socket` constants.
index 1ce7d86204e6f39544e8cc22d232996894d12564..3847349e5f6c36aa9d57505f9c96cecfb00917a3 100644 (file)
@@ -4685,6 +4685,8 @@ exit:
     return return_value;
 }
 
+#if ((defined(HAVE_DUP3) || defined(F_DUPFD) || defined(MS_WINDOWS)))
+
 PyDoc_STRVAR(os_dup2__doc__,
 "dup2($module, /, fd, fd2, inheritable=True)\n"
 "--\n"
@@ -4740,6 +4742,8 @@ exit:
     return return_value;
 }
 
+#endif /* ((defined(HAVE_DUP3) || defined(F_DUPFD) || defined(MS_WINDOWS))) */
+
 #if defined(HAVE_LOCKF)
 
 PyDoc_STRVAR(os_lockf__doc__,
@@ -9105,6 +9109,10 @@ exit:
     #define OS_TCSETPGRP_METHODDEF
 #endif /* !defined(OS_TCSETPGRP_METHODDEF) */
 
+#ifndef OS_DUP2_METHODDEF
+    #define OS_DUP2_METHODDEF
+#endif /* !defined(OS_DUP2_METHODDEF) */
+
 #ifndef OS_LOCKF_METHODDEF
     #define OS_LOCKF_METHODDEF
 #endif /* !defined(OS_LOCKF_METHODDEF) */
@@ -9352,4 +9360,4 @@ exit:
 #ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF
     #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF
 #endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */
-/*[clinic end generated code: output=bae15f09a1b3d2e7 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=9ff792e207a18392 input=a9049054013a1b77]*/
index bf6766e02349c0037beb4db84c3ab5a02da20735..0516e7367050c2f187ccf928a74233c61c7ccefd 100644 (file)
@@ -280,6 +280,10 @@ errno_exec(PyObject *module)
 #ifdef ENOANO
     add_errcode("ENOANO", ENOANO, "No anode");
 #endif
+#if defined(__wasi__) && !defined(ESHUTDOWN)
+    // WASI SDK 16 does not have ESHUTDOWN, shutdown results in EPIPE.
+    #define ESHUTDOWN EPIPE
+#endif
 #ifdef ESHUTDOWN
     add_errcode("ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown");
 #else
index 40229bce0f40339a4d64fd7067cbb553788ff709..2e89e2fb1d66cd29b6089239dc5e4bec5fc78931 100644 (file)
@@ -9316,7 +9316,9 @@ os_dup_impl(PyObject *module, int fd)
     return _Py_dup(fd);
 }
 
-
+// dup2() is either provided by libc or dup2.c with AC_REPLACE_FUNCS().
+// dup2.c provides working dup2() if and only if F_DUPFD is available.
+#if (defined(HAVE_DUP3) || defined(F_DUPFD) || defined(MS_WINDOWS))
 /*[clinic input]
 os.dup2 -> int
     fd: int
@@ -9416,6 +9418,7 @@ os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
 
     return res;
 }
+#endif
 
 
 #ifdef HAVE_LOCKF
index 5c36eaaedeb70b2d62da4e4c42b12cdc503fb85c..4eea928a2683ae6444004317188bc960b808ede2 100644 (file)
@@ -63,6 +63,11 @@ extern void bzero(void *, int);
 #  define SOCKET int
 #endif
 
+// WASI SDK 16 does not have POLLPRIO, define as no-op
+#if defined(__wasi__) && !defined(POLLPRI)
+#  define POLLPRI 0
+#endif
+
 typedef struct {
     PyObject *close;
     PyTypeObject *poll_Type;
index 9b4155e164f107daebd7cd5f44a7416ab4faf0c1..5641613452b3a45662267693861747fb693129d4 100644 (file)
@@ -7786,6 +7786,10 @@ PyInit__socket(void)
     PyModule_AddIntMacro(m, MSG_EOR);
 #endif
 #ifdef  MSG_TRUNC
+    // workaround for https://github.com/WebAssembly/wasi-libc/issues/305
+    #if defined(__wasi__) && !defined(__WASI_RIFLAGS_RECV_DATA_TRUNCATED)
+    #  define __WASI_RIFLAGS_RECV_DATA_TRUNCATED 2
+    #endif
     PyModule_AddIntMacro(m, MSG_TRUNC);
 #endif
 #ifdef  MSG_CTRUNC
index 87d55fa07e51e380d0710937834f2653b0e0ba02..1135a121fcfdd6989f6f76ce6ae46322526ab745 100644 (file)
@@ -678,6 +678,9 @@ Py_NO_ENABLE_SHARED to find out.  Also support MS_NO_COREDLL for b/w compat */
 /* Define if you have the 'inet_pton' function. */
 #define HAVE_INET_PTON 1
 
+/* Define to 1 if you have the `dup' function. */
+#define HAVE_DUP 1
+
 /* framework name */
 #define _PYTHONFRAMEWORK ""
 
index 7c6bbfce11dbf80dae7fe4c79d4c52839a0c68ad..a1df0492099163982661b996e697c708c0235783 100644 (file)
@@ -11,6 +11,7 @@
  * Return fd2 if all went well; return BADEXIT otherwise.
  */
 
+#include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 
@@ -20,12 +21,17 @@ int
 dup2(int fd1, int fd2)
 {
     if (fd1 != fd2) {
+#ifdef F_DUPFD
         if (fcntl(fd1, F_GETFL) < 0)
             return BADEXIT;
         if (fcntl(fd2, F_GETFL) >= 0)
             close(fd2);
         if (fcntl(fd1, F_DUPFD, fd2) < 0)
             return BADEXIT;
+#else
+        errno = ENOTSUP;
+        return BADEXIT;
+#endif
     }
     return fd2;
 }
index 7e5d01f6e63d3bc74aaded8609eabc4c44707615..fb1e5ef9a03026bb7b1e44659be5b79fb9c98104 100644 (file)
@@ -2366,7 +2366,7 @@ _Py_dup(int fd)
         return -1;
     }
 
-#else
+#elif HAVE_DUP
     Py_BEGIN_ALLOW_THREADS
     _Py_BEGIN_SUPPRESS_IPH
     fd = dup(fd);
@@ -2383,6 +2383,10 @@ _Py_dup(int fd)
         _Py_END_SUPPRESS_IPH
         return -1;
     }
+#else
+    errno = ENOTSUP;
+    PyErr_SetFromErrno(PyExc_OSError);
+    return -1;
 #endif
     return fd;
 }
index d607c5e5d37a03fff531d4626722702c0e56feb0..be045f2da3cebbfaf7046d89835e664963079ed9 100755 (executable)
--- a/configure
+++ b/configure
@@ -15545,7 +15545,7 @@ fi
 # checks for library functions
 for ac_func in  \
   accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
-  copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \
+  copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
   faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
   fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
   gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
index c5924169e03a0b30927ec12581d40fe3e3c8033a..a952324f4922cc16305be8eddea20f546e7e72d4 100644 (file)
@@ -4653,7 +4653,7 @@ fi
 # checks for library functions
 AC_CHECK_FUNCS([ \
   accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
-  copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \
+  copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
   faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
   fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
   gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
index aa9fc559fa2511cc507b33baa986211e430fdf1d..37f748393e739f9ea52c85d71c85b1015a8e6029 100644 (file)
 /* Define to 1 if you have the `dlopen' function. */
 #undef HAVE_DLOPEN
 
+/* Define to 1 if you have the `dup' function. */
+#undef HAVE_DUP
+
 /* Define to 1 if you have the `dup2' function. */
 #undef HAVE_DUP2