/* File object implementation */

#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "structmember.h"

#ifndef DONT_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif /* DONT_HAVE_SYS_TYPES_H */

#ifdef MS_WINDOWS
#define fileno _fileno
/* can simulate truncate with Win32 API functions; see file_truncate */
#define HAVE_FTRUNCATE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#ifdef _MSC_VER
/* Need GetVersion to see if on NT so safe to use _wfopen */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif /* _MSC_VER */

#if defined(PYOS_OS2) && defined(PYCC_GCC)
#include <io.h>
#endif

#define BUF(v) PyString_AS_STRING((PyStringObject *)v)

#ifndef DONT_HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef HAVE_GETC_UNLOCKED
#define GETC(f) getc_unlocked(f)
#define FLOCKFILE(f) flockfile(f)
#define FUNLOCKFILE(f) funlockfile(f)
#else
#define GETC(f) getc(f)
#define FLOCKFILE(f)
#define FUNLOCKFILE(f)
#endif

/* Bits in f_newlinetypes */
#define NEWLINE_UNKNOWN	0	/* No newline seen, yet */
#define NEWLINE_CR 1		/* \r newline seen */
#define NEWLINE_LF 2		/* \n newline seen */
#define NEWLINE_CRLF 4		/* \r\n newline seen */

#ifdef __cplusplus
extern "C" {
#endif

FILE *
PyFile_AsFile(PyObject *f)
{
	if (f == NULL || !PyFile_Check(f))
		return NULL;
	else
		return ((PyFileObject *)f)->f_fp;
}

PyObject *
PyFile_Name(PyObject *f)
{
	if (f == NULL || !PyFile_Check(f))
		return NULL;
	else
		return ((PyFileObject *)f)->f_name;
}

/* On Unix, fopen will succeed for directories.
   In Python, there should be no file objects referring to
   directories, so we need a check.  */

static PyFileObject*
dircheck(PyFileObject* f)
{
#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
	struct stat buf;
	if (f->f_fp == NULL)
		return f;
	if (fstat(fileno(f->f_fp), &buf) == 0 &&
	    S_ISDIR(buf.st_mode)) {
#ifdef HAVE_STRERROR
		char *msg = strerror(EISDIR);
#else
		char *msg = "Is a directory";
#endif
		PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(is)",
						      EISDIR, msg);
		PyErr_SetObject(PyExc_IOError, exc);
		Py_XDECREF(exc);
		return NULL;
	}
#endif
	return f;
}


static PyObject *
fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode,
		 int (*close)(FILE *))
{
	assert(f != NULL);
	assert(PyFile_Check(f));
	assert(f->f_fp == NULL);

	Py_DECREF(f->f_name);
	Py_DECREF(f->f_mode);
	Py_DECREF(f->f_encoding);

        Py_INCREF (name);
        f->f_name = name;

	f->f_mode = PyString_FromString(mode);

	f->f_close = close;
	f->f_softspace = 0;
	f->f_binary = strchr(mode,'b') != NULL;
	f->f_buf = NULL;
	f->f_univ_newline = (strchr(mode, 'U') != NULL);
	f->f_newlinetypes = NEWLINE_UNKNOWN;
	f->f_skipnextlf = 0;
	Py_INCREF(Py_None);
	f->f_encoding = Py_None;

	if (f->f_name == NULL || f->f_mode == NULL)
		return NULL;
	f->f_fp = fp;
        f = dircheck(f);
	return (PyObject *) f;
}

/* check for known incorrect mode strings - problem is, platforms are
   free to accept any mode characters they like and are supposed to
   ignore stuff they don't understand... write or append mode with
   universal newline support is expressly forbidden by PEP 278.
   Additionally, remove the 'U' from the mode string as platforms
   won't know what it is. */
/* zero return is kewl - one is un-kewl */
static int
sanitize_the_mode(char *mode)
{
	char *upos;
	size_t len = strlen(mode);

	if (!len) {
		PyErr_SetString(PyExc_ValueError, "empty mode string");
		return 1;
	}

	upos = strchr(mode, 'U');
	if (upos) {
		memmove(upos, upos+1, len-(upos-mode)); /* incl null char */

		if (mode[0] == 'w' || mode[0] == 'a') {
			PyErr_Format(PyExc_ValueError, "universal newline "
			             "mode can only be used with modes "
				     "starting with 'r'");
			return 1;
		}

		if (mode[0] != 'r') {
			memmove(mode+1, mode, strlen(mode)+1);
			mode[0] = 'r';
		}

		if (!strchr(mode, 'b')) {
			memmove(mode+2, mode+1, strlen(mode));
			mode[1] = 'b';
		}
	} else if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
		PyErr_Format(PyExc_ValueError, "mode string must begin with "
	        	    "one of 'r', 'w', 'a' or 'U', not '%.200s'", mode);
		return 1;
	}

	return 0;
}

static PyObject *
open_the_file(PyFileObject *f, char *name, char *mode)
{
	char *newmode;
	assert(f != NULL);
	assert(PyFile_Check(f));
#ifdef MS_WINDOWS
	/* windows ignores the passed name in order to support Unicode */
	assert(f->f_name != NULL);
#else
	assert(name != NULL);
#endif
	assert(mode != NULL);
	assert(f->f_fp == NULL);

	/* probably need to replace 'U' by 'rb' */
	newmode = PyMem_MALLOC(strlen(mode) + 3);
	if (!newmode) {
		PyErr_NoMemory();
		return NULL;
	}
	strcpy(newmode, mode);

	if (sanitize_the_mode(newmode)) {
		f = NULL;
		goto cleanup;
	}

	/* rexec.py can't stop a user from getting the file() constructor --
	   all they have to do is get *any* file object f, and then do
	   type(f).  Here we prevent them from doing damage with it. */
	if (PyEval_GetRestricted()) {
		PyErr_SetString(PyExc_IOError,
		"file() constructor not accessible in restricted mode");
		f = NULL;
		goto cleanup;
	}
	errno = 0;

#ifdef MS_WINDOWS
	if (PyUnicode_Check(f->f_name)) {
		PyObject *wmode;
		wmode = PyUnicode_DecodeASCII(newmode, strlen(newmode), NULL);
		if (f->f_name && wmode) {
			Py_BEGIN_ALLOW_THREADS
			/* PyUnicode_AS_UNICODE OK without thread
			   lock as it is a simple dereference. */
			f->f_fp = _wfopen(PyUnicode_AS_UNICODE(f->f_name),
					  PyUnicode_AS_UNICODE(wmode));
			Py_END_ALLOW_THREADS
		}
		Py_XDECREF(wmode);
	}
#endif
	if (NULL == f->f_fp && NULL != name) {
		Py_BEGIN_ALLOW_THREADS
		f->f_fp = fopen(name, newmode);
		Py_END_ALLOW_THREADS
	}

	if (f->f_fp == NULL) {
#ifdef _MSC_VER
		/* MSVC 6 (Microsoft) leaves errno at 0 for bad mode strings,
		 * across all Windows flavors.  When it sets EINVAL varies
		 * across Windows flavors, the exact conditions aren't
		 * documented, and the answer lies in the OS's implementation
		 * of Win32's CreateFile function (whose source is secret).
		 * Seems the best we can do is map EINVAL to ENOENT.
		 */
		if (errno == 0)	/* bad mode string */
			errno = EINVAL;
		else if (errno == EINVAL) /* unknown, but not a mode string */
			errno = ENOENT;
#endif
		if (errno == EINVAL)
			PyErr_Format(PyExc_IOError, "invalid mode: %s",
				     mode);
		else
			PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, f->f_name);
		f = NULL;
	}
	if (f != NULL)
		f = dircheck(f);

cleanup:
	PyMem_FREE(newmode);

	return (PyObject *)f;
}

PyObject *
PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
{
	PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type,
							     NULL, NULL);
	if (f != NULL) {
                PyObject *o_name = PyString_FromString(name);
		if (fill_file_fields(f, fp, o_name, mode, close) == NULL) {
			Py_DECREF(f);
			f = NULL;
		}
                Py_DECREF(o_name);
	}
	return (PyObject *) f;
}

PyObject *
PyFile_FromString(char *name, char *mode)
{
	extern int fclose(FILE *);
	PyFileObject *f;

	f = (PyFileObject *)PyFile_FromFile((FILE *)NULL, name, mode, fclose);
	if (f != NULL) {
		if (open_the_file(f, name, mode) == NULL) {
			Py_DECREF(f);
			f = NULL;
		}
	}
	return (PyObject *)f;
}

void
PyFile_SetBufSize(PyObject *f, int bufsize)
{
	PyFileObject *file = (PyFileObject *)f;
	if (bufsize >= 0) {
		int type;
		switch (bufsize) {
		case 0:
			type = _IONBF;
			break;
#ifdef HAVE_SETVBUF
		case 1:
			type = _IOLBF;
			bufsize = BUFSIZ;
			break;
#endif
		default:
			type = _IOFBF;
#ifndef HAVE_SETVBUF
			bufsize = BUFSIZ;
#endif
			break;
		}
		fflush(file->f_fp);
		if (type == _IONBF) {
			PyMem_Free(file->f_setbuf);
			file->f_setbuf = NULL;
		} else {
			file->f_setbuf = (char *)PyMem_Realloc(file->f_setbuf, 
                                                                bufsize);
		}
#ifdef HAVE_SETVBUF
		setvbuf(file->f_fp, file->f_setbuf, type, bufsize);
#else /* !HAVE_SETVBUF */
		setbuf(file->f_fp, file->f_setbuf);
#endif /* !HAVE_SETVBUF */
	}
}

