[Python-checkins] python/dist/src/Objects fileobject.c,2.171,2.172

niemeyer@users.sourceforge.net niemeyer@users.sourceforge.net
2002年12月16日 10:13:00 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv643/Objects
Modified Files:
	fileobject.c 
Log Message:
Fixed bug
[#521782] unreliable file.read() error handling
* Objects/fileobject.c
 (file_read): Clear errors before leaving the loop in all situations,
 and also check if some data was read before exiting the loop with an
 EWOULDBLOCK exception.
* Doc/lib/libstdtypes.tex
* Objects/fileobject.c
 Document that sometimes a read() operation can return less data than
 what the user asked, if running in non-blocking mode.
* Misc/NEWS
 Document the fix.
Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.171
retrieving revision 2.172
diff -C2 -d -r2.171 -r2.172
*** fileobject.c	11 Dec 2002 13:06:53 -0000	2.171
--- fileobject.c	16 Dec 2002 18:12:53 -0000	2.172
***************
*** 742,745 ****
--- 742,759 ----
 }
 
+ #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)
***************
*** 775,790 ****
 			if (!ferror(f->f_fp))
 				break;
- 			PyErr_SetFromErrno(PyExc_IOError);
 			clearerr(f->f_fp);
 			Py_DECREF(v);
 			return NULL;
 		}
 		bytesread += chunksize;
! 		if (bytesread < buffersize)
 			break;
 		if (bytesrequested < 0) {
 			buffersize = new_buffersize(f, buffersize);
 			if (_PyString_Resize(&v, buffersize) < 0)
 				return NULL;
 		}
 	}
--- 789,815 ----
 			if (!ferror(f->f_fp))
 				break;
 			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) {
! 			clearerr(f->f_fp);
 			break;
+ 		}
 		if (bytesrequested < 0) {
 			buffersize = new_buffersize(f, buffersize);
 			if (_PyString_Resize(&v, buffersize) < 0)
 				return NULL;
+ 		} else {
+ 			assert(bytesread == bytesrequested);
+ 			break;
 		}
 	}
***************
*** 1519,1523 ****
 "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.");
 
 PyDoc_STRVAR(write_doc,
--- 1544,1550 ----
 "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.\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.");
 
 PyDoc_STRVAR(write_doc,

AltStyle によって変換されたページ (->オリジナル) /