| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | /* Author: Daniel Stutzbach */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PY_SSIZE_T_CLEAN
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #include <stddef.h> /* For offsetof */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Known likely problems: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - Files larger then 2**32-1 | 
					
						
							|  |  |  |  * - Files with unicode filenames | 
					
						
							|  |  |  |  * - Passing numbers greater than 2**32-1 when an integer is expected | 
					
						
							|  |  |  |  * - Making it work on Windows and other oddball platforms | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * To Do: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - autoconfify header file inclusion | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | /* can simulate truncate with Win32 API functions; see file_truncate */ | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | #define HAVE_FTRUNCATE
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | #define WIN32_LEAN_AND_MEAN
 | 
					
						
							|  |  |  | #include <windows.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	int fd; | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 	unsigned readable : 1; | 
					
						
							|  |  |  | 	unsigned writable : 1; | 
					
						
							|  |  |  | 	int seekable : 2; /* -1 means unknown */ | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 	int closefd : 1; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	PyObject *weakreflist; | 
					
						
							|  |  |  | } PyFileIOObject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 21:46:15 +00:00
										 |  |  | PyTypeObject PyFileIO_Type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | /* Returns 0 on success, errno (which is < 0) on failure. */ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | internal_close(PyFileIOObject *self) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 	int save_errno = 0; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	if (self->fd >= 0) { | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 		int fd = self->fd; | 
					
						
							|  |  |  | 		self->fd = -1; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		Py_BEGIN_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 		if (close(fd) < 0) | 
					
						
							|  |  |  | 			save_errno = errno; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		Py_END_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return save_errno; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_close(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 	if (!self->closefd) { | 
					
						
							|  |  |  | 		if (PyErr_WarnEx(PyExc_RuntimeWarning, | 
					
						
							|  |  |  | 				 "Trying to close unclosable fd!", 3) < 0) { | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_RETURN_NONE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 	errno = internal_close(self); | 
					
						
							|  |  |  | 	if (errno < 0) { | 
					
						
							|  |  |  | 		PyErr_SetFromErrno(PyExc_IOError); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_new(PyTypeObject *type, PyObject *args, PyObject *kews) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyFileIOObject *self; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert(type != NULL && type->tp_alloc != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	self = (PyFileIOObject *) type->tp_alloc(type, 0); | 
					
						
							|  |  |  | 	if (self != NULL) { | 
					
						
							|  |  |  | 		self->fd = -1; | 
					
						
							|  |  |  | 		self->weakreflist = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *) self; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* On Unix, open will succeed for directories.
 | 
					
						
							|  |  |  |    In Python, there should be no file objects referring to | 
					
						
							|  |  |  |    directories, so we need a check.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | dircheck(PyFileIOObject* self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
 | 
					
						
							|  |  |  | 	struct stat buf; | 
					
						
							|  |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { | 
					
						
							|  |  |  | #ifdef HAVE_STRERROR
 | 
					
						
							|  |  |  | 		char *msg = strerror(EISDIR); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 		char *msg = "Is a directory"; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		PyObject *exc; | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 		internal_close(self); | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		exc = PyObject_CallFunction(PyExc_IOError, "(is)", | 
					
						
							|  |  |  | 					    EISDIR, msg); | 
					
						
							|  |  |  | 		PyErr_SetObject(PyExc_IOError, exc); | 
					
						
							|  |  |  | 		Py_XDECREF(exc); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyFileIOObject *self = (PyFileIOObject *) oself; | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 	static char *kwlist[] = {"file", "mode", "closefd", NULL}; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	char *name = NULL; | 
					
						
							|  |  |  | 	char *mode = "r"; | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	char *s; | 
					
						
							| 
									
										
										
										
											2007-07-12 11:03:13 +00:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | 	Py_UNICODE *widename = NULL; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	int ret = 0; | 
					
						
							|  |  |  | 	int rwa = 0, plus = 0, append = 0; | 
					
						
							|  |  |  | 	int flags = 0; | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 	int fd = -1; | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 	int closefd = 1; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	assert(PyFileIO_Check(oself)); | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 	if (self->fd >= 0) { | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		/* Have to close the existing file first. */ | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 		if (internal_close(self) < 0) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 	if (PyArg_ParseTupleAndKeywords(args, kwds, "i|si:fileio", | 
					
						
							|  |  |  | 					kwlist, &fd, &mode, &closefd)) { | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 		if (fd < 0) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  | 					"Negative filedescriptor"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | #ifdef Py_WIN_WIDE_FILENAMES
 | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 	    if (GetVersion() < 0x80000000) { | 
					
						
							|  |  |  | 		/* On NT, so wide API available */ | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		PyObject *po; | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 		if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:fileio", | 
					
						
							|  |  |  | 						kwlist, &po, &mode, &closefd) | 
					
						
							|  |  |  | 						) { | 
					
						
							| 
									
										
										
										
											2007-07-12 11:03:13 +00:00
										 |  |  | 			widename = PyUnicode_AS_UNICODE(po); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			/* Drop the argument parsing error as narrow
 | 
					
						
							|  |  |  | 			   strings are also valid. */ | 
					
						
							|  |  |  | 			PyErr_Clear(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 	    if (widename == NULL) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-07-12 11:03:13 +00:00
										 |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 		if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:fileio", | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 						 kwlist, | 
					
						
							|  |  |  | 						 Py_FileSystemDefaultEncoding, | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 						 &name, &mode, &closefd)) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 			goto error; | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	self->readable = self->writable = 0; | 
					
						
							| 
									
										
										
										
											2007-07-12 11:03:13 +00:00
										 |  |  | 	self->seekable = -1; | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	s = mode; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	while (*s) { | 
					
						
							|  |  |  | 		switch (*s++) { | 
					
						
							|  |  |  | 		case 'r': | 
					
						
							|  |  |  | 			if (rwa) { | 
					
						
							|  |  |  | 			bad_mode: | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  | 						"Must have exactly one of read/write/append mode"); | 
					
						
							|  |  |  | 				goto error; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rwa = 1; | 
					
						
							|  |  |  | 			self->readable = 1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case 'w': | 
					
						
							|  |  |  | 			if (rwa) | 
					
						
							|  |  |  | 				goto bad_mode; | 
					
						
							|  |  |  | 			rwa = 1; | 
					
						
							|  |  |  | 			self->writable = 1; | 
					
						
							|  |  |  | 			flags |= O_CREAT | O_TRUNC; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case 'a': | 
					
						
							|  |  |  | 			if (rwa) | 
					
						
							|  |  |  | 				goto bad_mode; | 
					
						
							|  |  |  | 			rwa = 1; | 
					
						
							|  |  |  | 			self->writable = 1; | 
					
						
							|  |  |  | 			flags |= O_CREAT; | 
					
						
							|  |  |  | 			append = 1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case '+': | 
					
						
							|  |  |  | 			if (plus) | 
					
						
							|  |  |  | 				goto bad_mode; | 
					
						
							|  |  |  | 			self->readable = self->writable = 1; | 
					
						
							|  |  |  | 			plus = 1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  | 				     "invalid mode: %.200s", mode); | 
					
						
							|  |  |  | 			goto error; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!rwa) | 
					
						
							|  |  |  | 		goto bad_mode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (self->readable && self->writable) | 
					
						
							|  |  |  | 		flags |= O_RDWR; | 
					
						
							|  |  |  | 	else if (self->readable) | 
					
						
							|  |  |  | 		flags |= O_RDONLY; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		flags |= O_WRONLY; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef O_BINARY
 | 
					
						
							|  |  |  | 	flags |= O_BINARY; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-06 16:55:38 +00:00
										 |  |  | #ifdef O_APPEND
 | 
					
						
							|  |  |  | 	if (append) | 
					
						
							|  |  |  | 		flags |= O_APPEND; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 	if (fd >= 0) { | 
					
						
							|  |  |  | 		self->fd = fd; | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 		self->closefd = closefd; | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 		self->closefd = 1; | 
					
						
							|  |  |  | 		if (!closefd) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  |                             "Cannot use closefd=True with file name"); | 
					
						
							|  |  |  | 			goto error; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 		Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 		errno = 0; | 
					
						
							| 
									
										
										
										
											2007-07-12 11:03:13 +00:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | 		if (widename != NULL) | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 			self->fd = _wopen(widename, flags, 0666); | 
					
						
							| 
									
										
										
										
											2007-07-12 11:03:13 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 			self->fd = open(name, flags, 0666); | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 		Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 		if (self->fd < 0 || dircheck(self) < 0) { | 
					
						
							| 
									
										
										
										
											2007-10-31 19:20:48 +00:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | 			PyErr_SetFromErrnoWithUnicodeFilename(PyExc_IOError, widename); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 			PyErr_SetFromErrnoWithFilename(PyExc_IOError, name); | 
					
						
							| 
									
										
										
										
											2007-10-31 19:20:48 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 			goto error; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	goto done; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  error: | 
					
						
							|  |  |  | 	ret = -1; | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  |  done: | 
					
						
							|  |  |  | 	PyMem_Free(name); | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | fileio_dealloc(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->weakreflist != NULL) | 
					
						
							|  |  |  | 		PyObject_ClearWeakRefs((PyObject *) self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-30 17:27:30 +00:00
										 |  |  | 	if (self->fd >= 0 && self->closefd) { | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 		errno = internal_close(self); | 
					
						
							|  |  |  | 		if (errno < 0) { | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | #ifdef HAVE_STRERROR
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 			PySys_WriteStderr("close failed: [Errno %d] %s\n", | 
					
						
							|  |  |  |                                           errno, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 			PySys_WriteStderr("close failed: [Errno %d]\n", errno); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Merged revisions 56467-56482 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/p3yk
................
  r56477 | martin.v.loewis | 2007-07-21 09:04:38 +0200 (Sa, 21 Jul 2007) | 11 lines
  Merged revisions 56466-56476 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk
  ........
    r56476 | martin.v.loewis | 2007-07-21 08:55:02 +0200 (Sa, 21 Jul 2007) | 4 lines
    PEP 3123: Provide forward compatibility with Python 3.0, while keeping
    backwards compatibility. Add Py_Refcnt, Py_Type, Py_Size, and
    PyVarObject_HEAD_INIT.
  ........
................
  r56478 | martin.v.loewis | 2007-07-21 09:47:23 +0200 (Sa, 21 Jul 2007) | 2 lines
  PEP 3123: Use proper C inheritance for PyObject.
................
  r56479 | martin.v.loewis | 2007-07-21 10:06:55 +0200 (Sa, 21 Jul 2007) | 3 lines
  Add longintrepr.h to Python.h, so that the compiler can
  see that PyFalse is really some kind of PyObject*.
................
  r56480 | martin.v.loewis | 2007-07-21 10:47:18 +0200 (Sa, 21 Jul 2007) | 2 lines
  Qualify SHIFT, MASK, BASE.
................
  r56482 | martin.v.loewis | 2007-07-21 19:10:57 +0200 (Sa, 21 Jul 2007) | 2 lines
  Correctly refer to _ob_next.
................
											
										 
											2007-07-21 17:22:18 +00:00
										 |  |  | 	Py_Type(self)->tp_free((PyObject *)self); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | err_closed(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | err_mode(char *action) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyErr_Format(PyExc_ValueError, "File not open for %s", action); | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_fileno(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							|  |  |  | 	return PyInt_FromLong((long) self->fd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_readable(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 	return PyBool_FromLong((long) self->readable); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_writable(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 	return PyBool_FromLong((long) self->writable); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_seekable(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							|  |  |  | 	if (self->seekable < 0) { | 
					
						
							|  |  |  | 		int ret; | 
					
						
							|  |  |  | 		Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 		ret = lseek(self->fd, 0, SEEK_CUR); | 
					
						
							|  |  |  | 		Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 		if (ret < 0) | 
					
						
							|  |  |  | 			self->seekable = 0; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			self->seekable = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | 	return PyBool_FromLong((long) self->seekable); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_readinto(PyFileIOObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char *ptr; | 
					
						
							|  |  |  | 	Py_ssize_t n; | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	if (!self->readable) | 
					
						
							|  |  |  | 		return err_mode("reading"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(args, "w#", &ptr, &n)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 	errno = 0; | 
					
						
							|  |  |  | 	n = read(self->fd, ptr, n); | 
					
						
							|  |  |  | 	Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 	if (n < 0) { | 
					
						
							|  |  |  | 		if (errno == EAGAIN) | 
					
						
							|  |  |  | 			Py_RETURN_NONE; | 
					
						
							|  |  |  | 		PyErr_SetFromErrno(PyExc_IOError); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 	return PyInt_FromSsize_t(n); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-10 06:54:34 +00:00
										 |  |  | #define DEFAULT_BUFFER_SIZE (8*1024)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_readall(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *result; | 
					
						
							|  |  |  | 	Py_ssize_t total = 0; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | 	result = PyString_FromStringAndSize(NULL, DEFAULT_BUFFER_SIZE); | 
					
						
							| 
									
										
										
										
											2007-07-10 06:54:34 +00:00
										 |  |  | 	if (result == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (1) { | 
					
						
							|  |  |  | 		Py_ssize_t newsize = total + DEFAULT_BUFFER_SIZE; | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | 		if (PyString_GET_SIZE(result) < newsize) { | 
					
						
							|  |  |  | 			if (_PyString_Resize(&result, newsize) < 0) { | 
					
						
							| 
									
										
										
										
											2007-07-10 06:54:34 +00:00
										 |  |  | 				if (total == 0) { | 
					
						
							|  |  |  | 					Py_DECREF(result); | 
					
						
							|  |  |  | 					return NULL; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				PyErr_Clear(); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 		errno = 0; | 
					
						
							|  |  |  | 		n = read(self->fd, | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | 			 PyString_AS_STRING(result) + total, | 
					
						
							| 
									
										
										
										
											2007-07-10 06:54:34 +00:00
										 |  |  | 			 newsize - total); | 
					
						
							|  |  |  | 		Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 		if (n == 0) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		if (n < 0) { | 
					
						
							|  |  |  | 			if (total > 0) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			if (errno == EAGAIN) { | 
					
						
							|  |  |  | 				Py_DECREF(result); | 
					
						
							|  |  |  | 				Py_RETURN_NONE; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			Py_DECREF(result); | 
					
						
							|  |  |  | 			PyErr_SetFromErrno(PyExc_IOError); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		total += n; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | 	if (PyString_GET_SIZE(result) > total) { | 
					
						
							|  |  |  | 		if (_PyString_Resize(&result, total) < 0) { | 
					
						
							| 
									
										
										
										
											2007-07-10 06:54:34 +00:00
										 |  |  | 			/* This should never happen, but just in case */ | 
					
						
							|  |  |  | 			Py_DECREF(result); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_read(PyFileIOObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char *ptr; | 
					
						
							| 
									
										
										
										
											2007-07-10 06:54:34 +00:00
										 |  |  | 	Py_ssize_t n; | 
					
						
							|  |  |  | 	Py_ssize_t size = -1; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	PyObject *bytes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	if (!self->readable) | 
					
						
							|  |  |  | 		return err_mode("reading"); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-08 04:36:17 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(args, "|n", &size)) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-24 00:50:02 +00:00
										 |  |  |         if (size < 0) { | 
					
						
							| 
									
										
										
										
											2007-07-10 06:54:34 +00:00
										 |  |  | 		return fileio_readall(self); | 
					
						
							| 
									
										
										
										
											2007-05-24 00:50:02 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | 	bytes = PyString_FromStringAndSize(NULL, size); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	if (bytes == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | 	ptr = PyString_AS_STRING(bytes); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 	errno = 0; | 
					
						
							|  |  |  | 	n = read(self->fd, ptr, size); | 
					
						
							|  |  |  | 	Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (n < 0) { | 
					
						
							|  |  |  | 		if (errno == EAGAIN) | 
					
						
							|  |  |  | 			Py_RETURN_NONE; | 
					
						
							|  |  |  | 		PyErr_SetFromErrno(PyExc_IOError); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (n != size) { | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | 		if (_PyString_Resize(&bytes, n) < 0) { | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 			Py_DECREF(bytes); | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject *) bytes; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_write(PyFileIOObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Py_ssize_t n; | 
					
						
							|  |  |  | 	char *ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	if (!self->writable) | 
					
						
							|  |  |  | 		return err_mode("writing"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(args, "s#", &ptr, &n)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 	errno = 0; | 
					
						
							|  |  |  | 	n = write(self->fd, ptr, n); | 
					
						
							|  |  |  | 	Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (n < 0) { | 
					
						
							|  |  |  | 		if (errno == EAGAIN) | 
					
						
							|  |  |  | 			Py_RETURN_NONE; | 
					
						
							|  |  |  | 		PyErr_SetFromErrno(PyExc_IOError); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-12 17:23:54 +00:00
										 |  |  | 	return PyInt_FromSsize_t(n); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | /* XXX Windows support below is likely incomplete */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MS_WIN64) || defined(MS_WINDOWS)
 | 
					
						
							|  |  |  | typedef PY_LONG_LONG Py_off_t; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | typedef off_t Py_off_t; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Cribbed from posix_lseek() */ | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | portable_lseek(int fd, PyObject *posobj, int whence) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	Py_off_t pos, res; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | #ifdef SEEK_SET
 | 
					
						
							|  |  |  | 	/* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ | 
					
						
							|  |  |  | 	switch (whence) { | 
					
						
							|  |  |  | #if SEEK_SET != 0
 | 
					
						
							|  |  |  | 	case 0: whence = SEEK_SET; break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if SEEK_CUR != 1
 | 
					
						
							|  |  |  | 	case 1: whence = SEEK_CUR; break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if SEEL_END != 2
 | 
					
						
							|  |  |  | 	case 2: whence = SEEK_END; break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif /* SEEK_SET */
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	if (posobj == NULL) | 
					
						
							|  |  |  | 		pos = 0; | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | #if !defined(HAVE_LARGEFILE_SUPPORT)
 | 
					
						
							|  |  |  | 		pos = PyInt_AsLong(posobj); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 		pos = PyLong_Check(posobj) ? | 
					
						
							|  |  |  | 			PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		if (PyErr_Occurred()) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Py_BEGIN_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | #if defined(MS_WIN64) || defined(MS_WINDOWS)
 | 
					
						
							|  |  |  | 	res = _lseeki64(fd, pos, whence); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	res = lseek(fd, pos, whence); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	Py_END_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	if (res < 0) | 
					
						
							|  |  |  | 		return PyErr_SetFromErrno(PyExc_IOError); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | #if !defined(HAVE_LARGEFILE_SUPPORT)
 | 
					
						
							|  |  |  | 	return PyInt_FromLong(res); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	return PyLong_FromLongLong(res); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | fileio_seek(PyFileIOObject *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	PyObject *posobj; | 
					
						
							|  |  |  | 	int whence = 0; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(args, "O|i", &posobj, &whence)) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	return portable_lseek(self->fd, posobj, whence); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | fileio_tell(PyFileIOObject *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	return portable_lseek(self->fd, NULL, 1); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-11 12:45:46 +00:00
										 |  |  | #ifdef HAVE_FTRUNCATE
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_truncate(PyFileIOObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *posobj = NULL; | 
					
						
							|  |  |  | 	Py_off_t pos; | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2007-04-12 22:55:07 +00:00
										 |  |  | 	int fd; | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	fd = self->fd; | 
					
						
							|  |  |  | 	if (fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							|  |  |  | 	if (!self->writable) | 
					
						
							|  |  |  | 		return err_mode("writing"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTuple(args, "|O", &posobj)) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-12 22:55:07 +00:00
										 |  |  | 	if (posobj == Py_None || posobj == NULL) { | 
					
						
							|  |  |  |                 posobj = portable_lseek(fd, NULL, 1); | 
					
						
							|  |  |  |                 if (posobj == NULL) | 
					
						
							|  |  |  |                   return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  | 		Py_INCREF(posobj); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if !defined(HAVE_LARGEFILE_SUPPORT)
 | 
					
						
							|  |  |  | 	pos = PyInt_AsLong(posobj); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	pos = PyLong_Check(posobj) ? | 
					
						
							|  |  |  | 		PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-04-10 21:06:59 +00:00
										 |  |  | 	if (PyErr_Occurred()) { | 
					
						
							|  |  |  | 		Py_DECREF(posobj); | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-04-10 21:06:59 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | #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; | 
					
						
							| 
									
										
										
										
											2007-10-26 17:19:33 +00:00
										 |  |  | 		PyObject *pos2, *oldposobj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* store the current position */ | 
					
						
							|  |  |  | 		oldposobj = portable_lseek(self->fd, NULL, 1); | 
					
						
							|  |  |  | 		if (oldposobj == NULL) { | 
					
						
							|  |  |  | 			Py_DECREF(posobj); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* Have to move current pos to desired endpoint on Windows. */ | 
					
						
							|  |  |  | 		errno = 0; | 
					
						
							|  |  |  | 		pos2 = portable_lseek(fd, posobj, SEEK_SET); | 
					
						
							| 
									
										
										
										
											2007-10-26 17:19:33 +00:00
										 |  |  | 		if (pos2 == NULL) { | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | 			Py_DECREF(posobj); | 
					
						
							| 
									
										
										
										
											2007-10-26 17:19:33 +00:00
										 |  |  | 			Py_DECREF(oldposobj); | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_DECREF(pos2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Truncate.  Note that this may grow the file! */ | 
					
						
							|  |  |  | 		Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 		errno = 0; | 
					
						
							|  |  |  | 		hFile = (HANDLE)_get_osfhandle(fd); | 
					
						
							|  |  |  | 		ret = hFile == (HANDLE)-1; | 
					
						
							|  |  |  | 		if (ret == 0) { | 
					
						
							|  |  |  | 			ret = SetEndOfFile(hFile) == 0; | 
					
						
							|  |  |  | 			if (ret) | 
					
						
							|  |  |  | 				errno = EACCES; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_END_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											2007-10-26 17:19:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (ret == 0) { | 
					
						
							|  |  |  | 			/* Move to the previous position in the file */ | 
					
						
							|  |  |  | 			pos2 = portable_lseek(fd, oldposobj, SEEK_SET); | 
					
						
							|  |  |  | 			if (pos2 == NULL) { | 
					
						
							|  |  |  | 				Py_DECREF(posobj); | 
					
						
							|  |  |  | 				Py_DECREF(oldposobj); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_DECREF(pos2); | 
					
						
							|  |  |  | 		Py_DECREF(oldposobj); | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 	errno = 0; | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | 	ret = ftruncate(fd, pos); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	Py_END_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | #endif /* !MS_WINDOWS */
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | 	if (ret != 0) { | 
					
						
							| 
									
										
										
										
											2007-04-10 21:06:59 +00:00
										 |  |  | 		Py_DECREF(posobj); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 		PyErr_SetFromErrno(PyExc_IOError); | 
					
						
							| 
									
										
										
										
											2007-07-12 11:21:36 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-04-10 21:06:59 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 21:06:59 +00:00
										 |  |  | 	return posobj; | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-07-11 12:45:46 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							|  |  |  | mode_string(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->readable) { | 
					
						
							|  |  |  | 		if (self->writable) | 
					
						
							|  |  |  | 			return "r+"; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return "r"; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return "w"; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_repr(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  |         if (self->fd < 0) | 
					
						
							| 
									
										
										
										
											2007-05-18 17:15:44 +00:00
										 |  |  | 		return PyUnicode_FromFormat("_fileio._FileIO(-1)"); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-18 17:15:44 +00:00
										 |  |  | 	return PyUnicode_FromFormat("_fileio._FileIO(%d, '%s')", | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 				   self->fd, mode_string(self)); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | fileio_isatty(PyFileIOObject *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	long res; | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	if (self->fd < 0) | 
					
						
							|  |  |  | 		return err_closed(); | 
					
						
							|  |  |  | 	Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 	res = isatty(self->fd); | 
					
						
							|  |  |  | 	Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 	return PyBool_FromLong(res); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(fileio_doc, | 
					
						
							|  |  |  | "file(name: str[, mode: str]) -> file IO 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 '+' to the mode to allow simultaneous\n" | 
					
						
							|  |  |  | "reading and writing."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(read_doc, | 
					
						
							|  |  |  | "read(size: int) -> bytes.  read at most size bytes, returned as bytes.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "Only makes one system call, so less data may be returned than requested\n" | 
					
						
							| 
									
										
										
										
											2007-07-10 06:54:34 +00:00
										 |  |  | "In non-blocking mode, returns None if no data is available.\n" | 
					
						
							|  |  |  | "On end-of-file, returns ''."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(readall_doc, | 
					
						
							|  |  |  | "readall() -> bytes.  read all data from the file, returned as bytes.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "In non-blocking mode, returns as much as is immediately available,\n" | 
					
						
							|  |  |  | "or None if no data is available.  On end-of-file, returns ''."); | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(write_doc, | 
					
						
							|  |  |  | "write(b: bytes) -> int.  Write bytes b to file, return number written.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "Only makes one system call, so not all of the data may be written.\n" | 
					
						
							|  |  |  | "The number of bytes actually written is returned."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(fileno_doc, | 
					
						
							|  |  |  | "fileno() -> int. \"file descriptor\".\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "This is needed for lower-level file interfaces, such the fcntl module."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(seek_doc, | 
					
						
							|  |  |  | "seek(offset: int[, whence: int]) -> 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)." | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "Note that not all file objects are seekable."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-11 12:45:46 +00:00
										 |  |  | #ifdef HAVE_FTRUNCATE
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | PyDoc_STRVAR(truncate_doc, | 
					
						
							|  |  |  | "truncate([size: int]) -> None.	 Truncate the file to at most size bytes.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "Size defaults to the current file position, as returned by tell()."); | 
					
						
							| 
									
										
										
										
											2007-07-11 12:45:46 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(tell_doc, | 
					
						
							|  |  |  | "tell() -> int.	 Current file position"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(readinto_doc, | 
					
						
							|  |  |  | "readinto() -> Undocumented.  Don't use this; it may go away."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(close_doc, | 
					
						
							|  |  |  | "close() -> None.  Close the file.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "A closed file cannot be used for further I/O operations.  close() may be\n" | 
					
						
							|  |  |  | "called more than once without error.  Changes the fileno to -1."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(isatty_doc, | 
					
						
							|  |  |  | "isatty() -> bool.  True if the file is connected to a tty device."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(seekable_doc, | 
					
						
							|  |  |  | "seekable() -> bool.  True if file supports random-access."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(readable_doc, | 
					
						
							|  |  |  | "readable() -> bool.  True if file was opened in a read mode."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(writable_doc, | 
					
						
							|  |  |  | "writable() -> bool.  True if file was opened in a write mode."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef fileio_methods[] = { | 
					
						
							|  |  |  | 	{"read",     (PyCFunction)fileio_read,	   METH_VARARGS, read_doc}, | 
					
						
							| 
									
										
										
										
											2007-07-10 06:54:34 +00:00
										 |  |  | 	{"readall",  (PyCFunction)fileio_readall,  METH_NOARGS,  readall_doc}, | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	{"readinto", (PyCFunction)fileio_readinto, METH_VARARGS, readinto_doc}, | 
					
						
							|  |  |  | 	{"write",    (PyCFunction)fileio_write,	   METH_VARARGS, write_doc}, | 
					
						
							|  |  |  | 	{"seek",     (PyCFunction)fileio_seek,	   METH_VARARGS, seek_doc}, | 
					
						
							|  |  |  | 	{"tell",     (PyCFunction)fileio_tell,	   METH_VARARGS, tell_doc}, | 
					
						
							| 
									
										
										
										
											2007-07-11 12:45:46 +00:00
										 |  |  | #ifdef HAVE_FTRUNCATE
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	{"truncate", (PyCFunction)fileio_truncate, METH_VARARGS, truncate_doc}, | 
					
						
							| 
									
										
										
										
											2007-07-11 12:45:46 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	{"close",    (PyCFunction)fileio_close,	   METH_NOARGS,	 close_doc}, | 
					
						
							|  |  |  | 	{"seekable", (PyCFunction)fileio_seekable, METH_NOARGS,	 seekable_doc}, | 
					
						
							|  |  |  | 	{"readable", (PyCFunction)fileio_readable, METH_NOARGS,	 readable_doc}, | 
					
						
							|  |  |  | 	{"writable", (PyCFunction)fileio_writable, METH_NOARGS,	 writable_doc}, | 
					
						
							|  |  |  | 	{"fileno",   (PyCFunction)fileio_fileno,   METH_NOARGS,	 fileno_doc}, | 
					
						
							|  |  |  | 	{"isatty",   (PyCFunction)fileio_isatty,   METH_NOARGS,	 isatty_doc}, | 
					
						
							|  |  |  | 	{NULL,	     NULL}	       /* sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | /* 'closed' and 'mode' are attributes for backwards compatibility reasons. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_closed(PyFileIOObject *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return PyBool_FromLong((long)(self->fd < 0)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | get_mode(PyFileIOObject *self, void *closure) | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-06-18 18:26:36 +00:00
										 |  |  | 	return PyUnicode_FromString(mode_string(self)); | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyGetSetDef fileio_getsetlist[] = { | 
					
						
							|  |  |  | 	{"closed", (getter)get_closed, NULL, "True if the file is closed"}, | 
					
						
							| 
									
										
										
										
											2007-04-10 19:01:47 +00:00
										 |  |  | 	{"mode", (getter)get_mode, NULL, "String giving the file mode"}, | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 	{0}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | PyTypeObject PyFileIO_Type = { | 
					
						
							| 
									
										
											  
											
												Merged revisions 56467-56482 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/p3yk
................
  r56477 | martin.v.loewis | 2007-07-21 09:04:38 +0200 (Sa, 21 Jul 2007) | 11 lines
  Merged revisions 56466-56476 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk
  ........
    r56476 | martin.v.loewis | 2007-07-21 08:55:02 +0200 (Sa, 21 Jul 2007) | 4 lines
    PEP 3123: Provide forward compatibility with Python 3.0, while keeping
    backwards compatibility. Add Py_Refcnt, Py_Type, Py_Size, and
    PyVarObject_HEAD_INIT.
  ........
................
  r56478 | martin.v.loewis | 2007-07-21 09:47:23 +0200 (Sa, 21 Jul 2007) | 2 lines
  PEP 3123: Use proper C inheritance for PyObject.
................
  r56479 | martin.v.loewis | 2007-07-21 10:06:55 +0200 (Sa, 21 Jul 2007) | 3 lines
  Add longintrepr.h to Python.h, so that the compiler can
  see that PyFalse is really some kind of PyObject*.
................
  r56480 | martin.v.loewis | 2007-07-21 10:47:18 +0200 (Sa, 21 Jul 2007) | 2 lines
  Qualify SHIFT, MASK, BASE.
................
  r56482 | martin.v.loewis | 2007-07-21 19:10:57 +0200 (Sa, 21 Jul 2007) | 2 lines
  Correctly refer to _ob_next.
................
											
										 
											2007-07-21 17:22:18 +00:00
										 |  |  | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	"FileIO", | 
					
						
							|  |  |  | 	sizeof(PyFileIOObject), | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | 	(destructor)fileio_dealloc,		/* tp_dealloc */ | 
					
						
							|  |  |  | 	0,					/* tp_print */ | 
					
						
							|  |  |  | 	0,					/* tp_getattr */ | 
					
						
							|  |  |  | 	0,					/* tp_setattr */ | 
					
						
							|  |  |  | 	0,					/* tp_compare */ | 
					
						
							|  |  |  | 	(reprfunc)fileio_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 */ | 
					
						
							|  |  |  | 	0,					/* tp_setattro */ | 
					
						
							|  |  |  | 	0,					/* tp_as_buffer */ | 
					
						
							|  |  |  | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ | 
					
						
							|  |  |  | 	fileio_doc,				/* tp_doc */ | 
					
						
							|  |  |  | 	0,					/* tp_traverse */ | 
					
						
							|  |  |  | 	0,					/* tp_clear */ | 
					
						
							|  |  |  | 	0,					/* tp_richcompare */ | 
					
						
							|  |  |  | 	offsetof(PyFileIOObject, weakreflist),	/* tp_weaklistoffset */ | 
					
						
							|  |  |  | 	0,					/* tp_iter */ | 
					
						
							|  |  |  | 	0,					/* tp_iternext */ | 
					
						
							|  |  |  | 	fileio_methods,				/* tp_methods */ | 
					
						
							|  |  |  | 	0,					/* tp_members */ | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:42 +00:00
										 |  |  | 	fileio_getsetlist,			/* tp_getset */ | 
					
						
							| 
									
										
										
										
											2007-03-08 00:43:48 +00:00
										 |  |  | 	0,					/* tp_base */ | 
					
						
							|  |  |  | 	0,					/* tp_dict */ | 
					
						
							|  |  |  | 	0,					/* tp_descr_get */ | 
					
						
							|  |  |  | 	0,					/* tp_descr_set */ | 
					
						
							|  |  |  | 	0,					/* tp_dictoffset */ | 
					
						
							|  |  |  | 	fileio_init,				/* tp_init */ | 
					
						
							|  |  |  | 	PyType_GenericAlloc,			/* tp_alloc */ | 
					
						
							|  |  |  | 	fileio_new,				/* tp_new */ | 
					
						
							|  |  |  | 	PyObject_Del,				/* tp_free */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef module_methods[] = { | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMODINIT_FUNC | 
					
						
							|  |  |  | init_fileio(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *m;	/* a module object */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m = Py_InitModule3("_fileio", module_methods, | 
					
						
							|  |  |  | 			   "Fast implementation of io.FileIO."); | 
					
						
							|  |  |  | 	if (m == NULL) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	if (PyType_Ready(&PyFileIO_Type) < 0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	Py_INCREF(&PyFileIO_Type); | 
					
						
							|  |  |  | 	PyModule_AddObject(m, "_FileIO", (PyObject *) &PyFileIO_Type); | 
					
						
							|  |  |  | } |