/* Set the encoding used to output Unicode strings.
   Returh 1 on success, 0 on failure. */

int
PyFile_SetEncoding(PyObject *f, const char *enc)
{
	PyFileObject *file = (PyFileObject*)f;
	PyObject *str = PyString_FromString(enc);
	if (!str)
		return 0;
	Py_DECREF(file->f_encoding);
	file->f_encoding = str;
	return 1;
}

static PyObject *
err_closed(void)
{
	PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
	return NULL;
}

/* Refuse regular file I/O if there's data in the iteration-buffer.
 * Mixing them would cause data to arrive out of order, as the read*
 * methods don't use the iteration buffer. */
static PyObject *
err_iterbuffered(void)
{
	PyErr_SetString(PyExc_ValueError,
		"Mixing iteration and read methods would lose data");
	return NULL;
}

static void drop_readahead(PyFileObject *);

/* Methods */

static void
file_dealloc(PyFileObject *f)
{
	int sts = 0;
	if (f->weakreflist != NULL)
		PyObject_ClearWeakRefs((PyObject *) f);
	if (f->f_fp != NULL && f->f_close != NULL) {
		Py_BEGIN_ALLOW_THREADS
		sts = (*f->f_close)(f->f_fp);
		Py_END_ALLOW_THREADS
		if (sts == EOF) 
#ifdef HAVE_STRERROR
			PySys_WriteStderr("close failed: [Errno %d] %s\n", errno, strerror(errno)); 
#else
			PySys_WriteStderr("close failed: [Errno %d]\n", errno); 
#endif
	}
	PyMem_Free(f->f_setbuf);
	Py_XDECREF(f->f_name);
	Py_XDECREF(f->f_mode);
	Py_XDECREF(f->f_encoding);
	drop_readahead(f);
	f->ob_type->tp_free((PyObject *)f);
}

static PyObject *
file_repr(PyFileObject *f)
{
	if (PyUnicode_Check(f->f_name)) {
#ifdef Py_USING_UNICODE
		PyObject *ret = NULL;
		PyObject *name;
		name = PyUnicode_AsUnicodeEscapeString(f->f_name);
		ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>",
				   f->f_fp == NULL ? "closed" : "open",
				   PyString_AsString(name),
				   PyString_AsString(f->f_mode),
				   f);
		Py_XDECREF(name);
		return ret;
#endif
	} else {
		return PyString_FromFormat("<%s file '%s', mode '%s' at %p>",
				   f->f_fp == NULL ? "closed" : "open",
				   PyString_AsString(f->f_name),
				   PyString_AsString(f->f_mode),
				   f);
	}
}

static PyObject *
file_close(PyFileObject *f)
{
	int sts = 0;
	if (f->f_fp != NULL) {
		if (f->f_close != NULL) {
			Py_BEGIN_ALLOW_THREADS
			errno = 0;
			sts = (*f->f_close)(f->f_fp);
			Py_END_ALLOW_THREADS
		}
		f->f_fp = NULL;
	}
	PyMem_Free(f->f_setbuf);
	f->f_setbuf = NULL;
	if (sts == EOF)
		return PyErr_SetFromErrno(PyExc_IOError);
	if (sts != 0)
		return PyInt_FromLong((long)sts);
	Py_INCREF(Py_None);
	return Py_None;
}


/* Our very own off_t-like type, 64-bit if possible */
#if !defined(HAVE_LARGEFILE_SUPPORT)
typedef off_t Py_off_t;
#elif SIZEOF_OFF_T >= 8
typedef off_t Py_off_t;
#elif SIZEOF_FPOS_T >= 8
typedef fpos_t Py_off_t;
#else
#error "Large file support, but neither off_t nor fpos_t is large enough."
#endif


/* a portable fseek() function
   return 0 on success, non-zero on failure (with errno set) */
static int
_portable_fseek(FILE *fp, Py_off_t offset, int whence)
{
#if !defined(HAVE_LARGEFILE_SUPPORT)
	return fseek(fp, offset, whence);
#elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8
	return fseeko(fp, offset, whence);
#elif defined(HAVE_FSEEK64)
	return fseek64(fp, offset, whence);
#elif defined(__BEOS__)
	return _fseek(fp, offset, whence);
#elif SIZEOF_FPOS_T >= 8
	/* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
	   and fgetpos() to implement fseek()*/
	fpos_t pos;
	switch (whence) {
	case SEEK_END:
#ifdef MS_WINDOWS
		fflush(fp);
		if (_lseeki64(fileno(fp), 0, 2) == -1)
			return -1;
#else
		if (fseek(fp, 0, SEEK_END) != 0)
			return -1;
#endif
		/* fall through */
	case SEEK_CUR:
		if (fgetpos(fp, &pos) != 0)
			return -1;
		offset += pos;
		break;
	/* case SEEK_SET: break; */
	}
	return fsetpos(fp, &offset);
#else
#error "Large file support, but no way to fseek."
#endif
}


/* a portable ftell() function
   Return -1 on failure with errno set appropriately, current file
   position on success */
static Py_off_t
_portable_ftell(FILE* fp)
{
#if !defined(HAVE_LARGEFILE_SUPPORT)
	return ftell(fp);
#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8
	return ftello(fp);
#elif defined(HAVE_FTELL64)
	return ftell64(fp);
#elif SIZEOF_FPOS_T >= 8
	fpos_t pos;
	if (fgetpos(fp, &pos) != 0)
		return -1;
	return pos;
#else
#error "Large file support, but no way to ftell."
#endif
}


static PyObject *
file_seek(PyFileObject *f, PyObject *args)
{
	int whence;
	int ret;
	Py_off_t offset;
	PyObject *offobj;

	if (f->f_fp == NULL)
		return err_closed();
	drop_readahead(f);
	whence = 0;
	if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
		return NULL;
#if !defined(HAVE_LARGEFILE_SUPPORT)
	offset = PyInt_AsLong(offobj);
#else
	offset = PyLong_Check(offobj) ?
		PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
#endif
	if (PyErr_Occurred())
		return NULL;

	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	ret = _portable_fseek(f->f_fp, offset, whence);
	Py_END_ALLOW_THREADS

	if (ret != 0) {
		PyErr_SetFromErrno(PyExc_IOError);
		clearerr(f->f_fp);
		return NULL;
	}
	f->f_skipnextlf = 0;
	Py_INCREF(Py_None);
	return Py_None;
}


#ifdef HAVE_FTRUNCATE
static PyObject *
file_truncate(PyFileObject *f, PyObject *args)
{
	Py_off_t newsize;
	PyObject *newsizeobj = NULL;
	Py_off_t initialpos;
	int ret;

	if (f->f_fp == NULL)
		return err_closed();
	if (!PyArg_UnpackTuple(args, "truncate", 0, 1, &newsizeobj))
		return NULL;

	/* Get current file position.  If the file happens to be open for
	 * update and the last operation was an input operation, C doesn't
	 * define what the later fflush() will do, but we promise truncate()
	 * won't change the current position (and fflush() *does* change it
	 * then at least on Windows).  The easiest thing is to capture
	 * current pos now and seek back to it at the end.
	 */
	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	initialpos = _portable_ftell(f->f_fp);
	Py_END_ALLOW_THREADS
	if (initialpos == -1)
		goto onioerror;

	/* Set newsize to current postion if newsizeobj NULL, else to the
	 * specified value.
	 */
	if (newsizeobj != NULL) {
#if !defined(HAVE_LARGEFILE_SUPPORT)
		newsize = PyInt_AsLong(newsizeobj);
#else
		newsize = PyLong_Check(newsizeobj) ?
				PyLong_AsLongLong(newsizeobj) :
				PyInt_AsLong(newsizeobj);
#endif
		if (PyErr_Occurred())
			return NULL;
	}
	else /* default to current position */
		newsize = initialpos;

	/* Flush the stream.  We're mixing stream-level I/O with lower-level
	 * I/O, and a flush may be necessary to synch both platform views
	 * of the current file state.
	 */
	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	ret = fflush(f->f_fp);
	Py_END_ALLOW_THREADS
	if (ret != 0)
		goto onioerror;

#ifdef MS_WINDOWS
	/* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
	   so don't even try using it. */
	{
		HANDLE hFile;

		/* Have to move current pos to desired endpoint on Windows. */
		Py_BEGIN_ALLOW_THREADS
		errno = 0;
		ret = _portable_fseek(f->f_fp, newsize, SEEK_SET) != 0;
		Py_END_ALLOW_THREADS
		if (ret)
			goto onioerror;

		/* Truncate.  Note that this may grow the file! */
		Py_BEGIN_ALLOW_THREADS
		errno = 0;
		hFile = (HANDLE)_get_osfhandle(fileno(f->f_fp));
		ret = hFile == (HANDLE)-1;
		if (ret == 0) {
			ret = SetEndOfFile(hFile) == 0;
			if (ret)
				errno = EACCES;
		}
		Py_END_ALLOW_THREADS
		if (ret)
			goto onioerror;
	}
#else
	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	ret = ftruncate(fileno(f->f_fp), newsize);
	Py_END_ALLOW_THREADS
	if (ret != 0)
		goto onioerror;
#endif /* !MS_WINDOWS */

	/* Restore original file position. */
	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	ret = _portable_fseek(f->f_fp, initialpos, SEEK_SET) != 0;
	Py_END_ALLOW_THREADS
	if (ret)
		goto onioerror;

	Py_INCREF(Py_None);
	return Py_None;

onioerror:
	PyErr_SetFromErrno(PyExc_IOError);
	clearerr(f->f_fp);
	return NULL;
}
#endif /* HAVE_FTRUNCATE */

