Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 57ddf78

Browse files
committed
Issue #20113: os.readv() and os.writev() now raise an OSError exception on
error instead of returning -1.
1 parent 2bcbc14 commit 57ddf78

4 files changed

Lines changed: 36 additions & 10 deletions

File tree

Lib/test/test_os.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,11 @@ def test_lseek(self):
12271227
def test_read(self):
12281228
self.check(os.read, 1)
12291229

1230+
@unittest.skipUnless(hasattr(os, 'readv'), 'test needs os.readv()')
1231+
def test_readv(self):
1232+
buf = bytearray(10)
1233+
self.check(os.readv, [buf])
1234+
12301235
@unittest.skipUnless(hasattr(os, 'tcsetpgrp'), 'test needs os.tcsetpgrp()')
12311236
def test_tcsetpgrpt(self):
12321237
self.check(os.tcsetpgrp, 0)
@@ -1235,6 +1240,10 @@ def test_tcsetpgrpt(self):
12351240
def test_write(self):
12361241
self.check(os.write, b" ")
12371242

1243+
@unittest.skipUnless(hasattr(os, 'writev'), 'test needs os.writev()')
1244+
def test_writev(self):
1245+
self.check(os.writev, [b'abc'])
1246+
12381247

12391248
class LinkTests(unittest.TestCase):
12401249
def setUp(self):

Lib/test/test_posix.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,14 @@ def test_utime_nofollow_symlinks(self):
283283
def test_writev(self):
284284
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
285285
try:
286-
os.writev(fd, (b'test1', b'tt2', b't3'))
286+
n = os.writev(fd, (b'test1', b'tt2', b't3'))
287+
self.assertEqual(n, 10)
288+
287289
os.lseek(fd, 0, os.SEEK_SET)
288290
self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
291+
292+
# Issue #20113: empty list of buffers should not crash
293+
self.assertEqual(posix.writev(fd, []), 0)
289294
finally:
290295
os.close(fd)
291296

@@ -298,6 +303,9 @@ def test_readv(self):
298303
buf = [bytearray(i) for i in [5, 3, 2]]
299304
self.assertEqual(posix.readv(fd, buf), 10)
300305
self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
306+
307+
# Issue #20113: empty list of buffers should not crash
308+
self.assertEqual(posix.readv(fd, []), 0)
301309
finally:
302310
os.close(fd)
303311

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ Core and Builtins
3636
Library
3737
-------
3838

39+
- Issue #20113: os.readv() and os.writev() now raise an OSError exception on
40+
error instead of returning -1.
41+
3942
- Issue #20072: Fixed multiple errors in tkinter with wantobjects is False.
4043

4144
- Issue #20108: Avoid parameter name clash in inspect.getcallargs().

Modules/posixmodule.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8050,14 +8050,14 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
80508050
*iov = PyMem_New(struct iovec, cnt);
80518051
if (*iov == NULL) {
80528052
PyErr_NoMemory();
8053-
return total;
8053+
return -1;
80548054
}
80558055

80568056
*buf = PyMem_New(Py_buffer, cnt);
80578057
if (*buf == NULL) {
80588058
PyMem_Del(*iov);
80598059
PyErr_NoMemory();
8060-
return total;
8060+
return -1;
80618061
}
80628062

80638063
for (i = 0; i < cnt; i++) {
@@ -8082,7 +8082,7 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
80828082
PyBuffer_Release(&(*buf)[j]);
80838083
}
80848084
PyMem_Del(*buf);
8085-
return 0;
8085+
return -1;
80868086
}
80878087

80888088
static void
@@ -8122,14 +8122,17 @@ posix_readv(PyObject *self, PyObject *args)
81228122
}
81238123
cnt = PySequence_Size(seq);
81248124

8125-
if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
8125+
if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
81268126
return NULL;
81278127

81288128
Py_BEGIN_ALLOW_THREADS
81298129
n = readv(fd, iov, cnt);
81308130
Py_END_ALLOW_THREADS
81318131

81328132
iov_cleanup(iov, buf, cnt);
8133+
if (n < 0)
8134+
return posix_error();
8135+
81338136
return PyLong_FromSsize_t(n);
81348137
}
81358138
#endif
@@ -8254,8 +8257,8 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
82548257
Py_ssize_t i = 0; /* Avoid uninitialized warning */
82558258
sf.hdr_cnt = PySequence_Size(headers);
82568259
if (sf.hdr_cnt > 0 &&
8257-
!(i = iov_setup(&(sf.headers), &hbuf,
8258-
headers, sf.hdr_cnt, PyBUF_SIMPLE)))
8260+
(i = iov_setup(&(sf.headers), &hbuf,
8261+
headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
82598262
return NULL;
82608263
#ifdef __APPLE__
82618264
sbytes += i;
@@ -8271,8 +8274,8 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
82718274
Py_ssize_t i = 0; /* Avoid uninitialized warning */
82728275
sf.trl_cnt = PySequence_Size(trailers);
82738276
if (sf.trl_cnt > 0 &&
8274-
!(i = iov_setup(&(sf.trailers), &tbuf,
8275-
trailers, sf.trl_cnt, PyBUF_SIMPLE)))
8277+
(i = iov_setup(&(sf.trailers), &tbuf,
8278+
trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
82768279
return NULL;
82778280
#ifdef __APPLE__
82788281
sbytes += i;
@@ -8483,7 +8486,7 @@ posix_writev(PyObject *self, PyObject *args)
84838486
}
84848487
cnt = PySequence_Size(seq);
84858488

8486-
if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8489+
if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
84878490
return NULL;
84888491
}
84898492

@@ -8492,6 +8495,9 @@ posix_writev(PyObject *self, PyObject *args)
84928495
Py_END_ALLOW_THREADS
84938496

84948497
iov_cleanup(iov, buf, cnt);
8498+
if (res < 0)
8499+
return posix_error();
8500+
84958501
return PyLong_FromSsize_t(res);
84968502
}
84978503
#endif

0 commit comments

Comments
 (0)