From 9f6df8ca9a3c56c312eb1439f11182ef261f711d Mon Sep 17 00:00:00 2001 From: Alexey Izbyshev Date: Sat, 4 Mar 2023 17:24:08 +0300 Subject: [PATCH 1/2] gh-102179: Fix `os.dup2` error reporting for negative fds (GH-102180) (cherry picked from commit c2bd55d26f8eb2850eb9f9026b5d7f0ed1420b65) Co-authored-by: Alexey Izbyshev --- Lib/test/test_os.py | 20 +++++++++++++++++++ ...-02-23-15-06-01.gh-issue-102179.P6KQ4c.rst | 1 + Modules/posixmodule.c | 5 ----- 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-02-23-15-06-01.gh-issue-102179.P6KQ4c.rst diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 1243b575dcafd1..258d1cfa8438e2 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2143,6 +2143,26 @@ def test_closerange(self): def test_dup2(self): self.check(os.dup2, 20) + @unittest.skipUnless(hasattr(os, 'dup2'), 'test needs os.dup2()') + @unittest.skipIf( + support.is_emscripten, + "dup2() with negative fds is broken on Emscripten (see gh-102179)" + ) + def test_dup2_negative_fd(self): + valid_fd = os.open(__file__, os.O_RDONLY) + self.addCleanup(os.close, valid_fd) + fds = [ + valid_fd, + -1, + -2**31, + ] + for fd, fd2 in itertools.product(fds, repeat=2): + if fd != fd2: + with self.subTest(fd=fd, fd2=fd2): + with self.assertRaises(OSError) as ctx: + os.dup2(fd, fd2) + self.assertEqual(ctx.exception.errno, errno.EBADF) + @unittest.skipUnless(hasattr(os, 'fchmod'), 'test needs os.fchmod()') def test_fchmod(self): self.check(os.fchmod, 0) diff --git a/Misc/NEWS.d/next/Library/2023-02-23-15-06-01.gh-issue-102179.P6KQ4c.rst b/Misc/NEWS.d/next/Library/2023-02-23-15-06-01.gh-issue-102179.P6KQ4c.rst new file mode 100644 index 00000000000000..f77493e267ac7e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-02-23-15-06-01.gh-issue-102179.P6KQ4c.rst @@ -0,0 +1 @@ +Fix :func:`os.dup2` error message for negative fds. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 62b81a16e80629..c0421a94c17397 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -9282,11 +9282,6 @@ os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable) static int dup3_works = -1; #endif - if (fd < 0 || fd2 < 0) { - posix_error(); - return -1; - } - /* dup2() can fail with EINTR if the target FD is already open, because it * then has to be closed. See os_close_impl() for why we don't handle EINTR * upon close(), and therefore below. From cd74b02bb1dc939178f879e135b0d43acaad54c8 Mon Sep 17 00:00:00 2001 From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Sat, 4 Mar 2023 20:32:57 +0530 Subject: [PATCH 2/2] Update test_os.py --- Lib/test/test_os.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 258d1cfa8438e2..6b443c48f8fcb5 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2144,10 +2144,6 @@ def test_dup2(self): self.check(os.dup2, 20) @unittest.skipUnless(hasattr(os, 'dup2'), 'test needs os.dup2()') - @unittest.skipIf( - support.is_emscripten, - "dup2() with negative fds is broken on Emscripten (see gh-102179)" - ) def test_dup2_negative_fd(self): valid_fd = os.open(__file__, os.O_RDONLY) self.addCleanup(os.close, valid_fd)