static PyObject *
file_tell(PyFileObject *f)
{
	Py_off_t pos;

	if (f->f_fp == NULL)
		return err_closed();
	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	pos = _portable_ftell(f->f_fp);
	Py_END_ALLOW_THREADS
	if (pos == -1) {
		PyErr_SetFromErrno(PyExc_IOError);
		clearerr(f->f_fp);
		return NULL;
	}
	if (f->f_skipnextlf) {
		int c;
		c = GETC(f->f_fp);
		if (c == '\n') {
			pos++;
			f->f_skipnextlf = 0;
		} else if (c != EOF) ungetc(c, f->f_fp);
	}
#if !defined(HAVE_LARGEFILE_SUPPORT)
	return PyInt_FromLong(pos);
#else
	return PyLong_FromLongLong(pos);
#endif
}

static PyObject *
file_fileno(PyFileObject *f)
{
	if (f->f_fp == NULL)
		return err_closed();
	return PyInt_FromLong((long) fileno(f->f_fp));
}

static PyObject *
file_flush(PyFileObject *f)
{
	int res;

	if (f->f_fp == NULL)
		return err_closed();
	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	res = fflush(f->f_fp);
	Py_END_ALLOW_THREADS
	if (res != 0) {
		PyErr_SetFromErrno(PyExc_IOError);
		clearerr(f->f_fp);
		return NULL;
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
file_isatty(PyFileObject *f)
{
	long res;
	if (f->f_fp == NULL)
		return err_closed();
	Py_BEGIN_ALLOW_THREADS
	res = isatty((int)fileno(f->f_fp));
	Py_END_ALLOW_THREADS
	return PyBool_FromLong(res);
}


#if BUFSIZ < 8192
#define SMALLCHUNK 8192
#else
#define SMALLCHUNK BUFSIZ
#endif

#if SIZEOF_INT < 4
#define BIGCHUNK  (512 * 32)
#else
#define BIGCHUNK  (512 * 1024)
#endif

static size_t
new_buffersize(PyFileObject *f, size_t currentsize)
{
#ifdef HAVE_FSTAT
	off_t pos, end;
	struct stat st;
	if (fstat(fileno(f->f_fp), &st) == 0) {
		end = st.st_size;
		/* The following is not a bug: we really need to call lseek()
		   *and* ftell().  The reason is that some stdio libraries
		   mistakenly flush their buffer when ftell() is called and
		   the lseek() call it makes fails, thereby throwing away
		   data that cannot be recovered in any way.  To avoid this,
		   we first test lseek(), and only call ftell() if lseek()
		   works.  We can't use the lseek() value either, because we
		   need to take the amount of buffered data into account.
		   (Yet another reason why stdio stinks. :-) */
		pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
		if (pos >= 0) {
			pos = ftell(f->f_fp);
		}
		if (pos < 0)
			clearerr(f->f_fp);
		if (end > pos && pos >= 0)
			return currentsize + end - pos + 1;
		/* Add 1 so if the file were to grow we'd notice. */
	}
#endif
	if (currentsize > SMALLCHUNK) {
		/* Keep doubling until we reach BIGCHUNK;
		   then keep adding BIGCHUNK. */
		if (currentsize <= BIGCHUNK)
			return currentsize + currentsize;
		else
			return currentsize + BIGCHUNK;
	}
	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)
{
	long bytesrequested = -1;
	size_t bytesread, buffersize, chunksize;
	PyObject *v;

	if (f->f_fp == NULL)
		return err_closed();
	/* refuse to mix with f.next() */
	if (f->f_buf != NULL &&
	    (f->f_bufend - f->f_bufptr) > 0 &&
	    f->f_buf[0] != '\0')
		return err_iterbuffered();
	if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
		return NULL;
	if (bytesrequested < 0)
		buffersize = new_buffersize(f, (size_t)0);
	else
		buffersize = bytesrequested;
	if (buffersize > PY_SSIZE_T_MAX) {
		PyErr_SetString(PyExc_OverflowError,
	"requested number of bytes is more than a Python string can hold");
		return NULL;
	}
	v = PyString_FromStringAndSize((char *)NULL, buffersize);
	if (v == NULL)
		return NULL;
	bytesread = 0;
	for (;;) {
		Py_BEGIN_ALLOW_THREADS
		errno = 0;
		chunksize = Py_UniversalNewlineFread(BUF(v) + bytesread,
			  buffersize - bytesread, f->f_fp, (PyObject *)f);
		Py_END_ALLOW_THREADS
		if (chunksize == 0) {
			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;
		}
	}
	if (bytesread != buffersize)
		_PyString_Resize(&v, bytesread);
	return v;
}

static PyObject *
file_readinto(PyFileObject *f, PyObject *args)
{
	char *ptr;
	Py_ssize_t ntodo;
	Py_ssize_t ndone, nnow;

	if (f->f_fp == NULL)
		return err_closed();
	/* refuse to mix with f.next() */
	if (f->f_buf != NULL &&
	    (f->f_bufend - f->f_bufptr) > 0 &&
	    f->f_buf[0] != '\0')
		return err_iterbuffered();
	if (!PyArg_ParseTuple(args, "w#", &ptr, &ntodo))
		return NULL;
	ndone = 0;
	while (ntodo > 0) {
		Py_BEGIN_ALLOW_THREADS
		errno = 0;
		nnow = Py_UniversalNewlineFread(ptr+ndone, ntodo, f->f_fp,
						(PyObject *)f);
		Py_END_ALLOW_THREADS
		if (nnow == 0) {
			if (!ferror(f->f_fp))
				break;
			PyErr_SetFromErrno(PyExc_IOError);
			clearerr(f->f_fp);
			return NULL;
		}
		ndone += nnow;
		ntodo -= nnow;
	}
	return PyInt_FromLong((long)ndone);
}

/**************************************************************************
Routine to get next line using platform fgets().

Under MSVC 6:

+ MS threadsafe getc is very slow (multiple layers of function calls before+
  after each character, to lock+unlock the stream).
+ The stream-locking functions are MS-internal -- can't access them from user
  code.
+ There's nothing Tim could find in the MS C or platform SDK libraries that
  can worm around this.
+ MS fgets locks/unlocks only once per line; it's the only hook we have.

So we use fgets for speed(!), despite that it's painful.

MS realloc is also slow.

Reports from other platforms on this method vs getc_unlocked (which MS doesn't
have):
	Linux		a wash
	Solaris		a wash
	Tru64 Unix	getline_via_fgets significantly faster

CAUTION:  The C std isn't clear about this:  in those cases where fgets
writes something into the buffer, can it write into any position beyond the
required trailing null byte?  MSVC 6 fgets does not, and no platform is (yet)
known on which it does; and it would be a strange way to code fgets. Still,
getline_via_fgets may not work correctly if it does.  The std test
test_bufio.py should fail if platform fgets() routinely writes beyond the
trailing null byte.  #define DONT_USE_FGETS_IN_GETLINE to disable this code.
**************************************************************************/

/* Use this routine if told to, or by default on non-get_unlocked()
 * platforms unless told not to.  Yikes!  Let's spell that out:
 * On a platform with getc_unlocked():
 *     By default, use getc_unlocked().
 *     If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
 * On a platform without getc_unlocked():
 *     By default, use fgets().
 *     If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
 */
#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
#define USE_FGETS_IN_GETLINE
#endif

#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
#undef USE_FGETS_IN_GETLINE
#endif

#ifdef USE_FGETS_IN_GETLINE
static PyObject*
getline_via_fgets(FILE *fp)
{
/* INITBUFSIZE is the maximum line length that lets us get away with the fast
 * no-realloc, one-fgets()-call path.  Boosting it isn't free, because we have
 * to fill this much of the buffer with a known value in order to figure out
 * how much of the buffer fgets() overwrites.  So if INITBUFSIZE is larger
 * than "most" lines, we waste time filling unused buffer slots.  100 is
 * surely adequate for most peoples' email archives, chewing over source code,
 * etc -- "regular old text files".
 * MAXBUFSIZE is the maximum line length that lets us get away with the less
 * fast (but still zippy) no-realloc, two-fgets()-call path.  See above for
 * cautions about boosting that.  300 was chosen because the worst real-life
 * text-crunching job reported on Python-Dev was a mail-log crawler where over
 * half the lines were 254 chars.
 */
#define INITBUFSIZE 100
#define MAXBUFSIZE 300
	char* p;	/* temp */
	char buf[MAXBUFSIZE];
	PyObject* v;	/* the string object result */
	char* pvfree;	/* address of next free slot */
	char* pvend;    /* address one beyond last free slot */
	size_t nfree;	/* # of free buffer slots; pvend-pvfree */
	size_t total_v_size;  /* total # of slots in buffer */
	size_t increment;	/* amount to increment the buffer */

	/* Optimize for normal case:  avoid _PyString_Resize if at all
	 * possible via first reading into stack buffer "buf".
	 */
	total_v_size = INITBUFSIZE;	/* start small and pray */
	pvfree = buf;
	for (;;) {
		Py_BEGIN_ALLOW_THREADS
		pvend = buf + total_v_size;
		nfree = pvend - pvfree;
		memset(pvfree, '\n', nfree);
		assert(nfree < INT_MAX); /* Should be atmost MAXBUFSIZE */
		p = fgets(pvfree, (int)nfree, fp);
		Py_END_ALLOW_THREADS

		if (p == NULL) {
			clearerr(fp);
			if (PyErr_CheckSignals())
				return NULL;
			v = PyString_FromStringAndSize(buf, pvfree - buf);
			return v;
		}
		/* fgets read *something* */
		p = memchr(pvfree, '\n', nfree);
		if (p != NULL) {
			/* Did the \n come from fgets or from us?
			 * Since fgets stops at the first \n, and then writes
			 * \0, if it's from fgets a \0 must be next.  But if
			 * that's so, it could not have come from us, since
			 * the \n's we filled the buffer with have only more
			 * \n's to the right.
			 */
			if (p+1 < pvend && *(p+1) == '\0') {
				/* It's from fgets:  we win!  In particular,
				 * we haven't done any mallocs yet, and can
				 * build the final result on the first try.
				 */
				++p;	/* include \n from fgets */
			}
			else {
				/* Must be from us:  fgets didn't fill the
				 * buffer and didn't find a newline, so it
				 * must be the last and newline-free line of
				 * the file.
				 */
				assert(p > pvfree && *(p-1) == '\0');
				--p;	/* don't include \0 from fgets */
			}
			v = PyString_FromStringAndSize(buf, p - buf);
			return v;
		}
		/* yuck:  fgets overwrote all the newlines, i.e. the entire
		 * buffer.  So this line isn't over yet, or maybe it is but
		 * we're exactly at EOF.  If we haven't already, try using the
		 * rest of the stack buffer.
		 */
		assert(*(pvend-1) == '\0');
		if (pvfree == buf) {
			pvfree = pvend - 1;	/* overwrite trailing null */
			total_v_size = MAXBUFSIZE;
		}
		else
			break;
	}

	/* The stack buffer isn't big enough; malloc a string object and read
	 * into its buffer.
	 */
	total_v_size = MAXBUFSIZE << 1;
	v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
	if (v == NULL)
		return v;
	/* copy over everything except the last null byte */
	memcpy(BUF(v), buf, MAXBUFSIZE-1);
	pvfree = BUF(v) + MAXBUFSIZE - 1;

	/* Keep reading stuff into v; if it ever ends successfully, break
	 * after setting p one beyond the end of the line.  The code here is
	 * very much like the code above, except reads into v's buffer; see
	 * the code above for detailed comments about the logic.
	 */
	for (;;) {
		Py_BEGIN_ALLOW_THREADS
		pvend = BUF(v) + total_v_size;
		nfree = pvend - pvfree;
		memset(pvfree, '\n', nfree);
		assert(nfree < INT_MAX);
		p = fgets(pvfree, (int)nfree, fp);
		Py_END_ALLOW_THREADS

		if (p == NULL) {
			clearerr(fp);
			if (PyErr_CheckSignals()) {
				Py_DECREF(v);
				return NULL;
			}
			p = pvfree;
			break;
		}
		p = memchr(pvfree, '\n', nfree);
		if (p != NULL) {
			if (p+1 < pvend && *(p+1) == '\0') {
				/* \n came from fgets */
				++p;
				break;
			}
			/* \n came from us; last line of file, no newline */
			assert(p > pvfree && *(p-1) == '\0');
			--p;
			break;
		}
		/* expand buffer and try again */
		assert(*(pvend-1) == '\0');
		increment = total_v_size >> 2;	/* mild exponential growth */
		total_v_size += increment;
		if (total_v_size > PY_SSIZE_T_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			    "line is longer than a Python string can hold");
			Py_DECREF(v);
			return NULL;
		}
		if (_PyString_Resize(&v, (int)total_v_size) < 0)
			return NULL;
		/* overwrite the trailing null byte */
		pvfree = BUF(v) + (total_v_size - increment - 1);
	}
	if (BUF(v) + total_v_size != p)
		_PyString_Resize(&v, p - BUF(v));
	return v;
#undef INITBUFSIZE
#undef MAXBUFSIZE
}
#endif	/* ifdef USE_FGETS_IN_GETLINE */

/* Internal routine to get a line.
   Size argument interpretation:
   > 0: max length;
   <= 0: read arbitrary line
*/

static PyObject *
get_line(PyFileObject *f, int n)
{
	FILE *fp = f->f_fp;
	int c;
	char *buf, *end;
	size_t total_v_size;	/* total # of slots in buffer */
	size_t used_v_size;	/* # used slots in buffer */
	size_t increment;       /* amount to increment the buffer */
	PyObject *v;
	int newlinetypes = f->f_newlinetypes;
	int skipnextlf = f->f_skipnextlf;
	int univ_newline = f->f_univ_newline;

#if defined(USE_FGETS_IN_GETLINE)
	if (n <= 0 && !univ_newline )
		return getline_via_fgets(fp);
#endif
	total_v_size = n > 0 ? n : 100;
	v = PyString_FromStringAndSize((char *)NULL, total_v_size);
	if (v == NULL)
		return NULL;
	buf = BUF(v);
	end = buf + total_v_size;

	for (;;) {
		Py_BEGIN_ALLOW_THREADS
		FLOCKFILE(fp);
		if (univ_newline) {
			c = 'x'; /* Shut up gcc warning */
			while ( buf != end && (c = GETC(fp)) != EOF ) {
				if (skipnextlf ) {
					skipnextlf = 0;
					if (c == '\n') {
						/* Seeing a \n here with
						 * skipnextlf true means we
						 * saw a \r before.
						 */
						newlinetypes |= NEWLINE_CRLF;
						c = GETC(fp);
						if (c == EOF) break;
					} else {
						newlinetypes |= NEWLINE_CR;
					}
				}
				if (c == '\r') {
					skipnextlf = 1;
					c = '\n';
				} else if ( c == '\n')
					newlinetypes |= NEWLINE_LF;
				*buf++ = c;
				if (c == '\n') break;
			}
			if ( c == EOF && skipnextlf )
				newlinetypes |= NEWLINE_CR;
		} else /* If not universal newlines use the normal loop */
		while ((c = GETC(fp)) != EOF &&
		       (*buf++ = c) != '\n' &&
			buf != end)
			;
		FUNLOCKFILE(fp);
		Py_END_ALLOW_THREADS
		f->f_newlinetypes = newlinetypes;
		f->f_skipnextlf = skipnextlf;
		if (c == '\n')
			break;
		if (c == EOF) {
			if (ferror(fp)) {
				PyErr_SetFromErrno(PyExc_IOError);
				clearerr(fp);
				Py_DECREF(v);
				return NULL;
			}
			clearerr(fp);
			if (PyErr_CheckSignals()) {
				Py_DECREF(v);
				return NULL;
			}
			break;
		}
		/* Must be because buf == end */
		if (n > 0)
			break;
		used_v_size = total_v_size;
		increment = total_v_size >> 2; /* mild exponential growth */
		total_v_size += increment;
		if (total_v_size > PY_SSIZE_T_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			    "line is longer than a Python string can hold");
			Py_DECREF(v);
			return NULL;
		}
		if (_PyString_Resize(&v, total_v_size) < 0)
			return NULL;
		buf = BUF(v) + used_v_size;
		end = BUF(v) + total_v_size;
	}

	used_v_size = buf - BUF(v);
	if (used_v_size != total_v_size)
		_PyString_Resize(&v, used_v_size);
	return v;
}

/* External C interface */

PyObject *
PyFile_GetLine(PyObject *f, int n)
{
	PyObject *result;

	if (f == NULL) {
		PyErr_BadInternalCall();
		return NULL;
	}

	if (PyFile_Check(f)) {
		PyFileObject *fo = (PyFileObject *)f;
		if (fo->f_fp == NULL)
			return err_closed();
		/* refuse to mix with f.next() */
		if (fo->f_buf != NULL &&
		    (fo->f_bufend - fo->f_bufptr) > 0 &&
		    fo->f_buf[0] != '\0')
			return err_iterbuffered();
		result = get_line(fo, n);
	}
	else {
		PyObject *reader;
		PyObject *args;

		reader = PyObject_GetAttrString(f, "readline");
		if (reader == NULL)
			return NULL;
		if (n <= 0)
			args = PyTuple_New(0);
		else
			args = Py_BuildValue("(i)", n);
		if (args == NULL) {
			Py_DECREF(reader);
			return NULL;
		}
		result = PyEval_CallObject(reader, args);
		Py_DECREF(reader);
		Py_DECREF(args);
		if (result != NULL && !PyString_Check(result) &&
		    !PyUnicode_Check(result)) {
			Py_DECREF(result);
			result = NULL;
			PyErr_SetString(PyExc_TypeError,
				   "object.readline() returned non-string");
		}
	}

	if (n < 0 && result != NULL && PyString_Check(result)) {
		char *s = PyString_AS_STRING(result);
		Py_ssize_t len = PyString_GET_SIZE(result);
		if (len == 0) {
			Py_DECREF(result);
			result = NULL;
			PyErr_SetString(PyExc_EOFError,
					"EOF when reading a line");
		}
		else if (s[len-1] == '\n') {
			if (result->ob_refcnt == 1)
				_PyString_Resize(&result, len-1);
			else {
				PyObject *v;
				v = PyString_FromStringAndSize(s, len-1);
				Py_DECREF(result);
				result = v;
			}
		}
	}
#ifdef Py_USING_UNICODE
	if (n < 0 && result != NULL && PyUnicode_Check(result)) {
		Py_UNICODE *s = PyUnicode_AS_UNICODE(result);
		Py_ssize_t len = PyUnicode_GET_SIZE(result);
		if (len == 0) {
			Py_DECREF(result);
			result = NULL;
			PyErr_SetString(PyExc_EOFError,
					"EOF when reading a line");
		}
		else if (s[len-1] == '\n') {
			if (result->ob_refcnt == 1)
				PyUnicode_Resize(&result, len-1);
			else {
				PyObject *v;
				v = PyUnicode_FromUnicode(s, len-1);
				Py_DECREF(result);
				result = v;
			}
		}
	}
#endif
	return result;
}

