Skip to content

Commit

Permalink
pythongh-95174: Handle missing dup() and constants in WASI (pythonGH-…
Browse files Browse the repository at this point in the history
…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)
  • Loading branch information
tiran committed Jul 26, 2022
1 parent e8f3e8f commit 0d35a59
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -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.
10 changes: 9 additions & 1 deletion Modules/clinic/posixmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Modules/errnomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -9416,6 +9418,7 @@ os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)

return res;
}
#endif


#ifdef HAVE_LOCKF
Expand Down
5 changes: 5 additions & 0 deletions Modules/selectmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions Modules/socketmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions PC/pyconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""

Expand Down
6 changes: 6 additions & 0 deletions Python/dup2.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Return fd2 if all went well; return BADEXIT otherwise.
*/

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

Expand All @@ -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;
}
6 changes: 5 additions & 1 deletion Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
3 changes: 3 additions & 0 deletions pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 0d35a59

Please sign in to comment.