[Python-checkins] python/dist/src/Objects fileobject.c,2.141.6.6,2.141.6.7

niemeyer@users.sourceforge.net niemeyer@users.sourceforge.net
Mon, 03 Mar 2003 16:50:27 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv25505/Objects

Modified Files:
      Tag: release22-maint
	fileobject.c 
Log Message:
Backported fix to [521782] unreliable file.read() error handling.


Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.141.6.6
retrieving revision 2.141.6.7
diff -C2 -d -r2.141.6.6 -r2.141.6.7
*** fileobject.c	25 Sep 2002 18:06:48 -0000	2.141.6.6
--- fileobject.c	4 Mar 2003 00:50:24 -0000	2.141.6.7
***************
*** 569,572 ****
--- 569,586 ----
  }
  
+ #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)
***************
*** 602,617 ****
  			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;
  		}
  	}
--- 616,642 ----
  			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 {
+ 			/* Got what was requested. */
+ 			break;
  		}
  	}
***************
*** 1322,1326 ****
  "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.";
  
  static char write_doc[] =
--- 1347,1353 ----
  "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.";
  
  static char write_doc[] =