/* File object implementation */ #define PY_SSIZE_T_CLEAN#include "Python.h"#include "structmember.h" #ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif /* 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 __cplusplusextern "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(name != NULL); 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_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 intsanitize_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) {#if defined _MSC_VER && (_MSC_VER < 1400 || !defined(__STDC_SECURE_LIB__)) /* 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. * Starting with Visual Studio .NET 2005, EINVAL is correctly * set by our CRT error handler (set in exceptions.c.) */ 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 (o_name == NULL) return NULL; 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;} voidPyFile_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. */ intPyFile_SetEncoding(PyObject *f, const char *enc){ PyFileObject *file = (PyFileObject*)f; PyObject *str = PyString_FromString(enc); assert(PyFile_Check(f)); 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 voidfile_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 = PyUnicode_AsUnicodeEscapeString(f->f_name); const char *name_str = name ? PyString_AsString(name) : "?"; ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>", f->f_fp == NULL ? "closed" : "open", name_str, 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 >= 8typedef off_t Py_off_t;#elif SIZEOF_FPOS_T >= 8typedef 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;#endifLines 1–500 of 2487. Load more
/* File object implementation */ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif /* 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(name != NULL); 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_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) { #if defined _MSC_VER && (_MSC_VER < 1400 || !defined(__STDC_SECURE_LIB__)) /* 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. * Starting with Visual Studio .NET 2005, EINVAL is correctly * set by our CRT error handler (set in exceptions.c.) */ 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 (o_name == NULL) return NULL; 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); assert(PyFile_Check(f)); 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 = PyUnicode_AsUnicodeEscapeString(f->f_name); const char *name_str = name ? PyString_AsString(name) : "?"; ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>", f->f_fp == NULL ? "closed" : "open", name_str, 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