blob: b0eb332b0869e561fb0c9912198acd2ee24aba8c [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
Guido van Rossum3c259041999-01-14 19:00:14 +0000455#if SIZEOF_INT < 4
456#define BIGCHUNK (512 * 32)
457#else
458#define BIGCHUNK (512 * 1024)
459#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000460
461static size_t
462new_buffersize(f, currentsize)
463 PyFileObject *f;
464 size_t currentsize;
465{
466#ifdef HAVE_FSTAT
467 long pos, end;
468 struct stat st;
469 if (fstat(fileno(f->f_fp), &st) == 0) {
470 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000471 /* The following is not a bug: we really need to call lseek()
472 *and* ftell(). The reason is that some stdio libraries
473 mistakenly flush their buffer when ftell() is called and
474 the lseek() call it makes fails, thereby throwing away
475 data that cannot be recovered in any way. To avoid this,
476 we first test lseek(), and only call ftell() if lseek()
477 works. We can't use the lseek() value either, because we
478 need to take the amount of buffered data into account.
479 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000480 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
481 if (pos >= 0)
482 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000483 if (pos < 0)
484 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000485 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000486 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000487 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000488 }
489#endif
490 if (currentsize > SMALLCHUNK) {
491 /* Keep doubling until we reach BIGCHUNK;
492 then keep adding BIGCHUNK. */
493 if (currentsize <= BIGCHUNK)
494 return currentsize + currentsize;
495 else
496 return currentsize + BIGCHUNK;
497 }
498 return currentsize + SMALLCHUNK;
499}
500
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000501static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000502file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000503 PyFileObject *f;
504 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000505{
Guido van Rossum789a1611997-05-10 22:33:55 +0000506 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000507 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000509
Guido van Rossumd7297e61992-07-06 14:19:26 +0000510 if (f->f_fp == NULL)
511 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000512 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
513 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000514 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000515 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000516 else
517 buffersize = bytesrequested;
518 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000519 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000520 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000521 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000522 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000523 Py_BEGIN_ALLOW_THREADS
524 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000525 chunksize = fread(BUF(v) + bytesread, 1,
526 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000527 Py_END_ALLOW_THREADS
528 if (chunksize == 0) {
529 if (!ferror(f->f_fp))
530 break;
531 PyErr_SetFromErrno(PyExc_IOError);
532 clearerr(f->f_fp);
533 Py_DECREF(v);
534 return NULL;
535 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000536 bytesread += chunksize;
537 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000538 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000539 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000540 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000541 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000542 return NULL;
543 }
544 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000545 if (bytesread != buffersize)
546 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000547 return v;
548}
549
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000550static PyObject *
551file_readinto(f, args)
552 PyFileObject *f;
553 PyObject *args;
554{
555 char *ptr;
556 int ntodo, ndone, nnow;
557
558 if (f->f_fp == NULL)
559 return err_closed();
560 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
561 return NULL;
562 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000563 while (ntodo > 0) {
564 Py_BEGIN_ALLOW_THREADS
565 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000566 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000567 Py_END_ALLOW_THREADS
568 if (nnow == 0) {
569 if (!ferror(f->f_fp))
570 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000571 PyErr_SetFromErrno(PyExc_IOError);
572 clearerr(f->f_fp);
573 return NULL;
574 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000575 ndone += nnow;
576 ntodo -= nnow;
577 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000578 return PyInt_FromLong(ndone);
579}
580
581
Guido van Rossum0bd24411991-04-04 15:21:57 +0000582/* Internal routine to get a line.
583 Size argument interpretation:
584 > 0: max length;
585 = 0: read arbitrary line;
586 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000587*/
588
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000589static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000590getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000591 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000592 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000593{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000594 register FILE *fp;
595 register int c;
596 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000597 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000598 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000599
Guido van Rossumc10aa771992-07-31 12:42:38 +0000600 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000601 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000603 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000604 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000605 buf = BUF(v);
606 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000607
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000609 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000610 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000611 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000612 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000613 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000614 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000615 return NULL;
616 }
617 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000618 Py_DECREF(v);
619 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000620 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000621 return NULL;
622 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000623 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000624 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000625 }
626 if ((*buf++ = c) == '\n') {
627 if (n < 0)
628 buf--;
629 break;
630 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000631 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000632 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000633 break;
634 n1 = n2;
635 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000636 Py_BLOCK_THREADS
637 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000638 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000639 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000640 buf = BUF(v) + n1;
641 end = BUF(v) + n2;
642 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000643 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000644 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000645
Guido van Rossumce5ba841991-03-06 13:06:18 +0000646 n1 = buf - BUF(v);
647 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000648 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000649 return v;
650}
651
Guido van Rossum0bd24411991-04-04 15:21:57 +0000652/* External C interface */
653
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654PyObject *
655PyFile_GetLine(f, n)
656 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000657 int n;
658{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000659 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000660 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000661 return NULL;
662 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663 if (!PyFile_Check(f)) {
664 PyObject *reader;
665 PyObject *args;
666 PyObject *result;
667 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000668 if (reader == NULL)
669 return NULL;
670 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000672 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000673 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000674 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000675 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000676 return NULL;
677 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000678 result = PyEval_CallObject(reader, args);
679 Py_DECREF(reader);
680 Py_DECREF(args);
681 if (result != NULL && !PyString_Check(result)) {
682 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000683 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000684 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000685 "object.readline() returned non-string");
686 }
687 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000688 char *s = PyString_AsString(result);
689 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000690 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000691 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000692 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000693 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000694 "EOF when reading a line");
695 }
696 else if (s[len-1] == '\n') {
697 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000698 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000699 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000700 PyObject *v;
701 v = PyString_FromStringAndSize(s,
702 len-1);
703 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000704 result = v;
705 }
706 }
707 }
708 return result;
709 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000710 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000711 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000712 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000713}
714
715/* Python method */
716
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000717static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000718file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000719 PyFileObject *f;
720 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000721{
Guido van Rossum789a1611997-05-10 22:33:55 +0000722 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000723
Guido van Rossumd7297e61992-07-06 14:19:26 +0000724 if (f->f_fp == NULL)
725 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000726 if (!PyArg_ParseTuple(args, "|i", &n))
727 return NULL;
728 if (n == 0)
729 return PyString_FromString("");
730 if (n < 0)
731 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000732 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000733}
734
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000735static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000736file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000737 PyFileObject *f;
738 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000739{
Guido van Rossum789a1611997-05-10 22:33:55 +0000740 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000741 PyObject *list;
742 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000743 char small_buffer[SMALLCHUNK];
744 char *buffer = small_buffer;
745 size_t buffersize = SMALLCHUNK;
746 PyObject *big_buffer = NULL;
747 size_t nfilled = 0;
748 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000749 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000750 char *p, *q, *end;
751 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000752
Guido van Rossumd7297e61992-07-06 14:19:26 +0000753 if (f->f_fp == NULL)
754 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000755 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000756 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000757 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000758 return NULL;
759 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000760 Py_BEGIN_ALLOW_THREADS
761 errno = 0;
762 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
763 Py_END_ALLOW_THREADS
764 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000765 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000766 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000767 break;
768 PyErr_SetFromErrno(PyExc_IOError);
769 clearerr(f->f_fp);
770 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000771 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000772 list = NULL;
773 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000774 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000775 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000776 p = memchr(buffer+nfilled, '\n', nread);
777 if (p == NULL) {
778 /* Need a larger buffer to fit this line */
779 nfilled += nread;
780 buffersize *= 2;
781 if (big_buffer == NULL) {
782 /* Create the big buffer */
783 big_buffer = PyString_FromStringAndSize(
784 NULL, buffersize);
785 if (big_buffer == NULL)
786 goto error;
787 buffer = PyString_AS_STRING(big_buffer);
788 memcpy(buffer, small_buffer, nfilled);
789 }
790 else {
791 /* Grow the big buffer */
792 _PyString_Resize(&big_buffer, buffersize);
793 buffer = PyString_AS_STRING(big_buffer);
794 }
795 continue;
796 }
797 end = buffer+nfilled+nread;
798 q = buffer;
799 do {
800 /* Process complete lines */
801 p++;
802 line = PyString_FromStringAndSize(q, p-q);
803 if (line == NULL)
804 goto error;
805 err = PyList_Append(list, line);
806 Py_DECREF(line);
807 if (err != 0)
808 goto error;
809 q = p;
810 p = memchr(q, '\n', end-q);
811 } while (p != NULL);
812 /* Move the remaining incomplete line to the start */
813 nfilled = end-q;
814 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000815 if (sizehint > 0)
816 if (totalread >= (size_t)sizehint)
817 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000818 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000819 if (nfilled != 0) {
820 /* Partial last line */
821 line = PyString_FromStringAndSize(buffer, nfilled);
822 if (line == NULL)
823 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000824 if (sizehint > 0) {
825 /* Need to complete the last line */
826 PyObject *rest = getline(f, 0);
827 if (rest == NULL) {
828 Py_DECREF(line);
829 goto error;
830 }
831 PyString_Concat(&line, rest);
832 Py_DECREF(rest);
833 if (line == NULL)
834 goto error;
835 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000836 err = PyList_Append(list, line);
837 Py_DECREF(line);
838 if (err != 0)
839 goto error;
840 }
841 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000842 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000843 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000844 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000845 return list;
846}
847
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000848static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000849file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000850 PyFileObject *f;
851 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000852{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000853 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000854 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000855 if (f->f_fp == NULL)
856 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000857 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000858 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000859 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000860 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000862 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000863 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000864 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000865 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000866 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000867 return NULL;
868 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000869 Py_INCREF(Py_None);
870 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000871}
872
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000873static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000874file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000875 PyFileObject *f;
876 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000877{
878 int i, n;
879 if (f->f_fp == NULL)
880 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000881 if (args == NULL || !PyList_Check(args)) {
882 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000883 "writelines() requires list of strings");
884 return NULL;
885 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000886 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000887 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000889 errno = 0;
890 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000891 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000892 int len;
893 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000894 if (!PyString_Check(line)) {
895 Py_BLOCK_THREADS
896 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000897 "writelines() requires list of strings");
898 return NULL;
899 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000900 len = PyString_Size(line);
901 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000902 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 Py_BLOCK_THREADS
904 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000905 clearerr(f->f_fp);
906 return NULL;
907 }
908 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000909 Py_END_ALLOW_THREADS
910 Py_INCREF(Py_None);
911 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000912}
913
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000914static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000915 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000916 {"read", (PyCFunction)file_read, 1},
917 {"write", (PyCFunction)file_write, 0},
918 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +0000919 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000920#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +0000921 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000922#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000923 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000924 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000925 {"readlines", (PyCFunction)file_readlines, 1},
926 {"writelines", (PyCFunction)file_writelines, 0},
927 {"flush", (PyCFunction)file_flush, 0},
928 {"close", (PyCFunction)file_close, 0},
929 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930 {NULL, NULL} /* sentinel */
931};
932
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000933#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000934
935static struct memberlist file_memberlist[] = {
936 {"softspace", T_INT, OFF(f_softspace)},
937 {"mode", T_OBJECT, OFF(f_mode), RO},
938 {"name", T_OBJECT, OFF(f_name), RO},
939 /* getattr(f, "closed") is implemented without this table */
940 {"closed", T_INT, 0, RO},
941 {NULL} /* Sentinel */
942};
943
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000944static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000945file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000946 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000947 char *name;
948{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000949 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000950
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000951 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000952 if (res != NULL)
953 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000954 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000955 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000956 return PyInt_FromLong((long)(f->f_fp == 0));
957 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000958}
959
960static int
961file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000962 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000963 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000964 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000965{
966 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000967 PyErr_SetString(PyExc_AttributeError,
968 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000969 return -1;
970 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000971 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000972}
973
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000974PyTypeObject PyFile_Type = {
975 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000976 0,
977 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000978 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000979 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000980 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000981 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000982 (getattrfunc)file_getattr, /*tp_getattr*/
983 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000984 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000985 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000986};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000987
988/* Interface for the 'soft space' between print items. */
989
990int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000991PyFile_SoftSpace(f, newflag)
992 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000993 int newflag;
994{
995 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000996 if (f == NULL) {
997 /* Do nothing */
998 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000999 else if (PyFile_Check(f)) {
1000 oldflag = ((PyFileObject *)f)->f_softspace;
1001 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001002 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001003 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001004 PyObject *v;
1005 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001006 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001007 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001008 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001009 if (PyInt_Check(v))
1010 oldflag = PyInt_AsLong(v);
1011 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001012 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001014 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001015 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001016 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001017 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1018 PyErr_Clear();
1019 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001020 }
1021 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001022 return oldflag;
1023}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001024
1025/* Interfaces to write objects/strings to file-like objects */
1026
1027int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001028PyFile_WriteObject(v, f, flags)
1029 PyObject *v;
1030 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001031 int flags;
1032{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001033 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001034 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001035 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001036 return -1;
1037 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001038 else if (PyFile_Check(f)) {
1039 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001040 if (fp == NULL) {
1041 err_closed();
1042 return -1;
1043 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001044 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001045 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001046 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001047 if (writer == NULL)
1048 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001049 if (flags & Py_PRINT_RAW)
1050 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001051 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001052 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001053 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001054 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001055 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001056 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001057 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001058 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001059 Py_DECREF(value);
1060 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001061 return -1;
1062 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001063 result = PyEval_CallObject(writer, args);
1064 Py_DECREF(args);
1065 Py_DECREF(value);
1066 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001067 if (result == NULL)
1068 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001069 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001070 return 0;
1071}
1072
Guido van Rossum27a60b11997-05-22 22:25:11 +00001073int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001074PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001075 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001076 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001077{
1078 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001079 /* Should be caused by a pre-existing error */
1080 if(!PyErr_Occurred())
1081 PyErr_SetString(PyExc_SystemError,
1082 "null file for PyFile_WriteString");
1083 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001084 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001085 else if (PyFile_Check(f)) {
1086 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001087 if (fp == NULL) {
1088 err_closed();
1089 return -1;
1090 }
1091 fputs(s, fp);
1092 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001093 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001094 else if (!PyErr_Occurred()) {
1095 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001096 int err;
1097 if (v == NULL)
1098 return -1;
1099 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1100 Py_DECREF(v);
1101 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001102 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001103 else
1104 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001105}