This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Use fcntl(fd, F_GETFD) to check whether an fd is valid
Type: behavior Stage: patch review
Components: C API Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: christian.heimes, corona10, eryksun, vstinner
Priority: normal Keywords: patch

Created on 2021-11-28 10:13 by christian.heimes, last changed 2022-04-11 14:59 by admin.

Pull Requests
URL Status Linked Edit
PR 29821 open christian.heimes, 2021-11-28 10:28
PR 30082 corona10, 2021-12-13 13:19
Messages (5)
msg407197 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2021-11-28 10:13
is_valid_fd() uses dup() or fstat() to check whether an fd is valid. Both operations are costly. 

fcntl() with F_GETFD returns the file descriptor flags (e.g. CLOEXEC) and -1 with errno set to EBADF when fd is not an open file descriptor. It's faster than duplicating + closing a fd or calling fstat(). The idea to use fcntl(fd, F_GETFD) is inspired by the patch [1]. According to Stackoverflow [2]:

> fcntl(fd, F_GETFD) is the canonical cheapest way to check that fd is a valid open file descriptor.
> F_GETFD is cheaper in principle since it only dereferences the (process-local) file descriptor in kernel space, not the underlying open file description (process-shared) which it refers to.

[1] https://github.com/singlestore-labs/cpython/commit/0364554615c79b9364a0acf3038147a999ea2219

[2] https://stackoverflow.com/questions/12340695/how-to-check-if-a-given-file-descriptor-stored-in-a-variable-is-still-valid
msg407217 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2021-11-28 18:40
New changeset f87ea0350286837e9e96de03f8bfa215176c2928 by Christian Heimes in branch 'main':
bpo-45915: use fcntl(fd, F_GETFD) in is_valid_fd() (GH-29821)
https://github.com/python/cpython/commit/f87ea0350286837e9e96de03f8bfa215176c2928
msg407222 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2021-11-28 19:25
I've created bpo-45919 with a suggested enhancement to use GetFileType() in Windows, since the Windows C runtime does not provide fcntl().
msg407224 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2021-11-28 19:31
Thank you!
msg408514 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2021-12-14 03:31
PR 29821 adds __APPLE__ to the platforms that use fcntl(fd, F_GETFD). Is this okay on macOS, given bpo-30225? Apparently fstat() fails if the other end of a pipe is closed.
History
Date User Action Args
2022-04-11 14:59:52adminsetgithub: 90073
2021-12-14 03:31:17eryksunsetmessages: + msg408514
2021-12-13 13:19:42corona10setnosy: + corona10
pull_requests: + pull_request28311
2021-11-28 19:31:12christian.heimessetmessages: + msg407224
2021-11-28 19:25:09eryksunsetmessages: + msg407222
2021-11-28 19:23:14eryksunsetmessages: - msg407216
2021-11-28 18:40:39christian.heimessetmessages: + msg407217
2021-11-28 18:25:34eryksunsetnosy: + eryksun
messages: + msg407216
2021-11-28 10:28:50christian.heimessetkeywords: + patch
stage: patch review
pull_requests: + pull_request28053
2021-11-28 10:13:06christian.heimescreate