Commit 282124b8 authored by Victor Stinner's avatar Victor Stinner

Closes #22258: Fix the the internal function set_inheritable() on Illumos.

This platform exposes the function ioctl(FIOCLEX), but calling it fails with
errno is ENOTTY: "Inappropriate ioctl for device". set_inheritable() now falls
back to the slower fcntl() (F_GETFD and then F_SETFD).
parent a42ad6bf
...@@ -10,6 +10,11 @@ Release date: XXXX-XX-XX ...@@ -10,6 +10,11 @@ Release date: XXXX-XX-XX
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #22258: Fix the the internal function set_inheritable() on Illumos.
This platform exposes the function ``ioctl(FIOCLEX)``, but calling it fails
with errno is ENOTTY: "Inappropriate ioctl for device". set_inheritable()
now falls back to the slower ``fcntl()`` (``F_GETFD`` and then ``F_SETFD``).
- Issue #21669: With the aid of heuristics in SyntaxError.__init__, the - Issue #21669: With the aid of heuristics in SyntaxError.__init__, the
parser now attempts to generate more meaningful (or at least more search parser now attempts to generate more meaningful (or at least more search
engine friendly) error messages when "exec" and "print" are used as engine friendly) error messages when "exec" and "print" are used as
......
...@@ -622,10 +622,12 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) ...@@ -622,10 +622,12 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
HANDLE handle; HANDLE handle;
DWORD flags; DWORD flags;
#elif defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) #else
#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
static int ioctl_works = -1;
int request; int request;
int err; int err;
#elif defined(HAVE_FCNTL_H) #endif
int flags; int flags;
int res; int res;
#endif #endif
...@@ -671,20 +673,38 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) ...@@ -671,20 +673,38 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
} }
return 0; return 0;
#elif defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) #else
#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
if (ioctl_works != 0) {
/* fast-path: ioctl() only requires one syscall */
if (inheritable) if (inheritable)
request = FIONCLEX; request = FIONCLEX;
else else
request = FIOCLEX; request = FIOCLEX;
err = ioctl(fd, request, NULL); err = ioctl(fd, request, NULL);
if (err) { if (!err) {
ioctl_works = 1;
return 0;
}
if (errno != ENOTTY) {
if (raise) if (raise)
PyErr_SetFromErrno(PyExc_OSError); PyErr_SetFromErrno(PyExc_OSError);
return -1; return -1;
} }
return 0; else {
/* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for
device". The ioctl is declared but not supported by the kernel.
Remember that ioctl() doesn't work. It is the case on
Illumos-based OS for example. */
ioctl_works = 0;
}
/* fallback to fcntl() if ioctl() does not work */
}
#endif
#else /* slow-path: fcntl() requires two syscalls */
flags = fcntl(fd, F_GETFD); flags = fcntl(fd, F_GETFD);
if (flags < 0) { if (flags < 0) {
if (raise) if (raise)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment