blob: 09ea31c1ccaee57211175247126d757a8d340bb1 [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 Rossum685a38e1996-12-05 21:54:17 +000037#ifdef HAVE_UNISTD_H
38#include <unistd.h>
39#endif
40
Guido van Rossumb8199141997-05-06 15:23:24 +000041#ifdef MS_WIN32
42#define ftruncate _chsize
43#define fileno _fileno
44#define HAVE_FTRUNCATE
45#endif
46
Guido van Rossumf2044e11998-04-28 16:05:59 +000047#ifdef macintosh
48#ifdef USE_GUSI
49#define HAVE_FTRUNCATE
50#endif
51#endif
52
Guido van Rossum295d1711995-02-19 15:55:19 +000053#ifdef THINK_C
54#define HAVE_FOPENRF
55#endif
Jack Jansene08dea191995-04-23 22:12:47 +000056#ifdef __MWERKS__
57/* Mwerks fopen() doesn't always set errno */
58#define NO_FOPEN_ERRNO
59#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000060
Guido van Rossumc0b618a1997-05-02 03:12:38 +000061#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000062
Guido van Rossumf1dc5661993-07-05 10:31:29 +000063#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000064
65typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000066 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000068 PyObject *f_name;
69 PyObject *f_mode;
70 int (*f_close) Py_PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000071 int f_softspace; /* Flag used by 'print' command */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000072} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073
74FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +000075PyFile_AsFile(f)
76 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000078 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000080 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000081 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082}
83
Guido van Rossumc0b618a1997-05-02 03:12:38 +000084PyObject *
85PyFile_Name(f)
86 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000087{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000089 return NULL;
90 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000092}
93
Guido van Rossumc0b618a1997-05-02 03:12:38 +000094PyObject *
95PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 FILE *fp;
97 char *name;
98 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000099 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000101 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102 if (f == NULL)
103 return NULL;
104 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000105 f->f_name = PyString_FromString(name);
106 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000107 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000108 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000110 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 return NULL;
112 }
113 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000114 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115}
116
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000117PyObject *
118PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119 char *name, *mode;
120{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000121 extern int fclose Py_PROTO((FILE *));
122 PyFileObject *f;
123 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124 if (f == NULL)
125 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000126#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000127 if (*mode == '*') {
128 FILE *fopenRF();
129 f->f_fp = fopenRF(name, mode+1);
130 }
131 else
132#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000133 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000134 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000135 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000136 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000137 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000138 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000139#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000140 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000141 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000142 PyErr_SetString(PyExc_IOError, "Cannot open file");
143 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000144 return NULL;
145 }
146#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000147 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000148 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149 return NULL;
150 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000151 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152}
153
Guido van Rossumb6775db1994-08-01 11:34:53 +0000154void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000155PyFile_SetBufSize(f, bufsize)
156 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000157 int bufsize;
158{
159 if (bufsize >= 0) {
160#ifdef HAVE_SETVBUF
161 int type;
162 switch (bufsize) {
163 case 0:
164 type = _IONBF;
165 break;
166 case 1:
167 type = _IOLBF;
168 bufsize = BUFSIZ;
169 break;
170 default:
171 type = _IOFBF;
172 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000173 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
174 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000175#else /* !HAVE_SETVBUF */
176 if (bufsize <= 1)
177 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
178#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179 }
180}
181
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000182static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000183err_closed()
184{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000185 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000186 return NULL;
187}
188
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189/* Methods */
190
191static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000192file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000193 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000195 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000196 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000197 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000198 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000199 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000200 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000201 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000202 }
203 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000205 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 free((char *)f);
207}
208
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000210file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000211 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212{
213 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000214 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000216 PyString_AsString(f->f_name),
217 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000218 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000219 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220}
221
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000222static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000223file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224 PyFileObject *f;
225 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000227 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000231 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000232 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000233 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000234 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000236 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237 f->f_fp = NULL;
238 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000239 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000241 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242 return PyInt_FromLong((long)sts);
243 Py_INCREF(Py_None);
244 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245}
246
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000247static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000248file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000249 PyFileObject *f;
250 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000252 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000253 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000254 off_t offset;
255 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000256
Guido van Rossumd7297e61992-07-06 14:19:26 +0000257 if (f->f_fp == NULL)
258 return err_closed();
259 whence = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000260 if (!PyArg_ParseTuple(args, "O|i", &offobj, &whence))
261 return NULL;
262#if !defined(HAVE_LARGEFILE_SUPPORT)
263 offset = PyInt_AsLong(offobj);
264#else
265 offset = PyLong_Check(offobj) ?
266 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
267#endif
268 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000269 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000270 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000271 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000272#if defined(HAVE_FSEEKO)
273 ret = fseeko(f->f_fp, offset, whence);
274#elif defined(HAVE_FSEEK64)
275 ret = fseek64(f->f_fp, offset, whence);
276#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000277 ret = fseek(f->f_fp, offset, whence);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000278#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000279 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000280 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000281 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000282 clearerr(f->f_fp);
283 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000284 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000285 Py_INCREF(Py_None);
286 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000287}
288
Guido van Rossumd7047b31995-01-02 19:07:15 +0000289#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000290static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000291file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000292 PyFileObject *f;
293 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000294{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000295 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000296 off_t newsize;
297 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000298
299 if (f->f_fp == NULL)
300 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000301 newsizeobj = NULL;
302 if (!PyArg_ParseTuple(args, "|O", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000303 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000304 if (newsizeobj != NULL) {
305#if !defined(HAVE_LARGEFILE_SUPPORT)
306 newsize = PyInt_AsLong(newsizeobj);
307#else
308 newsize = PyLong_Check(newsizeobj) ?
309 PyLong_AsLongLong(newsizeobj) :
310 PyInt_AsLong(newsizeobj);
311#endif
312 if (PyErr_Occurred())
313 return NULL;
314 } else {
315 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000316 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000317 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000318#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
319 newsize = ftello(f->f_fp);
320#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
321 newsize = ftell64(f->f_fp);
322#else
323 newsize = ftell(f->f_fp);
324#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000325 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000326 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000327 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000328 clearerr(f->f_fp);
329 return NULL;
330 }
331 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000332 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000333 errno = 0;
334 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000336 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000337 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000338 errno = 0;
339 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000341 }
342 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000343 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000344 clearerr(f->f_fp);
345 return NULL;
346 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347 Py_INCREF(Py_None);
348 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000349}
350#endif /* HAVE_FTRUNCATE */
351
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000353file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354 PyFileObject *f;
355 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000356{
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000357 off_t offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000358 if (f->f_fp == NULL)
359 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000360 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000361 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000362 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000363 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000364#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
365 offset = ftello(f->f_fp);
366#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
367 offset = ftell64(f->f_fp);
368#else
Guido van Rossumce5ba841991-03-06 13:06:18 +0000369 offset = ftell(f->f_fp);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000370#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000371 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000372 if (offset == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000374 clearerr(f->f_fp);
375 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000376 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000377#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000378 return PyInt_FromLong(offset);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000379#else
380 return PyLong_FromLongLong(offset);
381#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000382}
383
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000384static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000385file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000386 PyFileObject *f;
387 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000388{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000389 if (f->f_fp == NULL)
390 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000391 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000392 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000393 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000394}
395
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000396static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000397file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000398 PyFileObject *f;
399 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000400{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000401 int res;
402
Guido van Rossumd7297e61992-07-06 14:19:26 +0000403 if (f->f_fp == NULL)
404 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000405 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000406 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000407 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000408 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000409 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000410 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000411 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000412 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000413 clearerr(f->f_fp);
414 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000415 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000416 Py_INCREF(Py_None);
417 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000418}
419
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000420static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000421file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 PyFileObject *f;
423 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000424{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000425 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000426 if (f->f_fp == NULL)
427 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000429 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000431 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432 Py_END_ALLOW_THREADS
433 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000434}
435
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000436/* We expect that fstat exists on most systems.
437 It's confirmed on Unix, Mac and Windows.
438 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
439#ifndef DONT_HAVE_FSTAT
440#define HAVE_FSTAT
441
442#include <sys/types.h>
443#include <sys/stat.h>
444
445#endif
446
447#if BUFSIZ < 8192
448#define SMALLCHUNK 8192
449#else
450#define SMALLCHUNK BUFSIZ
451#endif
452
453#define BIGCHUNK (512*1024)
454
455static size_t
456new_buffersize(f, currentsize)
457 PyFileObject *f;
458 size_t currentsize;
459{
460#ifdef HAVE_FSTAT
461 long pos, end;
462 struct stat st;
463 if (fstat(fileno(f->f_fp), &st) == 0) {
464 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000465 /* The following is not a bug: we really need to call lseek()
466 *and* ftell(). The reason is that some stdio libraries
467 mistakenly flush their buffer when ftell() is called and
468 the lseek() call it makes fails, thereby throwing away
469 data that cannot be recovered in any way. To avoid this,
470 we first test lseek(), and only call ftell() if lseek()
471 works. We can't use the lseek() value either, because we
472 need to take the amount of buffered data into account.
473 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000474 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
475 if (pos >= 0)
476 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000477 if (pos < 0)
478 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000479 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000480 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000481 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000482 }
483#endif
484 if (currentsize > SMALLCHUNK) {
485 /* Keep doubling until we reach BIGCHUNK;
486 then keep adding BIGCHUNK. */
487 if (currentsize <= BIGCHUNK)
488 return currentsize + currentsize;
489 else
490 return currentsize + BIGCHUNK;
491 }
492 return currentsize + SMALLCHUNK;
493}
494
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000495static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000496file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000497 PyFileObject *f;
498 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000499{
Guido van Rossum789a1611997-05-10 22:33:55 +0000500 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000501 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000503
Guido van Rossumd7297e61992-07-06 14:19:26 +0000504 if (f->f_fp == NULL)
505 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000506 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
507 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000508 if (bytesrequested < 0)
509 buffersize = new_buffersize(f, 0);
510 else
511 buffersize = bytesrequested;
512 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000513 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000515 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000516 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000517 Py_BEGIN_ALLOW_THREADS
518 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000519 chunksize = fread(BUF(v) + bytesread, 1,
520 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000521 Py_END_ALLOW_THREADS
522 if (chunksize == 0) {
523 if (!ferror(f->f_fp))
524 break;
525 PyErr_SetFromErrno(PyExc_IOError);
526 clearerr(f->f_fp);
527 Py_DECREF(v);
528 return NULL;
529 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000530 bytesread += chunksize;
531 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000532 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000533 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000534 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000535 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000536 return NULL;
537 }
538 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000539 if (bytesread != buffersize)
540 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000541 return v;
542}
543
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000544static PyObject *
545file_readinto(f, args)
546 PyFileObject *f;
547 PyObject *args;
548{
549 char *ptr;
550 int ntodo, ndone, nnow;
551
552 if (f->f_fp == NULL)
553 return err_closed();
554 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
555 return NULL;
556 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000557 while (ntodo > 0) {
558 Py_BEGIN_ALLOW_THREADS
559 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000560 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000561 Py_END_ALLOW_THREADS
562 if (nnow == 0) {
563 if (!ferror(f->f_fp))
564 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000565 PyErr_SetFromErrno(PyExc_IOError);
566 clearerr(f->f_fp);
567 return NULL;
568 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000569 ndone += nnow;
570 ntodo -= nnow;
571 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000572 return PyInt_FromLong(ndone);
573}
574
575
Guido van Rossum0bd24411991-04-04 15:21:57 +0000576/* Internal routine to get a line.
577 Size argument interpretation:
578 > 0: max length;
579 = 0: read arbitrary line;
580 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000581*/
582
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000583static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000584getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000585 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000586 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000587{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000588 register FILE *fp;
589 register int c;
590 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000591 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000593
Guido van Rossumc10aa771992-07-31 12:42:38 +0000594 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000595 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000596 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000597 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000598 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000599 buf = BUF(v);
600 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000601
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000603 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000604 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000605 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000606 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000609 return NULL;
610 }
611 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000612 Py_DECREF(v);
613 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000614 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000615 return NULL;
616 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000617 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000618 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000619 }
620 if ((*buf++ = c) == '\n') {
621 if (n < 0)
622 buf--;
623 break;
624 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000625 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000626 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000627 break;
628 n1 = n2;
629 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000630 Py_BLOCK_THREADS
631 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000632 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000633 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000634 buf = BUF(v) + n1;
635 end = BUF(v) + n2;
636 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000637 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000638 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000639
Guido van Rossumce5ba841991-03-06 13:06:18 +0000640 n1 = buf - BUF(v);
641 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000642 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000643 return v;
644}
645
Guido van Rossum0bd24411991-04-04 15:21:57 +0000646/* External C interface */
647
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000648PyObject *
649PyFile_GetLine(f, n)
650 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000651 int n;
652{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000653 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000655 return NULL;
656 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000657 if (!PyFile_Check(f)) {
658 PyObject *reader;
659 PyObject *args;
660 PyObject *result;
661 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000662 if (reader == NULL)
663 return NULL;
664 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000665 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000666 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000667 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000668 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000670 return NULL;
671 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000672 result = PyEval_CallObject(reader, args);
673 Py_DECREF(reader);
674 Py_DECREF(args);
675 if (result != NULL && !PyString_Check(result)) {
676 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000677 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000678 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000679 "object.readline() returned non-string");
680 }
681 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000682 char *s = PyString_AsString(result);
683 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000684 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000685 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000686 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000687 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000688 "EOF when reading a line");
689 }
690 else if (s[len-1] == '\n') {
691 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000692 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000693 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000694 PyObject *v;
695 v = PyString_FromStringAndSize(s,
696 len-1);
697 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000698 result = v;
699 }
700 }
701 }
702 return result;
703 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000704 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000705 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000706 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000707}
708
709/* Python method */
710
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000711static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000712file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000713 PyFileObject *f;
714 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000715{
Guido van Rossum789a1611997-05-10 22:33:55 +0000716 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000717
Guido van Rossumd7297e61992-07-06 14:19:26 +0000718 if (f->f_fp == NULL)
719 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000720 if (!PyArg_ParseTuple(args, "|i", &n))
721 return NULL;
722 if (n == 0)
723 return PyString_FromString("");
724 if (n < 0)
725 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000726 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000727}
728
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000729static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000730file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000731 PyFileObject *f;
732 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000733{
Guido van Rossum789a1611997-05-10 22:33:55 +0000734 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000735 PyObject *list;
736 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000737 char small_buffer[SMALLCHUNK];
738 char *buffer = small_buffer;
739 size_t buffersize = SMALLCHUNK;
740 PyObject *big_buffer = NULL;
741 size_t nfilled = 0;
742 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000743 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000744 char *p, *q, *end;
745 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000746
Guido van Rossumd7297e61992-07-06 14:19:26 +0000747 if (f->f_fp == NULL)
748 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000749 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000750 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000751 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000752 return NULL;
753 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000754 Py_BEGIN_ALLOW_THREADS
755 errno = 0;
756 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
757 Py_END_ALLOW_THREADS
758 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000759 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000760 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000761 break;
762 PyErr_SetFromErrno(PyExc_IOError);
763 clearerr(f->f_fp);
764 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000765 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000766 list = NULL;
767 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000768 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000769 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000770 p = memchr(buffer+nfilled, '\n', nread);
771 if (p == NULL) {
772 /* Need a larger buffer to fit this line */
773 nfilled += nread;
774 buffersize *= 2;
775 if (big_buffer == NULL) {
776 /* Create the big buffer */
777 big_buffer = PyString_FromStringAndSize(
778 NULL, buffersize);
779 if (big_buffer == NULL)
780 goto error;
781 buffer = PyString_AS_STRING(big_buffer);
782 memcpy(buffer, small_buffer, nfilled);
783 }
784 else {
785 /* Grow the big buffer */
786 _PyString_Resize(&big_buffer, buffersize);
787 buffer = PyString_AS_STRING(big_buffer);
788 }
789 continue;
790 }
791 end = buffer+nfilled+nread;
792 q = buffer;
793 do {
794 /* Process complete lines */
795 p++;
796 line = PyString_FromStringAndSize(q, p-q);
797 if (line == NULL)
798 goto error;
799 err = PyList_Append(list, line);
800 Py_DECREF(line);
801 if (err != 0)
802 goto error;
803 q = p;
804 p = memchr(q, '\n', end-q);
805 } while (p != NULL);
806 /* Move the remaining incomplete line to the start */
807 nfilled = end-q;
808 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000809 if (sizehint > 0)
810 if (totalread >= (size_t)sizehint)
811 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000812 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000813 if (nfilled != 0) {
814 /* Partial last line */
815 line = PyString_FromStringAndSize(buffer, nfilled);
816 if (line == NULL)
817 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000818 if (sizehint > 0) {
819 /* Need to complete the last line */
820 PyObject *rest = getline(f, 0);
821 if (rest == NULL) {
822 Py_DECREF(line);
823 goto error;
824 }
825 PyString_Concat(&line, rest);
826 Py_DECREF(rest);
827 if (line == NULL)
828 goto error;
829 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000830 err = PyList_Append(list, line);
831 Py_DECREF(line);
832 if (err != 0)
833 goto error;
834 }
835 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000836 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000837 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000838 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000839 return list;
840}
841
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000842static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000843file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000844 PyFileObject *f;
845 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000847 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000848 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000849 if (f->f_fp == NULL)
850 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000851 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000852 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000853 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000854 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000855 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000856 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000857 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000858 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000859 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000860 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861 return NULL;
862 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000863 Py_INCREF(Py_None);
864 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000865}
866
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000867static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000868file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000869 PyFileObject *f;
870 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000871{
872 int i, n;
873 if (f->f_fp == NULL)
874 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000875 if (args == NULL || !PyList_Check(args)) {
876 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000877 "writelines() requires list of strings");
878 return NULL;
879 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000880 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000881 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000882 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000883 errno = 0;
884 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000885 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000886 int len;
887 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888 if (!PyString_Check(line)) {
889 Py_BLOCK_THREADS
890 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000891 "writelines() requires list of strings");
892 return NULL;
893 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000894 len = PyString_Size(line);
895 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000896 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000897 Py_BLOCK_THREADS
898 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000899 clearerr(f->f_fp);
900 return NULL;
901 }
902 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 Py_END_ALLOW_THREADS
904 Py_INCREF(Py_None);
905 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000906}
907
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000909 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000910 {"read", (PyCFunction)file_read, 1},
911 {"write", (PyCFunction)file_write, 0},
912 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +0000913 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000914#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +0000915 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000916#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000917 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000918 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000919 {"readlines", (PyCFunction)file_readlines, 1},
920 {"writelines", (PyCFunction)file_writelines, 0},
921 {"flush", (PyCFunction)file_flush, 0},
922 {"close", (PyCFunction)file_close, 0},
923 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000924 {NULL, NULL} /* sentinel */
925};
926
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000927#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000928
929static struct memberlist file_memberlist[] = {
930 {"softspace", T_INT, OFF(f_softspace)},
931 {"mode", T_OBJECT, OFF(f_mode), RO},
932 {"name", T_OBJECT, OFF(f_name), RO},
933 /* getattr(f, "closed") is implemented without this table */
934 {"closed", T_INT, 0, RO},
935 {NULL} /* Sentinel */
936};
937
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000938static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000939file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000940 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000941 char *name;
942{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000943 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000944
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000945 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000946 if (res != NULL)
947 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000948 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000949 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000950 return PyInt_FromLong((long)(f->f_fp == 0));
951 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000952}
953
954static int
955file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000956 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000957 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000958 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000959{
960 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000961 PyErr_SetString(PyExc_AttributeError,
962 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000963 return -1;
964 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000965 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000966}
967
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000968PyTypeObject PyFile_Type = {
969 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000970 0,
971 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000972 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000973 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000974 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000975 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000976 (getattrfunc)file_getattr, /*tp_getattr*/
977 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000978 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000979 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000980};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000981
982/* Interface for the 'soft space' between print items. */
983
984int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000985PyFile_SoftSpace(f, newflag)
986 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000987 int newflag;
988{
989 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000990 if (f == NULL) {
991 /* Do nothing */
992 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000993 else if (PyFile_Check(f)) {
994 oldflag = ((PyFileObject *)f)->f_softspace;
995 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000996 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000997 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000998 PyObject *v;
999 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001000 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001001 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001002 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003 if (PyInt_Check(v))
1004 oldflag = PyInt_AsLong(v);
1005 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001006 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001007 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001008 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001009 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001010 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001011 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1012 PyErr_Clear();
1013 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001014 }
1015 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001016 return oldflag;
1017}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001018
1019/* Interfaces to write objects/strings to file-like objects */
1020
1021int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001022PyFile_WriteObject(v, f, flags)
1023 PyObject *v;
1024 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001025 int flags;
1026{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001027 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001028 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001029 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001030 return -1;
1031 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001032 else if (PyFile_Check(f)) {
1033 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001034 if (fp == NULL) {
1035 err_closed();
1036 return -1;
1037 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001038 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001039 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001040 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001041 if (writer == NULL)
1042 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001043 if (flags & Py_PRINT_RAW)
1044 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001045 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001046 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001047 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001048 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001049 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001050 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001051 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001052 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001053 Py_DECREF(value);
1054 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001055 return -1;
1056 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001057 result = PyEval_CallObject(writer, args);
1058 Py_DECREF(args);
1059 Py_DECREF(value);
1060 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001061 if (result == NULL)
1062 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001063 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001064 return 0;
1065}
1066
Guido van Rossum27a60b11997-05-22 22:25:11 +00001067int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001068PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001069 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001070 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001071{
1072 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001073 /* Should be caused by a pre-existing error */
1074 if(!PyErr_Occurred())
1075 PyErr_SetString(PyExc_SystemError,
1076 "null file for PyFile_WriteString");
1077 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001078 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001079 else if (PyFile_Check(f)) {
1080 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001081 if (fp == NULL) {
1082 err_closed();
1083 return -1;
1084 }
1085 fputs(s, fp);
1086 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001087 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001088 else if (!PyErr_Occurred()) {
1089 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001090 int err;
1091 if (v == NULL)
1092 return -1;
1093 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1094 Py_DECREF(v);
1095 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001096 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001097 else
1098 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001099}