Skip to content

Commit 411107d

Browse files
author
Alexey Izbyshev
committed
pythongh-102179: Fix os.dup2() error reporting for negative fds
A remnant of old code manually checks the sign of fds, but doesn't set errno before raising OSError: ``` >>> os.dup2(-1, 0) Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 0] Error ``` Remove the manual check altogether: the C library functions used to implement os.dup2() check fd validity anyway.
1 parent 5b9573e commit 411107d

File tree

3 files changed

+17
-5
lines changed

3 files changed

+17
-5
lines changed

Lib/test/test_os.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2221,6 +2221,22 @@ def test_closerange(self):
22212221
def test_dup2(self):
22222222
self.check(os.dup2, 20)
22232223

2224+
@unittest.skipUnless(hasattr(os, 'dup2'), 'test needs os.dup2()')
2225+
def test_dup2_negative_fd(self):
2226+
valid_fd = os.open(__file__, os.O_RDONLY)
2227+
self.addCleanup(os.close, valid_fd)
2228+
fds = [
2229+
valid_fd,
2230+
-1,
2231+
-2**31,
2232+
]
2233+
for fd, fd2 in itertools.product(fds, repeat=2):
2234+
if fd != fd2:
2235+
with self.subTest(fd=fd, fd2=fd2):
2236+
with self.assertRaises(OSError) as ctx:
2237+
os.dup2(fd, fd2)
2238+
self.assertEqual(ctx.exception.errno, errno.EBADF)
2239+
22242240
@unittest.skipUnless(hasattr(os, 'fchmod'), 'test needs os.fchmod()')
22252241
def test_fchmod(self):
22262242
self.check(os.fchmod, 0)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix ``os.dup2()`` error reporting for negative fds.

Modules/posixmodule.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9829,11 +9829,6 @@ os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
98299829
static int dup3_works = -1;
98309830
#endif
98319831

9832-
if (fd < 0 || fd2 < 0) {
9833-
posix_error();
9834-
return -1;
9835-
}
9836-
98379832
/* dup2() can fail with EINTR if the target FD is already open, because it
98389833
* then has to be closed. See os_close_impl() for why we don't handle EINTR
98399834
* upon close(), and therefore below.

0 commit comments

Comments
 (0)