/* Python method */

static PyObject *
file_readline(PyFileObject *f, PyObject *args)
{
	int n = -1;

	if (f->f_fp == NULL)
		return err_closed();
	/* refuse to mix with f.next() */
	if (f->f_buf != NULL &&
	    (f->f_bufend - f->f_bufptr) > 0 &&
	    f->f_buf[0] != '\0')
		return err_iterbuffered();
	if (!PyArg_ParseTuple(args, "|i:readline", &n))
		return NULL;
	if (n == 0)
		return PyString_FromString("");
	if (n < 0)
		n = 0;
	return get_line(f, n);
}

static PyObject *
file_readlines(PyFileObject *f, PyObject *args)
{
	long sizehint = 0;
	PyObject *list;
	PyObject *line;
	char small_buffer[SMALLCHUNK];
	char *buffer = small_buffer;
	size_t buffersize = SMALLCHUNK;
	PyObject *big_buffer = NULL;
	size_t nfilled = 0;
	size_t nread;
	size_t totalread = 0;
	char *p, *q, *end;
	int err;
	int shortread = 0;

	if (f->f_fp == NULL)
		return err_closed();
	/* refuse to mix with f.next() */
	if (f->f_buf != NULL &&
	    (f->f_bufend - f->f_bufptr) > 0 &&
	    f->f_buf[0] != '\0')
		return err_iterbuffered();
	if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
		return NULL;
	if ((list = PyList_New(0)) == NULL)
		return NULL;
	for (;;) {
		if (shortread)
			nread = 0;
		else {
			Py_BEGIN_ALLOW_THREADS
			errno = 0;
			nread = Py_UniversalNewlineFread(buffer+nfilled,
				buffersize-nfilled, f->f_fp, (PyObject *)f);
			Py_END_ALLOW_THREADS
			shortread = (nread < buffersize-nfilled);
		}
		if (nread == 0) {
			sizehint = 0;
			if (!ferror(f->f_fp))
				break;
			PyErr_SetFromErrno(PyExc_IOError);
			clearerr(f->f_fp);
		  error:
			Py_DECREF(list);
			list = NULL;
			goto cleanup;
		}
		totalread += nread;
		p = (char *)memchr(buffer+nfilled, '\n', nread);
		if (p == NULL) {
			/* Need a larger buffer to fit this line */
			nfilled += nread;
			buffersize *= 2;
			if (buffersize > PY_SSIZE_T_MAX) {
				PyErr_SetString(PyExc_OverflowError,
			    "line is longer than a Python string can hold");
				goto error;
			}
			if (big_buffer == NULL) {
				/* Create the big buffer */
				big_buffer = PyString_FromStringAndSize(
					NULL, buffersize);
				if (big_buffer == NULL)
					goto error;
				buffer = PyString_AS_STRING(big_buffer);
				memcpy(buffer, small_buffer, nfilled);
			}
			else {
				/* Grow the big buffer */
				if ( _PyString_Resize(&big_buffer, buffersize) < 0 )
					goto error;
				buffer = PyString_AS_STRING(big_buffer);
			}
			continue;
		}
		end = buffer+nfilled+nread;
		q = buffer;
		do {
			/* Process complete lines */
			p++;
			line = PyString_FromStringAndSize(q, p-q);
			if (line == NULL)
				goto error;
			err = PyList_Append(list, line);
			Py_DECREF(line);
			if (err != 0)
				goto error;
			q = p;
			p = (char *)memchr(q, '\n', end-q);
		} while (p != NULL);
		/* Move the remaining incomplete line to the start */
		nfilled = end-q;
		memmove(buffer, q, nfilled);
		if (sizehint > 0)
			if (totalread >= (size_t)sizehint)
				break;
	}
	if (nfilled != 0) {
		/* Partial last line */
		line = PyString_FromStringAndSize(buffer, nfilled);
		if (line == NULL)
			goto error;
		if (sizehint > 0) {
			/* Need to complete the last line */
			PyObject *rest = get_line(f, 0);
			if (rest == NULL) {
				Py_DECREF(line);
				goto error;
			}
			PyString_Concat(&line, rest);
			Py_DECREF(rest);
			if (line == NULL)
				goto error;
		}
		err = PyList_Append(list, line);
		Py_DECREF(line);
		if (err != 0)
			goto error;
	}
  cleanup:
	Py_XDECREF(big_buffer);
	return list;
}

