certain files, like ttys, it makes sense to continue reading after
an \EOF{} is hit.) Note that this method may call the underlying
C function \cfunction{fread()} more than once in an effort to
- acquire as close to \var{size} bytes as possible.
+ acquire as close to \var{size} bytes as possible. Also note that
+ when in non-blocking mode, less data than what was requested may
+ be returned, even if no \var{size} parameter was given.
\end{methoddesc}
\begin{methoddesc}[file]{readline}{\optional{size}}
supply a __doc__ descriptor that returns something different for a
class than for instances of that class.
+- Fixed bug #521782: when a file was in non-blocking mode, file.read()
+ could silently lose data or wrongly throw an unknown error.
+
Extension modules
- In readline.c: change completion to avoid appending a space
return currentsize + SMALLCHUNK;
}
+#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
+#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK || (x) == EAGAIN)
+#else
+#ifdef EWOULDBLOCK
+#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define BLOCKED_ERRNO(x) ((x) == EAGAIN)
+#else
+#define BLOCKED_ERRNO(x) 0
+#endif
+#endif
+#endif
+
static PyObject *
file_read(PyFileObject *f, PyObject *args)
{
if (chunksize == 0) {
if (!ferror(f->f_fp))
break;
- PyErr_SetFromErrno(PyExc_IOError);
clearerr(f->f_fp);
+ /* When in non-blocking mode, data shouldn't
+ * be discarded if a blocking signal was
+ * received. That will also happen if
+ * chunksize != 0, but bytesread < buffersize. */
+ if (bytesread > 0 && BLOCKED_ERRNO(errno))
+ break;
+ PyErr_SetFromErrno(PyExc_IOError);
Py_DECREF(v);
return NULL;
}
bytesread += chunksize;
- if (bytesread < buffersize)
+ if (bytesread < buffersize) {
+ clearerr(f->f_fp);
break;
+ }
if (bytesrequested < 0) {
buffersize = new_buffersize(f, buffersize);
if (_PyString_Resize(&v, buffersize) < 0)
return NULL;
+ } else {
+ /* Got what was requested. */
+ break;
}
}
if (bytesread != buffersize)
static char read_doc[] =
"read([size]) -> read at most size bytes, returned as a string.\n"
"\n"
-"If the size argument is negative or omitted, read until EOF is reached.";
+"If the size argument is negative or omitted, read until EOF is reached.\n"
+"Notice that when in non-blocking mode, less data than what was requested\n"
+"may be returned, even if no size parameter was given.";
static char write_doc[] =
"write(str) -> None. Write string str to file.\n"