]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #20113: os.readv() and os.writev() now raise an OSError exception on
authorVictor Stinner <victor.stinner@gmail.com>
Wed, 8 Jan 2014 14:21:28 +0000 (15:21 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Wed, 8 Jan 2014 14:21:28 +0000 (15:21 +0100)
error instead of returning -1.

Lib/test/test_os.py
Lib/test/test_posix.py
Misc/NEWS
Modules/posixmodule.c

index b5bfe9433bb47c0bb9cb60d02646ac947dba3631..d70a0aeaf84a92d17cb4869d21cfa2cd399ad69b 100644 (file)
@@ -1227,6 +1227,11 @@ class TestInvalidFD(unittest.TestCase):
     def test_read(self):
         self.check(os.read, 1)
 
+    @unittest.skipUnless(hasattr(os, 'readv'), 'test needs os.readv()')
+    def test_readv(self):
+        buf = bytearray(10)
+        self.check(os.readv, [buf])
+
     @unittest.skipUnless(hasattr(os, 'tcsetpgrp'), 'test needs os.tcsetpgrp()')
     def test_tcsetpgrpt(self):
         self.check(os.tcsetpgrp, 0)
@@ -1235,6 +1240,10 @@ class TestInvalidFD(unittest.TestCase):
     def test_write(self):
         self.check(os.write, b" ")
 
+    @unittest.skipUnless(hasattr(os, 'writev'), 'test needs os.writev()')
+    def test_writev(self):
+        self.check(os.writev, [b'abc'])
+
 
 class LinkTests(unittest.TestCase):
     def setUp(self):
index 02bb6acb8296c9b2f89026e3601c6520c1eee26a..5e680c922b9a441a9300f7e3e9714af991be9208 100644 (file)
@@ -283,9 +283,14 @@ class PosixTester(unittest.TestCase):
     def test_writev(self):
         fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
         try:
-            os.writev(fd, (b'test1', b'tt2', b't3'))
+            n = os.writev(fd, (b'test1', b'tt2', b't3'))
+            self.assertEqual(n, 10)
+
             os.lseek(fd, 0, os.SEEK_SET)
             self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
+
+            # Issue #20113: empty list of buffers should not crash
+            self.assertEqual(posix.writev(fd, []), 0)
         finally:
             os.close(fd)
 
@@ -298,6 +303,9 @@ class PosixTester(unittest.TestCase):
             buf = [bytearray(i) for i in [5, 3, 2]]
             self.assertEqual(posix.readv(fd, buf), 10)
             self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
+
+            # Issue #20113: empty list of buffers should not crash
+            self.assertEqual(posix.readv(fd, []), 0)
         finally:
             os.close(fd)
 
index c17e493f76f8889011f2fbcd808b6772ea108b70..1306891d2a06e174ab288f776941a495318d93c4 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -36,6 +36,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #20113: os.readv() and os.writev() now raise an OSError exception on
+  error instead of returning -1.
+
 - Issue #20072: Fixed multiple errors in tkinter with wantobjects is False.
 
 - Issue #20108: Avoid parameter name clash in inspect.getcallargs().
index f97d70beb931ebef55d4cfefa7cfa029901db00b..c00ca203c5b02e856b6ced5e465bdd4c6c30e57a 100644 (file)
@@ -8050,14 +8050,14 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
     *iov = PyMem_New(struct iovec, cnt);
     if (*iov == NULL) {
         PyErr_NoMemory();
-        return total;
+        return -1;
     }
 
     *buf = PyMem_New(Py_buffer, cnt);
     if (*buf == NULL) {
         PyMem_Del(*iov);
         PyErr_NoMemory();
-        return total;
+        return -1;
     }
 
     for (i = 0; i < cnt; i++) {
@@ -8082,7 +8082,7 @@ fail:
         PyBuffer_Release(&(*buf)[j]);
     }
     PyMem_Del(*buf);
-    return 0;
+    return -1;
 }
 
 static void
@@ -8122,7 +8122,7 @@ posix_readv(PyObject *self, PyObject *args)
     }
     cnt = PySequence_Size(seq);
 
-    if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
+    if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -8130,6 +8130,9 @@ posix_readv(PyObject *self, PyObject *args)
     Py_END_ALLOW_THREADS
 
     iov_cleanup(iov, buf, cnt);
+    if (n < 0)
+        return posix_error();
+
     return PyLong_FromSsize_t(n);
 }
 #endif
@@ -8254,8 +8257,8 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
             Py_ssize_t i = 0; /* Avoid uninitialized warning */
             sf.hdr_cnt = PySequence_Size(headers);
             if (sf.hdr_cnt > 0 &&
-                !(i = iov_setup(&(sf.headers), &hbuf,
-                                headers, sf.hdr_cnt, PyBUF_SIMPLE)))
+                (i = iov_setup(&(sf.headers), &hbuf,
+                                headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
                 return NULL;
 #ifdef __APPLE__
             sbytes += i;
@@ -8271,8 +8274,8 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
             Py_ssize_t i = 0; /* Avoid uninitialized warning */
             sf.trl_cnt = PySequence_Size(trailers);
             if (sf.trl_cnt > 0 &&
-                !(i = iov_setup(&(sf.trailers), &tbuf,
-                                trailers, sf.trl_cnt, PyBUF_SIMPLE)))
+                (i = iov_setup(&(sf.trailers), &tbuf,
+                                trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
                 return NULL;
 #ifdef __APPLE__
             sbytes += i;
@@ -8483,7 +8486,7 @@ posix_writev(PyObject *self, PyObject *args)
     }
     cnt = PySequence_Size(seq);
 
-    if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
+    if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
         return NULL;
     }
 
@@ -8492,6 +8495,9 @@ posix_writev(PyObject *self, PyObject *args)
     Py_END_ALLOW_THREADS
 
     iov_cleanup(iov, buf, cnt);
+    if (res < 0)
+        return posix_error();
+
     return PyLong_FromSsize_t(res);
 }
 #endif