[Python-checkins] gh-95174: Handle missing dup() and constants in WASI (GH-95229)
tiran
webhook-mailer at python.org
Tue Jul 26 05:16:56 EDT 2022
https://github.com/python/cpython/commit/0d35a59ce3242b7326890a8c8cc41b321192ec9a
commit: 0d35a59ce3242b7326890a8c8cc41b321192ec9a
branch: main
author: Christian Heimes <christian at python.org>
committer: tiran <christian at python.org>
date: 2022-07-26T11:16:51+02:00
summary:
gh-95174: Handle missing dup() and constants in WASI (GH-95229)
- 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)
files:
A Misc/NEWS.d/next/Build/2022-07-25-08-59-35.gh-issue-95174.g8woUW.rst
M Modules/clinic/posixmodule.c.h
M Modules/errnomodule.c
M Modules/posixmodule.c
M Modules/selectmodule.c
M Modules/socketmodule.c
M PC/pyconfig.h
M Python/dup2.c
M Python/fileutils.c
M configure
M configure.ac
M 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
index 0000000000000..05f29955072c5
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2022-07-25-08-59-35.gh-issue-95174.g8woUW.rst
@@ -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.
diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h
index 1ce7d86204e6f..3847349e5f6c3 100644
--- a/Modules/clinic/posixmodule.c.h
+++ b/Modules/clinic/posixmodule.c.h
@@ -4685,6 +4685,8 @@ os_dup(PyObject *module, PyObject *arg)
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 @@ os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn
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 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na
#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 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na
#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]*/
diff --git a/Modules/errnomodule.c b/Modules/errnomodule.c
index bf6766e02349c..0516e7367050c 100644
--- a/Modules/errnomodule.c
+++ b/Modules/errnomodule.c
@@ -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
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 40229bce0f403..2e89e2fb1d66c 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -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
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 5c36eaaedeb70..4eea928a2683a 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -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;
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 9b4155e164f10..5641613452b3a 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -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
diff --git a/PC/pyconfig.h b/PC/pyconfig.h
index 87d55fa07e51e..1135a121fcfdd 100644
--- a/PC/pyconfig.h
+++ b/PC/pyconfig.h
@@ -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 ""
diff --git a/Python/dup2.c b/Python/dup2.c
index 7c6bbfce11dbf..a1df049209916 100644
--- a/Python/dup2.c
+++ b/Python/dup2.c
@@ -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;
}
diff --git a/Python/fileutils.c b/Python/fileutils.c
index 7e5d01f6e63d3..fb1e5ef9a0302 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -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;
}
diff --git a/configure b/configure
index d607c5e5d37a0..be045f2da3ceb 100755
--- 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 \
diff --git a/configure.ac b/configure.ac
index c5924169e03a0..a952324f4922c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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 \
diff --git a/pyconfig.h.in b/pyconfig.h.in
index aa9fc559fa251..37f748393e739 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -278,6 +278,9 @@
/* 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
More information about the Python-checkins
mailing list