blob: ed15587ef65c927eada402a853c055ac52d2185f [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* File object implementation */
33
Guido van Rossumc0b618a1997-05-02 03:12:38 +000034#include "Python.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000035#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036
Guido van Rossum41498431999-01-07 22:09:51 +000037#include <sys/types.h>
38
Guido van Rossum685a38e1996-12-05 21:54:17 +000039#ifdef HAVE_UNISTD_H
40#include <unistd.h>
41#endif
42
Guido van Rossumb8199141997-05-06 15:23:24 +000043#ifdef MS_WIN32
44#define ftruncate _chsize
45#define fileno _fileno
46#define HAVE_FTRUNCATE
47#endif
48
Guido van Rossumf2044e11998-04-28 16:05:59 +000049#ifdef macintosh
50#ifdef USE_GUSI
51#define HAVE_FTRUNCATE
52#endif
53#endif
54
Guido van Rossum295d1711995-02-19 15:55:19 +000055#ifdef THINK_C
56#define HAVE_FOPENRF
57#endif
Jack Jansene08dea191995-04-23 22:12:47 +000058#ifdef __MWERKS__
59/* Mwerks fopen() doesn't always set errno */
60#define NO_FOPEN_ERRNO
61#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000062
Guido van Rossumc0b618a1997-05-02 03:12:38 +000063#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000064
Guido van Rossumf1dc5661993-07-05 10:31:29 +000065#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
67typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000068 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000070 PyObject *f_name;
71 PyObject *f_mode;
72 int (*f_close) Py_PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000073 int f_softspace; /* Flag used by 'print' command */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000074} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075
76FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +000077PyFile_AsFile(f)
78 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000080 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000082 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000083 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084}
85
Guido van Rossumc0b618a1997-05-02 03:12:38 +000086PyObject *
87PyFile_Name(f)
88 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000089{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000090 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000091 return NULL;
92 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000093 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000094}
95
Guido van Rossumc0b618a1997-05-02 03:12:38 +000096PyObject *
97PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098 FILE *fp;
99 char *name;
100 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000101 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000103 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104 if (f == NULL)
105 return NULL;
106 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107 f->f_name = PyString_FromString(name);
108 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000109 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000110 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000112 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 return NULL;
114 }
115 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000116 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117}
118
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000119PyObject *
120PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 char *name, *mode;
122{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000123 extern int fclose Py_PROTO((FILE *));
124 PyFileObject *f;
125 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000126 if (f == NULL)
127 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000128#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000129 if (*mode == '*') {
130 FILE *fopenRF();
131 f->f_fp = fopenRF(name, mode+1);
132 }
133 else
134#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000135 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000136 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000137 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000138 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000139 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000140 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000141#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000142 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000143 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000144 PyErr_SetString(PyExc_IOError, "Cannot open file");
145 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000146 return NULL;
147 }
148#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000149 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000150 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 return NULL;
152 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000153 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154}
155
Guido van Rossumb6775db1994-08-01 11:34:53 +0000156void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000157PyFile_SetBufSize(f, bufsize)
158 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000159 int bufsize;
160{
161 if (bufsize >= 0) {
162#ifdef HAVE_SETVBUF
163 int type;
164 switch (bufsize) {
165 case 0:
166 type = _IONBF;
167 break;
168 case 1:
169 type = _IOLBF;
170 bufsize = BUFSIZ;
171 break;
172 default:
173 type = _IOFBF;
174 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000175 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
176 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000177#else /* !HAVE_SETVBUF */
178 if (bufsize <= 1)
179 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
180#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181 }
182}
183
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000184static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000185err_closed()
186{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000187 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000188 return NULL;
189}
190
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191/* Methods */
192
193static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000194file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000195 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000197 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000198 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000199 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000200 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000201 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000202 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000203 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000204 }
205 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000206 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000207 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208 free((char *)f);
209}
210
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000211static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000212file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000213 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214{
215 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000216 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000218 PyString_AsString(f->f_name),
219 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000220 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222}
223
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000225file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000226 PyFileObject *f;
227 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000229 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000233 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000235 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000236 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000238 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000239 f->f_fp = NULL;
240 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000241 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000243 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000244 return PyInt_FromLong((long)sts);
245 Py_INCREF(Py_None);
246 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247}
248
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000249static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000250file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000251 PyFileObject *f;
252 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000253{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000254 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000255 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000256 off_t offset;
257 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000258
Guido van Rossumd7297e61992-07-06 14:19:26 +0000259 if (f->f_fp == NULL)
260 return err_closed();
261 whence = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000262 if (!PyArg_ParseTuple(args, "O|i", &offobj, &whence))
263 return NULL;
264#if !defined(HAVE_LARGEFILE_SUPPORT)
265 offset = PyInt_AsLong(offobj);
266#else
267 offset = PyLong_Check(offobj) ?
268 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
269#endif
270 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000271 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000272 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000273 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000274#if defined(HAVE_FSEEKO)
275 ret = fseeko(f->f_fp, offset, whence);
276#elif defined(HAVE_FSEEK64)
277 ret = fseek64(f->f_fp, offset, whence);
278#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000279 ret = fseek(f->f_fp, offset, whence);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000280#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000281 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000282 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000283 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000284 clearerr(f->f_fp);
285 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000286 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000287 Py_INCREF(Py_None);
288 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000289}
290
Guido van Rossumd7047b31995-01-02 19:07:15 +0000291#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000292static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000293file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000294 PyFileObject *f;
295 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000296{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000297 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000298 off_t newsize;
299 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000300
301 if (f->f_fp == NULL)
302 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000303 newsizeobj = NULL;
304 if (!PyArg_ParseTuple(args, "|O", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000305 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000306 if (newsizeobj != NULL) {
307#if !defined(HAVE_LARGEFILE_SUPPORT)
308 newsize = PyInt_AsLong(newsizeobj);
309#else
310 newsize = PyLong_Check(newsizeobj) ?
311 PyLong_AsLongLong(newsizeobj) :
312 PyInt_AsLong(newsizeobj);
313#endif
314 if (PyErr_Occurred())
315 return NULL;
316 } else {
317 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000318 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000319 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000320#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
321 newsize = ftello(f->f_fp);
322#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
323 newsize = ftell64(f->f_fp);
324#else
325 newsize = ftell(f->f_fp);
326#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000327 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000328 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000329 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000330 clearerr(f->f_fp);
331 return NULL;
332 }
333 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000334 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000335 errno = 0;
336 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000337 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000338 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000339 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000340 errno = 0;
341 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000342 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000343 }
344 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000345 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000346 clearerr(f->f_fp);
347 return NULL;
348 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 Py_INCREF(Py_None);
350 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000351}
352#endif /* HAVE_FTRUNCATE */
353
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000355file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356 PyFileObject *f;
357 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000358{
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000359 off_t offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000360 if (f->f_fp == NULL)
361 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000362 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000364 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000365 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000366#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
367 offset = ftello(f->f_fp);
368#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
369 offset = ftell64(f->f_fp);
370#else
Guido van Rossumce5ba841991-03-06 13:06:18 +0000371 offset = ftell(f->f_fp);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000372#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000374 if (offset == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000375 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000376 clearerr(f->f_fp);
377 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000378 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000379#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 return PyInt_FromLong(offset);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000381#else
382 return PyLong_FromLongLong(offset);
383#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000384}
385
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000386static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000387file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000388 PyFileObject *f;
389 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000390{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000391 if (f->f_fp == NULL)
392 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000393 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000394 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000395 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000396}
397
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000398static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000399file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000400 PyFileObject *f;
401 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000402{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000403 int res;
404
Guido van Rossumd7297e61992-07-06 14:19:26 +0000405 if (f->f_fp == NULL)
406 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000407 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000408 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000409 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000410 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000411 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000412 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000413 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000414 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000415 clearerr(f->f_fp);
416 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000417 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000418 Py_INCREF(Py_None);
419 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000420}
421
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000423file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000424 PyFileObject *f;
425 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000426{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000427 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000428 if (f->f_fp == NULL)
429 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000431 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000433 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 Py_END_ALLOW_THREADS
435 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000436}
437
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000438/* We expect that fstat exists on most systems.
439 It's confirmed on Unix, Mac and Windows.
440 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
441#ifndef DONT_HAVE_FSTAT
442#define HAVE_FSTAT
443
444#include <sys/types.h>
445#include <sys/stat.h>
446
447#endif
448
449#if BUFSIZ < 8192
450#define SMALLCHUNK 8192
451#else
452#define SMALLCHUNK BUFSIZ
453#endif
454
455#define BIGCHUNK (512*1024)
456
457static size_t
458new_buffersize(f, currentsize)
459 PyFileObject *f;
460 size_t currentsize;
461{
462#ifdef HAVE_FSTAT
463 long pos, end;
464 struct stat st;
465 if (fstat(fileno(f->f_fp), &st) == 0) {
466 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000467 /* The following is not a bug: we really need to call lseek()
468 *and* ftell(). The reason is that some stdio libraries
469 mistakenly flush their buffer when ftell() is called and
470 the lseek() call it makes fails, thereby throwing away
471 data that cannot be recovered in any way. To avoid this,
472 we first test lseek(), and only call ftell() if lseek()
473 works. We can't use the lseek() value either, because we
474 need to take the amount of buffered data into account.
475 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000476 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
477 if (pos >= 0)
478 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000479 if (pos < 0)
480 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000481 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000482 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000483 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000484 }
485#endif
486 if (currentsize > SMALLCHUNK) {
487 /* Keep doubling until we reach BIGCHUNK;
488 then keep adding BIGCHUNK. */
489 if (currentsize <= BIGCHUNK)
490 return currentsize + currentsize;
491 else
492 return currentsize + BIGCHUNK;
493 }
494 return currentsize + SMALLCHUNK;
495}
496
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000497static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000498file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000499 PyFileObject *f;
500 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000501{
Guido van Rossum789a1611997-05-10 22:33:55 +0000502 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000503 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000504 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000505
Guido van Rossumd7297e61992-07-06 14:19:26 +0000506 if (f->f_fp == NULL)
507 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000508 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
509 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000510 if (bytesrequested < 0)
511 buffersize = new_buffersize(f, 0);
512 else
513 buffersize = bytesrequested;
514 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000515 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000516 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000517 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000518 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000519 Py_BEGIN_ALLOW_THREADS
520 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000521 chunksize = fread(BUF(v) + bytesread, 1,
522 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000523 Py_END_ALLOW_THREADS
524 if (chunksize == 0) {
525 if (!ferror(f->f_fp))
526 break;
527 PyErr_SetFromErrno(PyExc_IOError);
528 clearerr(f->f_fp);
529 Py_DECREF(v);
530 return NULL;
531 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000532 bytesread += chunksize;
533 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000534 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000535 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000536 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000537 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000538 return NULL;
539 }
540 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000541 if (bytesread != buffersize)
542 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000543 return v;
544}
545
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000546static PyObject *
547file_readinto(f, args)
548 PyFileObject *f;
549 PyObject *args;
550{
551 char *ptr;
552 int ntodo, ndone, nnow;
553
554 if (f->f_fp == NULL)
555 return err_closed();
556 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
557 return NULL;
558 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000559 while (ntodo > 0) {
560 Py_BEGIN_ALLOW_THREADS
561 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000562 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000563 Py_END_ALLOW_THREADS
564 if (nnow == 0) {
565 if (!ferror(f->f_fp))
566 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000567 PyErr_SetFromErrno(PyExc_IOError);
568 clearerr(f->f_fp);
569 return NULL;
570 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000571 ndone += nnow;
572 ntodo -= nnow;
573 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000574 return PyInt_FromLong(ndone);
575}
576
577
Guido van Rossum0bd24411991-04-04 15:21:57 +0000578/* Internal routine to get a line.
579 Size argument interpretation:
580 > 0: max length;
581 = 0: read arbitrary line;
582 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000583*/
584
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000585static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000586getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000587 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000588 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000589{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000590 register FILE *fp;
591 register int c;
592 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000593 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000594 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000595
Guido van Rossumc10aa771992-07-31 12:42:38 +0000596 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000597 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000598 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000599 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000600 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000601 buf = BUF(v);
602 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000603
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000605 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000606 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000607 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000608 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000609 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000610 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000611 return NULL;
612 }
613 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000614 Py_DECREF(v);
615 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000616 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000617 return NULL;
618 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000619 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000620 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000621 }
622 if ((*buf++ = c) == '\n') {
623 if (n < 0)
624 buf--;
625 break;
626 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000627 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000628 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000629 break;
630 n1 = n2;
631 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 Py_BLOCK_THREADS
633 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000634 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000635 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000636 buf = BUF(v) + n1;
637 end = BUF(v) + n2;
638 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000640 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000641
Guido van Rossumce5ba841991-03-06 13:06:18 +0000642 n1 = buf - BUF(v);
643 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000644 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000645 return v;
646}
647
Guido van Rossum0bd24411991-04-04 15:21:57 +0000648/* External C interface */
649
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000650PyObject *
651PyFile_GetLine(f, n)
652 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000653 int n;
654{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000655 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000656 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000657 return NULL;
658 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000659 if (!PyFile_Check(f)) {
660 PyObject *reader;
661 PyObject *args;
662 PyObject *result;
663 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000664 if (reader == NULL)
665 return NULL;
666 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000667 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000668 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000670 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000672 return NULL;
673 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000674 result = PyEval_CallObject(reader, args);
675 Py_DECREF(reader);
676 Py_DECREF(args);
677 if (result != NULL && !PyString_Check(result)) {
678 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000679 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000680 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000681 "object.readline() returned non-string");
682 }
683 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000684 char *s = PyString_AsString(result);
685 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000686 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000687 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000688 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000689 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000690 "EOF when reading a line");
691 }
692 else if (s[len-1] == '\n') {
693 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000694 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000695 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000696 PyObject *v;
697 v = PyString_FromStringAndSize(s,
698 len-1);
699 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000700 result = v;
701 }
702 }
703 }
704 return result;
705 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000706 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000707 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000708 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000709}
710
711/* Python method */
712
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000713static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000714file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000715 PyFileObject *f;
716 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000717{
Guido van Rossum789a1611997-05-10 22:33:55 +0000718 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000719
Guido van Rossumd7297e61992-07-06 14:19:26 +0000720 if (f->f_fp == NULL)
721 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000722 if (!PyArg_ParseTuple(args, "|i", &n))
723 return NULL;
724 if (n == 0)
725 return PyString_FromString("");
726 if (n < 0)
727 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000728 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000729}
730
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000731static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000732file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000733 PyFileObject *f;
734 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000735{
Guido van Rossum789a1611997-05-10 22:33:55 +0000736 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000737 PyObject *list;
738 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000739 char small_buffer[SMALLCHUNK];
740 char *buffer = small_buffer;
741 size_t buffersize = SMALLCHUNK;
742 PyObject *big_buffer = NULL;
743 size_t nfilled = 0;
744 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000745 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000746 char *p, *q, *end;
747 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000748
Guido van Rossumd7297e61992-07-06 14:19:26 +0000749 if (f->f_fp == NULL)
750 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000751 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000752 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000753 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000754 return NULL;
755 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000756 Py_BEGIN_ALLOW_THREADS
757 errno = 0;
758 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
759 Py_END_ALLOW_THREADS
760 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000761 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000762 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000763 break;
764 PyErr_SetFromErrno(PyExc_IOError);
765 clearerr(f->f_fp);
766 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000767 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000768 list = NULL;
769 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000770 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000771 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000772 p = memchr(buffer+nfilled, '\n', nread);
773 if (p == NULL) {
774 /* Need a larger buffer to fit this line */
775 nfilled += nread;
776 buffersize *= 2;
777 if (big_buffer == NULL) {
778 /* Create the big buffer */
779 big_buffer = PyString_FromStringAndSize(
780 NULL, buffersize);
781 if (big_buffer == NULL)
782 goto error;
783 buffer = PyString_AS_STRING(big_buffer);
784 memcpy(buffer, small_buffer, nfilled);
785 }
786 else {
787 /* Grow the big buffer */
788 _PyString_Resize(&big_buffer, buffersize);
789 buffer = PyString_AS_STRING(big_buffer);
790 }
791 continue;
792 }
793 end = buffer+nfilled+nread;
794 q = buffer;
795 do {
796 /* Process complete lines */
797 p++;
798 line = PyString_FromStringAndSize(q, p-q);
799 if (line == NULL)
800 goto error;
801 err = PyList_Append(list, line);
802 Py_DECREF(line);
803 if (err != 0)
804 goto error;
805 q = p;
806 p = memchr(q, '\n', end-q);
807 } while (p != NULL);
808 /* Move the remaining incomplete line to the start */
809 nfilled = end-q;
810 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000811 if (sizehint > 0)
812 if (totalread >= (size_t)sizehint)
813 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000814 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000815 if (nfilled != 0) {
816 /* Partial last line */
817 line = PyString_FromStringAndSize(buffer, nfilled);
818 if (line == NULL)
819 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000820 if (sizehint > 0) {
821 /* Need to complete the last line */
822 PyObject *rest = getline(f, 0);
823 if (rest == NULL) {
824 Py_DECREF(line);
825 goto error;
826 }
827 PyString_Concat(&line, rest);
828 Py_DECREF(rest);
829 if (line == NULL)
830 goto error;
831 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000832 err = PyList_Append(list, line);
833 Py_DECREF(line);
834 if (err != 0)
835 goto error;
836 }
837 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000838 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000839 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000840 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000841 return list;
842}
843
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000844static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000845file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000846 PyFileObject *f;
847 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000848{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000849 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000850 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000851 if (f->f_fp == NULL)
852 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000853 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000854 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000855 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000856 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000857 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000858 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000859 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000860 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000861 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000862 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000863 return NULL;
864 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000865 Py_INCREF(Py_None);
866 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000867}
868
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000869static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000870file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000871 PyFileObject *f;
872 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000873{
874 int i, n;
875 if (f->f_fp == NULL)
876 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000877 if (args == NULL || !PyList_Check(args)) {
878 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000879 "writelines() requires list of strings");
880 return NULL;
881 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000882 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000883 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000884 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000885 errno = 0;
886 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000887 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000888 int len;
889 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890 if (!PyString_Check(line)) {
891 Py_BLOCK_THREADS
892 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000893 "writelines() requires list of strings");
894 return NULL;
895 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000896 len = PyString_Size(line);
897 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000898 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000899 Py_BLOCK_THREADS
900 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000901 clearerr(f->f_fp);
902 return NULL;
903 }
904 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000905 Py_END_ALLOW_THREADS
906 Py_INCREF(Py_None);
907 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000908}
909
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000910static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000911 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000912 {"read", (PyCFunction)file_read, 1},
913 {"write", (PyCFunction)file_write, 0},
914 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +0000915 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000916#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +0000917 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000918#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000919 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000920 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000921 {"readlines", (PyCFunction)file_readlines, 1},
922 {"writelines", (PyCFunction)file_writelines, 0},
923 {"flush", (PyCFunction)file_flush, 0},
924 {"close", (PyCFunction)file_close, 0},
925 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000926 {NULL, NULL} /* sentinel */
927};
928
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000929#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000930
931static struct memberlist file_memberlist[] = {
932 {"softspace", T_INT, OFF(f_softspace)},
933 {"mode", T_OBJECT, OFF(f_mode), RO},
934 {"name", T_OBJECT, OFF(f_name), RO},
935 /* getattr(f, "closed") is implemented without this table */
936 {"closed", T_INT, 0, RO},
937 {NULL} /* Sentinel */
938};
939
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000940static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000941file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000942 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000943 char *name;
944{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000945 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000946
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000947 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000948 if (res != NULL)
949 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000950 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000951 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000952 return PyInt_FromLong((long)(f->f_fp == 0));
953 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000954}
955
956static int
957file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000958 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000959 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000960 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000961{
962 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000963 PyErr_SetString(PyExc_AttributeError,
964 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000965 return -1;
966 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000967 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000968}
969
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000970PyTypeObject PyFile_Type = {
971 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000972 0,
973 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000974 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000975 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000976 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000977 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000978 (getattrfunc)file_getattr, /*tp_getattr*/
979 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000980 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000981 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000982};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000983
984/* Interface for the 'soft space' between print items. */
985
986int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000987PyFile_SoftSpace(f, newflag)
988 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000989 int newflag;
990{
991 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000992 if (f == NULL) {
993 /* Do nothing */
994 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000995 else if (PyFile_Check(f)) {
996 oldflag = ((PyFileObject *)f)->f_softspace;
997 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000998 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000999 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001000 PyObject *v;
1001 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001002 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001004 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001005 if (PyInt_Check(v))
1006 oldflag = PyInt_AsLong(v);
1007 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001008 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001009 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001010 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001011 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001012 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1014 PyErr_Clear();
1015 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001016 }
1017 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001018 return oldflag;
1019}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001020
1021/* Interfaces to write objects/strings to file-like objects */
1022
1023int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001024PyFile_WriteObject(v, f, flags)
1025 PyObject *v;
1026 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001027 int flags;
1028{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001029 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001030 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001031 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001032 return -1;
1033 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001034 else if (PyFile_Check(f)) {
1035 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001036 if (fp == NULL) {
1037 err_closed();
1038 return -1;
1039 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001040 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001041 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001042 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001043 if (writer == NULL)
1044 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001045 if (flags & Py_PRINT_RAW)
1046 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001047 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001048 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001049 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001050 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001051 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001052 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001053 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001054 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001055 Py_DECREF(value);
1056 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001057 return -1;
1058 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001059 result = PyEval_CallObject(writer, args);
1060 Py_DECREF(args);
1061 Py_DECREF(value);
1062 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001063 if (result == NULL)
1064 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001065 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001066 return 0;
1067}
1068
Guido van Rossum27a60b11997-05-22 22:25:11 +00001069int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001070PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001071 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001072 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001073{
1074 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001075 /* Should be caused by a pre-existing error */
1076 if(!PyErr_Occurred())
1077 PyErr_SetString(PyExc_SystemError,
1078 "null file for PyFile_WriteString");
1079 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001080 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001081 else if (PyFile_Check(f)) {
1082 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001083 if (fp == NULL) {
1084 err_closed();
1085 return -1;
1086 }
1087 fputs(s, fp);
1088 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001089 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001090 else if (!PyErr_Occurred()) {
1091 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001092 int err;
1093 if (v == NULL)
1094 return -1;
1095 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1096 Py_DECREF(v);
1097 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001098 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001099 else
1100 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001101}