mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	Issue #20113: os.readv() and os.writev() now raise an OSError exception on
error instead of returning -1.
This commit is contained in:
		
							parent
							
								
									2bcbc14117
								
							
						
					
					
						commit
						57ddf78b6b
					
				
					 4 changed files with 36 additions and 10 deletions
				
			
		| 
						 | 
					@ -1227,6 +1227,11 @@ class TestInvalidFD(unittest.TestCase):
 | 
				
			||||||
    def test_read(self):
 | 
					    def test_read(self):
 | 
				
			||||||
        self.check(os.read, 1)
 | 
					        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()')
 | 
					    @unittest.skipUnless(hasattr(os, 'tcsetpgrp'), 'test needs os.tcsetpgrp()')
 | 
				
			||||||
    def test_tcsetpgrpt(self):
 | 
					    def test_tcsetpgrpt(self):
 | 
				
			||||||
        self.check(os.tcsetpgrp, 0)
 | 
					        self.check(os.tcsetpgrp, 0)
 | 
				
			||||||
| 
						 | 
					@ -1235,6 +1240,10 @@ class TestInvalidFD(unittest.TestCase):
 | 
				
			||||||
    def test_write(self):
 | 
					    def test_write(self):
 | 
				
			||||||
        self.check(os.write, b" ")
 | 
					        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):
 | 
					class LinkTests(unittest.TestCase):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -283,9 +283,14 @@ class PosixTester(unittest.TestCase):
 | 
				
			||||||
    def test_writev(self):
 | 
					    def test_writev(self):
 | 
				
			||||||
        fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
 | 
					        fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
 | 
				
			||||||
        try:
 | 
					        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)
 | 
					            os.lseek(fd, 0, os.SEEK_SET)
 | 
				
			||||||
            self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
 | 
					            self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Issue #20113: empty list of buffers should not crash
 | 
				
			||||||
 | 
					            self.assertEqual(posix.writev(fd, []), 0)
 | 
				
			||||||
        finally:
 | 
					        finally:
 | 
				
			||||||
            os.close(fd)
 | 
					            os.close(fd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -298,6 +303,9 @@ class PosixTester(unittest.TestCase):
 | 
				
			||||||
            buf = [bytearray(i) for i in [5, 3, 2]]
 | 
					            buf = [bytearray(i) for i in [5, 3, 2]]
 | 
				
			||||||
            self.assertEqual(posix.readv(fd, buf), 10)
 | 
					            self.assertEqual(posix.readv(fd, buf), 10)
 | 
				
			||||||
            self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
 | 
					            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:
 | 
					        finally:
 | 
				
			||||||
            os.close(fd)
 | 
					            os.close(fd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,9 @@ Core and Builtins
 | 
				
			||||||
Library
 | 
					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 #20072: Fixed multiple errors in tkinter with wantobjects is False.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Issue #20108: Avoid parameter name clash in inspect.getcallargs().
 | 
					- Issue #20108: Avoid parameter name clash in inspect.getcallargs().
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8050,14 +8050,14 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
 | 
				
			||||||
    *iov = PyMem_New(struct iovec, cnt);
 | 
					    *iov = PyMem_New(struct iovec, cnt);
 | 
				
			||||||
    if (*iov == NULL) {
 | 
					    if (*iov == NULL) {
 | 
				
			||||||
        PyErr_NoMemory();
 | 
					        PyErr_NoMemory();
 | 
				
			||||||
        return total;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *buf = PyMem_New(Py_buffer, cnt);
 | 
					    *buf = PyMem_New(Py_buffer, cnt);
 | 
				
			||||||
    if (*buf == NULL) {
 | 
					    if (*buf == NULL) {
 | 
				
			||||||
        PyMem_Del(*iov);
 | 
					        PyMem_Del(*iov);
 | 
				
			||||||
        PyErr_NoMemory();
 | 
					        PyErr_NoMemory();
 | 
				
			||||||
        return total;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < cnt; i++) {
 | 
					    for (i = 0; i < cnt; i++) {
 | 
				
			||||||
| 
						 | 
					@ -8082,7 +8082,7 @@ fail:
 | 
				
			||||||
        PyBuffer_Release(&(*buf)[j]);
 | 
					        PyBuffer_Release(&(*buf)[j]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    PyMem_Del(*buf);
 | 
					    PyMem_Del(*buf);
 | 
				
			||||||
    return 0;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -8122,7 +8122,7 @@ posix_readv(PyObject *self, PyObject *args)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    cnt = PySequence_Size(seq);
 | 
					    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;
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Py_BEGIN_ALLOW_THREADS
 | 
					    Py_BEGIN_ALLOW_THREADS
 | 
				
			||||||
| 
						 | 
					@ -8130,6 +8130,9 @@ posix_readv(PyObject *self, PyObject *args)
 | 
				
			||||||
    Py_END_ALLOW_THREADS
 | 
					    Py_END_ALLOW_THREADS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    iov_cleanup(iov, buf, cnt);
 | 
					    iov_cleanup(iov, buf, cnt);
 | 
				
			||||||
 | 
					    if (n < 0)
 | 
				
			||||||
 | 
					        return posix_error();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return PyLong_FromSsize_t(n);
 | 
					    return PyLong_FromSsize_t(n);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -8254,8 +8257,8 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
 | 
				
			||||||
            Py_ssize_t i = 0; /* Avoid uninitialized warning */
 | 
					            Py_ssize_t i = 0; /* Avoid uninitialized warning */
 | 
				
			||||||
            sf.hdr_cnt = PySequence_Size(headers);
 | 
					            sf.hdr_cnt = PySequence_Size(headers);
 | 
				
			||||||
            if (sf.hdr_cnt > 0 &&
 | 
					            if (sf.hdr_cnt > 0 &&
 | 
				
			||||||
                !(i = iov_setup(&(sf.headers), &hbuf,
 | 
					                (i = iov_setup(&(sf.headers), &hbuf,
 | 
				
			||||||
                                headers, sf.hdr_cnt, PyBUF_SIMPLE)))
 | 
					                                headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
 | 
				
			||||||
                return NULL;
 | 
					                return NULL;
 | 
				
			||||||
#ifdef __APPLE__
 | 
					#ifdef __APPLE__
 | 
				
			||||||
            sbytes += i;
 | 
					            sbytes += i;
 | 
				
			||||||
| 
						 | 
					@ -8271,8 +8274,8 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
 | 
				
			||||||
            Py_ssize_t i = 0; /* Avoid uninitialized warning */
 | 
					            Py_ssize_t i = 0; /* Avoid uninitialized warning */
 | 
				
			||||||
            sf.trl_cnt = PySequence_Size(trailers);
 | 
					            sf.trl_cnt = PySequence_Size(trailers);
 | 
				
			||||||
            if (sf.trl_cnt > 0 &&
 | 
					            if (sf.trl_cnt > 0 &&
 | 
				
			||||||
                !(i = iov_setup(&(sf.trailers), &tbuf,
 | 
					                (i = iov_setup(&(sf.trailers), &tbuf,
 | 
				
			||||||
                                trailers, sf.trl_cnt, PyBUF_SIMPLE)))
 | 
					                                trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
 | 
				
			||||||
                return NULL;
 | 
					                return NULL;
 | 
				
			||||||
#ifdef __APPLE__
 | 
					#ifdef __APPLE__
 | 
				
			||||||
            sbytes += i;
 | 
					            sbytes += i;
 | 
				
			||||||
| 
						 | 
					@ -8483,7 +8486,7 @@ posix_writev(PyObject *self, PyObject *args)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    cnt = PySequence_Size(seq);
 | 
					    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;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8492,6 +8495,9 @@ posix_writev(PyObject *self, PyObject *args)
 | 
				
			||||||
    Py_END_ALLOW_THREADS
 | 
					    Py_END_ALLOW_THREADS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    iov_cleanup(iov, buf, cnt);
 | 
					    iov_cleanup(iov, buf, cnt);
 | 
				
			||||||
 | 
					    if (res < 0)
 | 
				
			||||||
 | 
					        return posix_error();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return PyLong_FromSsize_t(res);
 | 
					    return PyLong_FromSsize_t(res);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue