mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-32849: Fix is_valid_fd() on FreeBSD (GH-12852)
Fix Python Initialization code on FreeBSD to detect properly when stdin file descriptor (fd 0) is invalid. On FreeBSD, fstat() must be used to check if stdin (fd 0) is valid. dup(0) doesn't fail if stdin is invalid in some cases.
This commit is contained in:
parent
197f0447e3
commit
3092d6b263
2 changed files with 28 additions and 18 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
Fix Python Initialization code on FreeBSD to detect properly when stdin file
|
||||||
|
descriptor (fd 0) is invalid.
|
|
@ -1664,26 +1664,34 @@ initsite(void)
|
||||||
static int
|
static int
|
||||||
is_valid_fd(int fd)
|
is_valid_fd(int fd)
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
/* dup() is faster than fstat(): fstat() can require input/output operations,
|
||||||
/* bpo-30225: On macOS Tiger, when stdout is redirected to a pipe
|
whereas dup() doesn't. There is a low risk of EMFILE/ENFILE at Python
|
||||||
and the other side of the pipe is closed, dup(1) succeed, whereas
|
startup. Problem: dup() doesn't check if the file descriptor is valid on
|
||||||
fstat(1, &st) fails with EBADF. Prefer fstat() over dup() to detect
|
some platforms.
|
||||||
such error. */
|
|
||||||
|
bpo-30225: On macOS Tiger, when stdout is redirected to a pipe and the other
|
||||||
|
side of the pipe is closed, dup(1) succeed, whereas fstat(1, &st) fails with
|
||||||
|
EBADF. FreeBSD has similar issue (bpo-32849).
|
||||||
|
|
||||||
|
Only use dup() on platforms where dup() is enough to detect invalid FD in
|
||||||
|
corner cases: on Linux and Windows (bpo-32849). */
|
||||||
|
#if defined(__linux__) || defined(MS_WINDOWS)
|
||||||
|
if (fd < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int fd2;
|
||||||
|
|
||||||
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
|
fd2 = dup(fd);
|
||||||
|
if (fd2 >= 0) {
|
||||||
|
close(fd2);
|
||||||
|
}
|
||||||
|
_Py_END_SUPPRESS_IPH
|
||||||
|
|
||||||
|
return (fd2 >= 0);
|
||||||
|
#else
|
||||||
struct stat st;
|
struct stat st;
|
||||||
return (fstat(fd, &st) == 0);
|
return (fstat(fd, &st) == 0);
|
||||||
#else
|
|
||||||
int fd2;
|
|
||||||
if (fd < 0)
|
|
||||||
return 0;
|
|
||||||
_Py_BEGIN_SUPPRESS_IPH
|
|
||||||
/* Prefer dup() over fstat(). fstat() can require input/output whereas
|
|
||||||
dup() doesn't, there is a low risk of EMFILE/ENFILE at Python
|
|
||||||
startup. */
|
|
||||||
fd2 = dup(fd);
|
|
||||||
if (fd2 >= 0)
|
|
||||||
close(fd2);
|
|
||||||
_Py_END_SUPPRESS_IPH
|
|
||||||
return fd2 >= 0;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue