changeset: 88355:cd50efdce294 parent: 88353:c0b0e7aef360 parent: 88354:1437f499024d user: Victor Stinner date: Wed Jan 08 15:26:12 2014 +0100 files: Lib/test/test_os.py Lib/test/test_posix.py Misc/NEWS Modules/posixmodule.c description: (Merge 3.3) Issue #20113: os.readv() and os.writev() now raise an OSError exception on error instead of returning -1. diff -r c0b0e7aef360 -r cd50efdce294 Lib/test/test_os.py --- a/Lib/test/test_os.py Tue Jan 07 23:29:19 2014 -0700 +++ b/Lib/test/test_os.py Wed Jan 08 15:26:12 2014 +0100 @@ -1267,6 +1267,11 @@ 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) @@ -1275,6 +1280,10 @@ 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): diff -r c0b0e7aef360 -r cd50efdce294 Lib/test/test_posix.py --- a/Lib/test/test_posix.py Tue Jan 07 23:29:19 2014 -0700 +++ b/Lib/test/test_posix.py Wed Jan 08 15:26:12 2014 +0100 @@ -283,9 +283,14 @@ 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 @@ 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) diff -r c0b0e7aef360 -r cd50efdce294 Misc/NEWS --- a/Misc/NEWS Tue Jan 07 23:29:19 2014 -0700 +++ b/Misc/NEWS Wed Jan 08 15:26:12 2014 +0100 @@ -18,6 +18,9 @@ Library ------- +- Issue #20113: os.readv() and os.writev() now raise an OSError exception on + error instead of returning -1. + - Issue #19719: Make importlib.abc.MetaPathFinder.find_module(), PathEntryFinder.find_loader(), and Loader.load_module() use PEP 451 APIs to help with backwards-compatibility. diff -r c0b0e7aef360 -r cd50efdce294 Modules/posixmodule.c --- a/Modules/posixmodule.c Tue Jan 07 23:29:19 2014 -0700 +++ b/Modules/posixmodule.c Wed Jan 08 15:26:12 2014 +0100 @@ -8011,14 +8011,14 @@ *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++) { @@ -8043,7 +8043,7 @@ PyBuffer_Release(&(*buf)[j]); } PyMem_Del(*buf); - return 0; + return -1; } static void @@ -8083,7 +8083,7 @@ } 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 @@ -8091,6 +8091,9 @@ Py_END_ALLOW_THREADS iov_cleanup(iov, buf, cnt); + if (n < 0) + return posix_error(); + return PyLong_FromSsize_t(n); } #endif @@ -8216,8 +8219,8 @@ 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; @@ -8233,8 +8236,8 @@ 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; @@ -8475,7 +8478,7 @@ } 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; } @@ -8484,6 +8487,9 @@ Py_END_ALLOW_THREADS iov_cleanup(iov, buf, cnt); + if (res < 0) + return posix_error(); + return PyLong_FromSsize_t(res); } #endif