Skip to content

Commit b9817d7

Browse files
committed
Check the errno with != 0 in close impls
1 parent 4507d49 commit b9817d7

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

Lib/test/test_devpoll.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Initial tests are copied as is from "test_poll.py"
44

5+
import errno
56
import os
67
import random
78
import select
@@ -112,6 +113,15 @@ def test_close(self):
112113
self.assertRaises(ValueError, devpoll.register, fd, select.POLLIN)
113114
self.assertRaises(ValueError, devpoll.unregister, fd)
114115

116+
def test_close_error(self):
117+
# gh-146205: close() should raise OSError if underlying fd is invalid
118+
devpoll = select.devpoll()
119+
fd = devpoll.fileno()
120+
os.close(fd)
121+
with self.assertRaises(OSError) as cm:
122+
devpoll.close()
123+
self.assertEqual(cm.exception.errno, errno.EBADF)
124+
115125
def test_fd_non_inheritable(self):
116126
devpoll = select.devpoll()
117127
self.addCleanup(devpoll.close)

Lib/test/test_epoll.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,15 @@ def test_close(self):
259259
self.assertRaises(ValueError, epoll.register, fd, select.EPOLLIN)
260260
self.assertRaises(ValueError, epoll.unregister, fd)
261261

262+
def test_close_error(self):
263+
# gh-146205: close() should raise OSError if underlying fd is invalid
264+
epoll = select.epoll()
265+
fd = epoll.fileno()
266+
os.close(fd)
267+
with self.assertRaises(OSError) as cm:
268+
epoll.close()
269+
self.assertEqual(cm.exception.errno, errno.EBADF)
270+
262271
def test_fd_non_inheritable(self):
263272
epoll = select.epoll()
264273
self.addCleanup(epoll.close)

Lib/test/test_kqueue.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,15 @@ def test_close(self):
254254
# operations must fail with ValueError("I/O operation on closed ...")
255255
self.assertRaises(ValueError, kqueue.control, None, 4)
256256

257+
def test_close_error(self):
258+
# gh-146205: close() should raise OSError if underlying fd is invalid
259+
kqueue = select.kqueue()
260+
fd = kqueue.fileno()
261+
os.close(fd)
262+
with self.assertRaises(OSError) as cm:
263+
kqueue.close()
264+
self.assertEqual(cm.exception.errno, errno.EBADF)
265+
257266
def test_fd_non_inheritable(self):
258267
kqueue = select.kqueue()
259268
self.addCleanup(kqueue.close)

Modules/selectmodule.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,8 +1118,9 @@ static PyObject *
11181118
select_devpoll_close_impl(devpollObject *self)
11191119
/*[clinic end generated code: output=26b355bd6429f21b input=408fde21a377ccfb]*/
11201120
{
1121-
errno = devpoll_internal_close(self);
1122-
if (errno < 0) {
1121+
int err = devpoll_internal_close(self);
1122+
if (err != 0) {
1123+
errno = err;
11231124
PyErr_SetFromErrno(PyExc_OSError);
11241125
return NULL;
11251126
}
@@ -1446,8 +1447,9 @@ static PyObject *
14461447
select_epoll_close_impl(pyEpoll_Object *self)
14471448
/*[clinic end generated code: output=ee2144c446a1a435 input=f626a769192e1dbe]*/
14481449
{
1449-
errno = pyepoll_internal_close(self);
1450-
if (errno < 0) {
1450+
int err = pyepoll_internal_close(self);
1451+
if (err != 0) {
1452+
errno = err;
14511453
PyErr_SetFromErrno(PyExc_OSError);
14521454
return NULL;
14531455
}
@@ -2263,8 +2265,9 @@ static PyObject *
22632265
select_kqueue_close_impl(kqueue_queue_Object *self)
22642266
/*[clinic end generated code: output=d1c7df0b407a4bc1 input=6d763c858b17b690]*/
22652267
{
2266-
errno = kqueue_queue_internal_close(self);
2267-
if (errno < 0) {
2268+
int err = kqueue_queue_internal_close(self);
2269+
if (err != 0) {
2270+
errno = err;
22682271
PyErr_SetFromErrno(PyExc_OSError);
22692272
return NULL;
22702273
}

0 commit comments

Comments
 (0)