static PyObject *
file_write(PyFileObject *f, PyObject *args)
{
	char *s;
	Py_ssize_t n, n2;
	if (f->f_fp == NULL)
		return err_closed();
	if (!PyArg_ParseTuple(args, f->f_binary ? "s#" : "t#", &s, &n))
		return NULL;
	f->f_softspace = 0;
	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	n2 = fwrite(s, 1, n, f->f_fp);
	Py_END_ALLOW_THREADS
	if (n2 != n) {
		PyErr_SetFromErrno(PyExc_IOError);
		clearerr(f->f_fp);
		return NULL;
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
file_writelines(PyFileObject *f, PyObject *seq)
{
#define CHUNKSIZE 1000
	PyObject *list, *line;
	PyObject *it;	/* iter(seq) */
	PyObject *result;
	int index, islist;
	Py_ssize_t i, j, nwritten, len;

	assert(seq != NULL);
	if (f->f_fp == NULL)
		return err_closed();

	result = NULL;
	list = NULL;
	islist = PyList_Check(seq);
	if  (islist)
		it = NULL;
	else {
		it = PyObject_GetIter(seq);
		if (it == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"writelines() requires an iterable argument");
			return NULL;
		}
		/* From here on, fail by going to error, to reclaim "it". */
		list = PyList_New(CHUNKSIZE);
		if (list == NULL)
			goto error;
	}

	/* Strategy: slurp CHUNKSIZE lines into a private list,
	   checking that they are all strings, then write that list
	   without holding the interpreter lock, then come back for more. */
	for (index = 0; ; index += CHUNKSIZE) {
		if (islist) {
			Py_XDECREF(list);
			list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
			if (list == NULL)
				goto error;
			j = PyList_GET_SIZE(list);
		}
		else {
			for (j = 0; j < CHUNKSIZE; j++) {
				line = PyIter_Next(it);
				if (line == NULL) {
					if (PyErr_Occurred())
						goto error;
					break;
				}
				PyList_SetItem(list, j, line);
			}
		}
		if (j == 0)
			break;

		/* Check that all entries are indeed strings. If not,
		   apply the same rules as for file.write() and
		   convert the results to strings. This is slow, but
		   seems to be the only way since all conversion APIs
		   could potentially execute Python code. */
		for (i = 0; i < j; i++) {
			PyObject *v = PyList_GET_ITEM(list, i);
			if (!PyString_Check(v)) {
			    	const char *buffer;
				if (((f->f_binary &&
				      PyObject_AsReadBuffer(v,
					      (const void**)&buffer,
							    &len)) ||
				     PyObject_AsCharBuffer(v,
							   &buffer,
							   &len))) {
					PyErr_SetString(PyExc_TypeError,
			"writelines() argument must be a sequence of strings");
					goto error;
				}
				line = PyString_FromStringAndSize(buffer,
								  len);
				if (line == NULL)
					goto error;
				Py_DECREF(v);
				PyList_SET_ITEM(list, i, line);
			}
		}

		/* Since we are releasing the global lock, the
		   following code may *not* execute Python code. */
		Py_BEGIN_ALLOW_THREADS
		f->f_softspace = 0;
		errno = 0;
		for (i = 0; i < j; i++) {
		    	line = PyList_GET_ITEM(list, i);
			len = PyString_GET_SIZE(line);
			nwritten = fwrite(PyString_AS_STRING(line),
					  1, len, f->f_fp);
			if (nwritten != len) {
				Py_BLOCK_THREADS
				PyErr_SetFromErrno(PyExc_IOError);
				clearerr(f->f_fp);
				goto error;
			}
		}
		Py_END_ALLOW_THREADS

		if (j < CHUNKSIZE)
			break;
	}

	Py_INCREF(Py_None);
	result = Py_None;
  error:
	Py_XDECREF(list);
  	Py_XDECREF(it);
	return result;
#undef CHUNKSIZE
}

static PyObject *
file_self(PyFileObject *f)
{
	if (f->f_fp == NULL)
		return err_closed();
	Py_INCREF(f);
	return (PyObject *)f;
}

PyDoc_STRVAR(readline_doc,
"readline([size]) -> next line from the file, as a string.\n"
"\n"
"Retain newline.  A non-negative size argument limits the maximum\n"
"number of bytes to return (an incomplete line may be returned then).\n"
"Return an empty string at EOF.");

PyDoc_STRVAR(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.\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,
"write(str) -> None.  Write string str to file.\n"
"\n"
"Note that due to buffering, flush() or close() may be needed before\n"
"the file on disk reflects the data written.");

PyDoc_STRVAR(fileno_doc,
"fileno() -> integer \"file descriptor\".\n"
"\n"
"This is needed for lower-level file interfaces, such os.read().");

PyDoc_STRVAR(seek_doc,
"seek(offset[, whence]) -> None.  Move to new file position.\n"
"\n"
"Argument offset is a byte count.  Optional argument whence defaults to\n"
"0 (offset from start of file, offset should be >= 0); other values are 1\n"
"(move relative to current position, positive or negative), and 2 (move\n"
"relative to end of file, usually negative, although many platforms allow\n"
"seeking beyond the end of a file).  If the file is opened in text mode,\n"
"only offsets returned by tell() are legal.  Use of other offsets causes\n"
"undefined behavior."
"\n"
"Note that not all file objects are seekable.");

#ifdef HAVE_FTRUNCATE
PyDoc_STRVAR(truncate_doc,
"truncate([size]) -> None.  Truncate the file to at most size bytes.\n"
"\n"
"Size defaults to the current file position, as returned by tell().");
#endif

PyDoc_STRVAR(tell_doc,
"tell() -> current file position, an integer (may be a long integer).");

PyDoc_STRVAR(readinto_doc,
"readinto() -> Undocumented.  Don't use this; it may go away.");

PyDoc_STRVAR(readlines_doc,
"readlines([size]) -> list of strings, each a line from the file.\n"
"\n"
"Call readline() repeatedly and return a list of the lines so read.\n"
"The optional size argument, if given, is an approximate bound on the\n"
"total number of bytes in the lines returned.");

PyDoc_STRVAR(xreadlines_doc,
"xreadlines() -> returns self.\n"
"\n"
"For backward compatibility. File objects now include the performance\n"
"optimizations previously implemented in the xreadlines module.");

PyDoc_STRVAR(writelines_doc,
"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
"\n"
"Note that newlines are not added.  The sequence can be any iterable object\n"
"producing strings. This is equivalent to calling write() for each string.");

PyDoc_STRVAR(flush_doc,
"flush() -> None.  Flush the internal I/O buffer.");

PyDoc_STRVAR(close_doc,
"close() -> None or (perhaps) an integer.  Close the file.\n"
"\n"
"Sets data attribute .closed to True.  A closed file cannot be used for\n"
"further I/O operations.  close() may be called more than once without\n"
"error.  Some kinds of file objects (for example, opened by popen())\n"
"may return an exit status upon closing.");

PyDoc_STRVAR(isatty_doc,
"isatty() -> true or false.  True if the file is connected to a tty device.");

PyDoc_STRVAR(enter_doc,
	     "__enter__() -> self.");

static PyMethodDef file_methods[] = {
	{"readline",  (PyCFunction)file_readline, METH_VARARGS, readline_doc},
	{"read",      (PyCFunction)file_read,     METH_VARARGS, read_doc},
	{"write",     (PyCFunction)file_write,    METH_VARARGS, write_doc},
	{"fileno",    (PyCFunction)file_fileno,   METH_NOARGS,  fileno_doc},
	{"seek",      (PyCFunction)file_seek,     METH_VARARGS, seek_doc},
#ifdef HAVE_FTRUNCATE
	{"truncate",  (PyCFunction)file_truncate, METH_VARARGS, truncate_doc},
#endif
	{"tell",      (PyCFunction)file_tell,     METH_NOARGS,  tell_doc},
	{"readinto",  (PyCFunction)file_readinto, METH_VARARGS, readinto_doc},
	{"readlines", (PyCFunction)file_readlines,METH_VARARGS, readlines_doc},
	{"xreadlines",(PyCFunction)file_self,     METH_NOARGS, xreadlines_doc},
	{"writelines",(PyCFunction)file_writelines, METH_O,    writelines_doc},
	{"flush",     (PyCFunction)file_flush,    METH_NOARGS,  flush_doc},
	{"close",     (PyCFunction)file_close,    METH_NOARGS,  close_doc},
	{"isatty",    (PyCFunction)file_isatty,   METH_NOARGS,  isatty_doc},
	{"__enter__", (PyCFunction)file_self,     METH_NOARGS,  enter_doc},
	{"__exit__",  (PyCFunction)file_close,    METH_VARARGS, close_doc},
	{NULL,	      NULL}		/* sentinel */
};

#define OFF(x) offsetof(PyFileObject, x)

static PyMemberDef file_memberlist[] = {
	{"softspace",	T_INT,		OFF(f_softspace), 0,
	 "flag indicating that a space needs to be printed; used by print"},
	{"mode",	T_OBJECT,	OFF(f_mode),	RO,
	 "file mode ('r', 'U', 'w', 'a', possibly with 'b' or '+' added)"},
	{"name",	T_OBJECT,	OFF(f_name),	RO,
	 "file name"},
	{"encoding",	T_OBJECT,	OFF(f_encoding),	RO,
	 "file encoding"},
	/* getattr(f, "closed") is implemented without this table */
	{NULL}	/* Sentinel */
};

static PyObject *
get_closed(PyFileObject *f, void *closure)
{
	return PyBool_FromLong((long)(f->f_fp == 0));
}
static PyObject *
get_newlines(PyFileObject *f, void *closure)
{
	switch (f->f_newlinetypes) {
	case NEWLINE_UNKNOWN:
		Py_INCREF(Py_None);
		return Py_None;
	case NEWLINE_CR:
		return PyString_FromString("\r");
	case NEWLINE_LF:
		return PyString_FromString("\n");
	case NEWLINE_CR|NEWLINE_LF:
		return Py_BuildValue("(ss)", "\r", "\n");
	case NEWLINE_CRLF:
		return PyString_FromString("\r\n");
	case NEWLINE_CR|NEWLINE_CRLF:
		return Py_BuildValue("(ss)", "\r", "\r\n");
	case NEWLINE_LF|NEWLINE_CRLF:
		return Py_BuildValue("(ss)", "\n", "\r\n");
	case NEWLINE_CR|NEWLINE_LF|NEWLINE_CRLF:
		return Py_BuildValue("(sss)", "\r", "\n", "\r\n");
	default:
		PyErr_Format(PyExc_SystemError,
			     "Unknown newlines value 0x%x\n",
			     f->f_newlinetypes);
		return NULL;
	}
}

static PyGetSetDef file_getsetlist[] = {
	{"closed", (getter)get_closed, NULL, "True if the file is closed"},
	{"newlines", (getter)get_newlines, NULL,
	 "end-of-line convention used in this file"},
	{0},
};

static void
drop_readahead(PyFileObject *f)
{
	if (f->f_buf != NULL) {
		PyMem_Free(f->f_buf);
		f->f_buf = NULL;
	}
}

/* Make sure that file has a readahead buffer with at least one byte
   (unless at EOF) and no more than bufsize.  Returns negative value on
   error, will set MemoryError if bufsize bytes cannot be allocated. */
static int
readahead(PyFileObject *f, int bufsize)
{
	Py_ssize_t chunksize;

	if (f->f_buf != NULL) {
		if( (f->f_bufend - f->f_bufptr) >= 1)
			return 0;
		else
			drop_readahead(f);
	}
	if ((f->f_buf = (char *)PyMem_Malloc(bufsize)) == NULL) {
		PyErr_NoMemory();
		return -1;
	}
	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	chunksize = Py_UniversalNewlineFread(
		f->f_buf, bufsize, f->f_fp, (PyObject *)f);
	Py_END_ALLOW_THREADS
	if (chunksize == 0) {
		if (ferror(f->f_fp)) {
			PyErr_SetFromErrno(PyExc_IOError);
			clearerr(f->f_fp);
			drop_readahead(f);
			return -1;
		}
	}
	f->f_bufptr = f->f_buf;
	f->f_bufend = f->f_buf + chunksize;
	return 0;
}

/* Used by file_iternext.  The returned string will start with 'skip'
   uninitialized bytes followed by the remainder of the line. Don't be
   horrified by the recursive call: maximum recursion depth is limited by
   logarithmic buffer growth to about 50 even when reading a 1gb line. */

static PyStringObject *
readahead_get_line_skip(PyFileObject *f, int skip, int bufsize)
{
	PyStringObject* s;
	char *bufptr;
	char *buf;
	Py_ssize_t len;

	if (f->f_buf == NULL)
		if (readahead(f, bufsize) < 0)
			return NULL;

	len = f->f_bufend - f->f_bufptr;
	if (len == 0)
		return (PyStringObject *)
			PyString_FromStringAndSize(NULL, skip);
	bufptr = (char *)memchr(f->f_bufptr, '\n', len);
	if (bufptr != NULL) {
		bufptr++;			/* Count the '\n' */
		len = bufptr - f->f_bufptr;
		s = (PyStringObject *)
			PyString_FromStringAndSize(NULL, skip+len);
		if (s == NULL)
			return NULL;
		memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len);
		f->f_bufptr = bufptr;
		if (bufptr == f->f_bufend)
			drop_readahead(f);
	} else {
		bufptr = f->f_bufptr;
		buf = f->f_buf;
		f->f_buf = NULL; 	/* Force new readahead buffer */
		assert(skip+len < INT_MAX);
                s = readahead_get_line_skip(
			f, (int)(skip+len), bufsize + (bufsize>>2) );
		if (s == NULL) {
		        PyMem_Free(buf);
			return NULL;
		}
		memcpy(PyString_AS_STRING(s)+skip, bufptr, len);
		PyMem_Free(buf);
	}
	return s;
}

