mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-118422: Fix run_fileexflags() test (#118429)
Don't test the undefined behavior of fileno() on a closed file, but use fstat() as a reliable test if the file was closed or not.
This commit is contained in:
parent
587388ff22
commit
e93c39b47e
4 changed files with 62 additions and 58 deletions
|
@ -3050,3 +3050,52 @@ _Py_GetTicksPerSecond(long *ticks_per_second)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Check if a file descriptor is valid or not.
|
||||
Return 0 if the file descriptor is invalid, return non-zero otherwise. */
|
||||
int
|
||||
_Py_IsValidFD(int fd)
|
||||
{
|
||||
/* dup() is faster than fstat(): fstat() can require input/output operations,
|
||||
whereas dup() doesn't. There is a low risk of EMFILE/ENFILE at Python
|
||||
startup. Problem: dup() doesn't check if the file descriptor is valid on
|
||||
some platforms.
|
||||
|
||||
fcntl(fd, F_GETFD) is even faster, because it only checks the process table.
|
||||
It is preferred over dup() when available, since it cannot fail with the
|
||||
"too many open files" error (EMFILE).
|
||||
|
||||
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 Linux where dup() is enough to detect invalid FD
|
||||
(bpo-32849).
|
||||
*/
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
#if defined(F_GETFD) && ( \
|
||||
defined(__linux__) || \
|
||||
defined(__APPLE__) || \
|
||||
(defined(__wasm__) && !defined(__wasi__)))
|
||||
return fcntl(fd, F_GETFD) >= 0;
|
||||
#elif defined(__linux__)
|
||||
int fd2 = dup(fd);
|
||||
if (fd2 >= 0) {
|
||||
close(fd2);
|
||||
}
|
||||
return (fd2 >= 0);
|
||||
#elif defined(MS_WINDOWS)
|
||||
HANDLE hfile;
|
||||
_Py_BEGIN_SUPPRESS_IPH
|
||||
hfile = (HANDLE)_get_osfhandle(fd);
|
||||
_Py_END_SUPPRESS_IPH
|
||||
return (hfile != INVALID_HANDLE_VALUE
|
||||
&& GetFileType(hfile) != FILE_TYPE_UNKNOWN);
|
||||
#else
|
||||
struct stat st;
|
||||
return (fstat(fd, &st) == 0);
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue