From: Serhiy Storchaka Date: Tue, 17 Dec 2013 12:40:06 +0000 (+0200) Subject: Issue #17976: Fixed potential problem with file.write() not detecting IO error X-Git-Tag: v2.7.8~194 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6d562319d2ec43fb226861306b0d191aa1792489;p=python Issue #17976: Fixed potential problem with file.write() not detecting IO error by inspecting the return value of fwrite(). Based on patches by Jaakko Moisio and test by Victor Stinner. --- diff --git a/Lib/test/test_file2k.py b/Lib/test/test_file2k.py index 0c633b4e8f..5b90852b07 100644 --- a/Lib/test/test_file2k.py +++ b/Lib/test/test_file2k.py @@ -415,6 +415,14 @@ class OtherFileTests(unittest.TestCase): finally: os.unlink(TESTFN) + @unittest.skipUnless(os.name == 'posix', 'test requires a posix system.') + def test_write_full(self): + # Issue #17976 + with open('/dev/full', 'w', 1) as f: + with self.assertRaises(IOError): + f.write('hello') + f.write('\n') + class FileSubclassTests(unittest.TestCase): def testExit(self): diff --git a/Misc/ACKS b/Misc/ACKS index cb2af182a5..35c9cf0e11 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -710,6 +710,7 @@ Dustin J. Mitchell Dom Mitchell Florian Mladitsch Doug Moen +Jaakko Moisio The Dragon De Monsyne Skip Montanaro Paul Moore diff --git a/Misc/NEWS b/Misc/NEWS index 5a921c9020..5f7485892e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -9,6 +9,10 @@ What's New in Python 2.7.7? Core and Builtins ----------------- +- Issue #17976: Fixed potential problem with file.write() not detecting IO error + by inspecting the return value of fwrite(). Based on patches by Jaakko Moisio + and Victor Stinner. + - Issue #14432: Generator now clears the borrowed reference to the thread state. Fix a crash when a generator is created in a C thread that is destroyed while the generator is still used. The issue was that a generator diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 76cdf74777..d3b1cf6f3f 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -1804,6 +1804,7 @@ file_write(PyFileObject *f, PyObject *args) const char *s; Py_ssize_t n, n2; PyObject *encoded = NULL; + int err = 0; if (f->f_fp == NULL) return err_closed(); @@ -1849,11 +1850,14 @@ file_write(PyFileObject *f, PyObject *args) FILE_BEGIN_ALLOW_THREADS(f) errno = 0; n2 = fwrite(s, 1, n, f->f_fp); + if (n2 != n || ferror(f->f_fp)) + err = errno; FILE_END_ALLOW_THREADS(f) Py_XDECREF(encoded); if (f->f_binary) PyBuffer_Release(&pbuf); - if (n2 != n) { + if (err) { + errno = err; PyErr_SetFromErrno(PyExc_IOError); clearerr(f->f_fp); return NULL;