/* A larger buffer size may actually decrease performance. */
#define READAHEAD_BUFSIZE 8192

static PyObject *
file_iternext(PyFileObject *f)
{
	PyStringObject* l;

	if (f->f_fp == NULL)
		return err_closed();

	l = readahead_get_line_skip(f, 0, READAHEAD_BUFSIZE);
	if (l == NULL || PyString_GET_SIZE(l) == 0) {
		Py_XDECREF(l);
		return NULL;
	}
	return (PyObject *)l;
}


static PyObject *
file_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *self;
	static PyObject *not_yet_string;

	assert(type != NULL && type->tp_alloc != NULL);

	if (not_yet_string == NULL) {
		not_yet_string = PyString_FromString("<uninitialized file>");
		if (not_yet_string == NULL)
			return NULL;
	}

	self = type->tp_alloc(type, 0);
	if (self != NULL) {
		/* Always fill in the name and mode, so that nobody else
		   needs to special-case NULLs there. */
		Py_INCREF(not_yet_string);
		((PyFileObject *)self)->f_name = not_yet_string;
		Py_INCREF(not_yet_string);
		((PyFileObject *)self)->f_mode = not_yet_string;
		Py_INCREF(Py_None);
		((PyFileObject *)self)->f_encoding = Py_None;
		((PyFileObject *)self)->weakreflist = NULL;
	}
	return self;
}

static int
file_init(PyObject *self, PyObject *args, PyObject *kwds)
{
	PyFileObject *foself = (PyFileObject *)self;
	int ret = 0;
	static char *kwlist[] = {"name", "mode", "buffering", 0};
	char *name = NULL;
	char *mode = "r";
	int bufsize = -1;
	int wideargument = 0;

	assert(PyFile_Check(self));
	if (foself->f_fp != NULL) {
		/* Have to close the existing file first. */
		PyObject *closeresult = file_close(foself);
		if (closeresult == NULL)
			return -1;
		Py_DECREF(closeresult);
	}

#ifdef Py_WIN_WIDE_FILENAMES
	if (GetVersion() < 0x80000000) {    /* On NT, so wide API available */
		PyObject *po;
		if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:file",
						kwlist, &po, &mode, &bufsize)) {
			wideargument = 1;
			if (fill_file_fields(foself, NULL, po, mode,
					     fclose) == NULL)
				goto Error;
		} else {
			/* Drop the argument parsing error as narrow
			   strings are also valid. */
			PyErr_Clear();
		}
	}
#endif

	if (!wideargument) {
                PyObject *o_name;

		if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist,
						 Py_FileSystemDefaultEncoding,
						 &name,
						 &mode, &bufsize))
			return -1;

                /* We parse again to get the name as a PyObject */
                if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:file", 
                                                 kwlist, &o_name, &mode, 
                                                 &bufsize))
                        return -1;

		if (fill_file_fields(foself, NULL, o_name, mode,
				     fclose) == NULL)
			goto Error;
	}
	if (open_the_file(foself, name, mode) == NULL)
		goto Error;
	foself->f_setbuf = NULL;
	PyFile_SetBufSize(self, bufsize);
	goto Done;

Error:
	ret = -1;
	/* fall through */
Done:
	PyMem_Free(name); /* free the encoded string */
	return ret;
}

PyDoc_VAR(file_doc) =
PyDoc_STR(
"file(name[, mode[, buffering]]) -> file object\n"
"\n"
"Open a file.  The mode can be 'r', 'w' or 'a' for reading (default),\n"
"writing or appending.  The file will be created if it doesn't exist\n"
"when opened for writing or appending; it will be truncated when\n"
"opened for writing.  Add a 'b' to the mode for binary files.\n"
"Add a '+' to the mode to allow simultaneous reading and writing.\n"
"If the buffering argument is given, 0 means unbuffered, 1 means line\n"
"buffered, and larger numbers specify the buffer size.\n"
)
PyDoc_STR(
"Add a 'U' to mode to open the file for input with universal newline\n"
"support.  Any line ending in the input file will be seen as a '\\n'\n"
"in Python.  Also, a file so opened gains the attribute 'newlines';\n"
"the value for this attribute is one of None (no newline read yet),\n"
"'\\r', '\\n', '\\r\\n' or a tuple containing all the newline types seen.\n"
"\n"
"'U' cannot be combined with 'w' or '+' mode.\n"
);

PyTypeObject PyFile_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,
	"file",
	sizeof(PyFileObject),
	0,
	(destructor)file_dealloc,		/* tp_dealloc */
	0,					/* tp_print */
	0,			 		/* tp_getattr */
	0,			 		/* tp_setattr */
	0,					/* tp_compare */
	(reprfunc)file_repr, 			/* tp_repr */
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	/* softspace is writable:  we must supply tp_setattro */
	PyObject_GenericSetAttr,		/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
	file_doc,				/* tp_doc */
	0,					/* tp_traverse */
	0,					/* tp_clear */
	0,					/* tp_richcompare */
	offsetof(PyFileObject, weakreflist),	/* tp_weaklistoffset */
	(getiterfunc)file_self,			/* tp_iter */
	(iternextfunc)file_iternext,		/* tp_iternext */
	file_methods,				/* tp_methods */
	file_memberlist,			/* tp_members */
	file_getsetlist,			/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	file_init,				/* tp_init */
	PyType_GenericAlloc,			/* tp_alloc */
	file_new,				/* tp_new */
	PyObject_Del,                           /* tp_free */
};

/* Interface for the 'soft space' between print items. */

int
PyFile_SoftSpace(PyObject *f, int newflag)
{
	long oldflag = 0;
	if (f == NULL) {
		/* Do nothing */
	}
	else if (PyFile_Check(f)) {
		oldflag = ((PyFileObject *)f)->f_softspace;
		((PyFileObject *)f)->f_softspace = newflag;
	}
	else {
		PyObject *v;
		v = PyObject_GetAttrString(f, "softspace");
		if (v == NULL)
			PyErr_Clear();
		else {
			if (PyInt_Check(v))
				oldflag = PyInt_AsLong(v);
			assert(oldflag < INT_MAX);
			Py_DECREF(v);
		}
		v = PyInt_FromLong((long)newflag);
		if (v == NULL)
			PyErr_Clear();
		else {
			if (PyObject_SetAttrString(f, "softspace", v) != 0)
				PyErr_Clear();
			Py_DECREF(v);
		}
	}
	return (int)oldflag;
}

/* Interfaces to write objects/strings to file-like objects */

int
PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
{
	PyObject *writer, *value, *args, *result;
	if (f == NULL) {
		PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
		return -1;
	}
	else if (PyFile_Check(f)) {
		FILE *fp = PyFile_AsFile(f);
#ifdef Py_USING_UNICODE
		PyObject *enc = ((PyFileObject*)f)->f_encoding;
		int result;
#endif
		if (fp == NULL) {
			err_closed();
			return -1;
		}
#ifdef Py_USING_UNICODE
                if ((flags & Py_PRINT_RAW) &&
		    PyUnicode_Check(v) && enc != Py_None) {
			char *cenc = PyString_AS_STRING(enc);
			value = PyUnicode_AsEncodedString(v, cenc, "strict");
			if (value == NULL)
				return -1;
		} else {
			value = v;
			Py_INCREF(value);
		}
		result = PyObject_Print(value, fp, flags);
		Py_DECREF(value);
		return result;
#else
		return PyObject_Print(v, fp, flags);
#endif
	}
	writer = PyObject_GetAttrString(f, "write");
	if (writer == NULL)
		return -1;
	if (flags & Py_PRINT_RAW) {
                if (PyUnicode_Check(v)) {
                        value = v;
                        Py_INCREF(value);
                } else
                        value = PyObject_Str(v);
	}
        else
		value = PyObject_Repr(v);
	if (value == NULL) {
		Py_DECREF(writer);
		return -1;
	}
	args = PyTuple_Pack(1, value);
	if (args == NULL) {
		Py_DECREF(value);
		Py_DECREF(writer);
		return -1;
	}
	result = PyEval_CallObject(writer, args);
	Py_DECREF(args);
	Py_DECREF(value);
	Py_DECREF(writer);
	if (result == NULL)
		return -1;
	Py_DECREF(result);
	return 0;
}

int
PyFile_WriteString(const char *s, PyObject *f)
{
	if (f == NULL) {
		/* Should be caused by a pre-existing error */
		if (!PyErr_Occurred())
			PyErr_SetString(PyExc_SystemError,
					"null file for PyFile_WriteString");
		return -1;
	}
	else if (PyFile_Check(f)) {
		FILE *fp = PyFile_AsFile(f);
		if (fp == NULL) {
			err_closed();
			return -1;
		}
		fputs(s, fp);
		return 0;
	}
	else if (!PyErr_Occurred()) {
		PyObject *v = PyString_FromString(s);
		int err;
		if (v == NULL)
			return -1;
		err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
		Py_DECREF(v);
		return err;
	}
	else
		return -1;
}

/* Try to get a file-descriptor from a Python object.  If the object
   is an integer or long integer, its value is returned.  If not, the
   object's fileno() method is called if it exists; the method must return
   an integer or long integer, which is returned as the file descriptor value.
   -1 is returned on failure.
*/

int PyObject_AsFileDescriptor(PyObject *o)
{
	int fd;
	PyObject *meth;

	if (PyInt_Check(o)) {
		fd = PyInt_AsLong(o);
	}
	else if (PyLong_Check(o)) {
		fd = PyLong_AsLong(o);
	}
	else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
	{
		PyObject *fno = PyEval_CallObject(meth, NULL);
		Py_DECREF(meth);
		if (fno == NULL)
			return -1;

		if (PyInt_Check(fno)) {
			fd = PyInt_AsLong(fno);
			Py_DECREF(fno);
		}
		else if (PyLong_Check(fno)) {
			fd = PyLong_AsLong(fno);
			Py_DECREF(fno);
		}
		else {
			PyErr_SetString(PyExc_TypeError,
					"fileno() returned a non-integer");
			Py_DECREF(fno);
			return -1;
		}
	}
	else {
		PyErr_SetString(PyExc_TypeError,
				"argument must be an int, or have a fileno() method.");
		return -1;
	}

	if (fd < 0) {
		PyErr_Format(PyExc_ValueError,
			     "file descriptor cannot be a negative integer (%i)",
			     fd);
		return -1;
	}
	return fd;
}

/* From here on we need access to the real fgets and fread */
#undef fgets
#undef fread

/*
** Py_UniversalNewlineFgets is an fgets variation that understands
** all of \r, \n and \r\n conventions.
** The stream should be opened in binary mode.
** If fobj is NULL the routine always does newline conversion, and
** it may peek one char ahead to gobble the second char in \r\n.
** If fobj is non-NULL it must be a PyFileObject. In this case there
** is no readahead but in stead a flag is used to skip a following
** \n on the next read. Also, if the file is open in binary mode
** the whole conversion is skipped. Finally, the routine keeps track of
** the different types of newlines seen.
** Note that we need no error handling: fgets() treats error and eof
** identically.
*/
char *
Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
{
	char *p = buf;
	int c;
	int newlinetypes = 0;
	int skipnextlf = 0;
	int univ_newline = 1;

	if (fobj) {
		if (!PyFile_Check(fobj)) {
			errno = ENXIO;	/* What can you do... */
			return NULL;
		}
		univ_newline = ((PyFileObject *)fobj)->f_univ_newline;
		if ( !univ_newline )
			return fgets(buf, n, stream);
		newlinetypes = ((PyFileObject *)fobj)->f_newlinetypes;
		skipnextlf = ((PyFileObject *)fobj)->f_skipnextlf;
	}
	FLOCKFILE(stream);
	c = 'x'; /* Shut up gcc warning */
	while (--n > 0 && (c = GETC(stream)) != EOF ) {
		if (skipnextlf ) {
			skipnextlf = 0;
			if (c == '\n') {
				/* Seeing a \n here with skipnextlf true
				** means we saw a \r before.
				*/
				newlinetypes |= NEWLINE_CRLF;
				c = GETC(stream);
				if (c == EOF) break;
			} else {
				/*
				** Note that c == EOF also brings us here,
				** so we're okay if the last char in the file
				** is a CR.
				*/
				newlinetypes |= NEWLINE_CR;
			}
		}
		if (c == '\r') {
			/* A \r is translated into a \n, and we skip
			** an adjacent \n, if any. We don't set the
			** newlinetypes flag until we've seen the next char.
			*/
			skipnextlf = 1;
			c = '\n';
		} else if ( c == '\n') {
			newlinetypes |= NEWLINE_LF;
		}
		*p++ = c;
		if (c == '\n') break;
	}
	if ( c == EOF && skipnextlf )
		newlinetypes |= NEWLINE_CR;
	FUNLOCKFILE(stream);
	*p = '\0';
	if (fobj) {
		((PyFileObject *)fobj)->f_newlinetypes = newlinetypes;
		((PyFileObject *)fobj)->f_skipnextlf = skipnextlf;
	} else if ( skipnextlf ) {
		/* If we have no file object we cannot save the
		** skipnextlf flag. We have to readahead, which
		** will cause a pause if we're reading from an
		** interactive stream, but that is very unlikely
		** unless we're doing something silly like
		** execfile("/dev/tty").
		*/
		c = GETC(stream);
		if ( c != '\n' )
			ungetc(c, stream);
	}
	if (p == buf)
		return NULL;
	return buf;
}

/*
** Py_UniversalNewlineFread is an fread variation that understands
** all of \r, \n and \r\n conventions.
** The stream should be opened in binary mode.
** fobj must be a PyFileObject. In this case there
** is no readahead but in stead a flag is used to skip a following
** \n on the next read. Also, if the file is open in binary mode
** the whole conversion is skipped. Finally, the routine keeps track of
** the different types of newlines seen.
*/
size_t
Py_UniversalNewlineFread(char *buf, size_t n,
			 FILE *stream, PyObject *fobj)
{
	char *dst = buf;
	PyFileObject *f = (PyFileObject *)fobj;
	int newlinetypes, skipnextlf;

	assert(buf != NULL);
	assert(stream != NULL);

	if (!fobj || !PyFile_Check(fobj)) {
		errno = ENXIO;	/* What can you do... */
		return 0;
	}
	if (!f->f_univ_newline)
		return fread(buf, 1, n, stream);
	newlinetypes = f->f_newlinetypes;
	skipnextlf = f->f_skipnextlf;
	/* Invariant:  n is the number of bytes remaining to be filled
	 * in the buffer.
	 */
	while (n) {
		size_t nread;
		int shortread;
		char *src = dst;

		nread = fread(dst, 1, n, stream);
		assert(nread <= n);
		if (nread == 0)
			break;

		n -= nread; /* assuming 1 byte out for each in; will adjust */
		shortread = n != 0;	/* true iff EOF or error */
		while (nread--) {
			char c = *src++;
			if (c == '\r') {
				/* Save as LF and set flag to skip next LF. */
				*dst++ = '\n';
				skipnextlf = 1;
			}
			else if (skipnextlf && c == '\n') {
				/* Skip LF, and remember we saw CR LF. */
				skipnextlf = 0;
				newlinetypes |= NEWLINE_CRLF;
				++n;
			}
			else {
				/* Normal char to be stored in buffer.  Also
				 * update the newlinetypes flag if either this
				 * is an LF or the previous char was a CR.
				 */
				if (c == '\n')
					newlinetypes |= NEWLINE_LF;
				else if (skipnextlf)
					newlinetypes |= NEWLINE_CR;
				*dst++ = c;
				skipnextlf = 0;
			}
		}
		if (shortread) {
			/* If this is EOF, update type flags. */
			if (skipnextlf && feof(stream))
				newlinetypes |= NEWLINE_CR;
			break;
		}
	}
	f->f_newlinetypes = newlinetypes;
	f->f_skipnextlf = skipnextlf;
	return dst - buf;
}

#ifdef __cplusplus
}
#endif
