blob: d07aa69e61e49c2031f429f2c67bf873fa3a4a15 [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 Rossum295d1711995-02-19 15:55:19 +000047#ifdef THINK_C
48#define HAVE_FOPENRF
49#endif
Jack Jansene08dea191995-04-23 22:12:47 +000050#ifdef __MWERKS__
51/* Mwerks fopen() doesn't always set errno */
52#define NO_FOPEN_ERRNO
53#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000054
Guido van Rossumc0b618a1997-05-02 03:12:38 +000055#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000056
Guido van Rossumf1dc5661993-07-05 10:31:29 +000057#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000058
59typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000060 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000062 PyObject *f_name;
63 PyObject *f_mode;
64 int (*f_close) Py_PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000065 int f_softspace; /* Flag used by 'print' command */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000066} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067
68FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +000069PyFile_AsFile(f)
70 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000072 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000074 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000075 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076}
77
Guido van Rossumc0b618a1997-05-02 03:12:38 +000078PyObject *
79PyFile_Name(f)
80 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000081{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000083 return NULL;
84 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000085 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000086}
87
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088PyObject *
89PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090 FILE *fp;
91 char *name;
92 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000093 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000095 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 if (f == NULL)
97 return NULL;
98 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000099 f->f_name = PyString_FromString(name);
100 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000101 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000102 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000104 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105 return NULL;
106 }
107 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000108 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109}
110
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000111PyObject *
112PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 char *name, *mode;
114{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115 extern int fclose Py_PROTO((FILE *));
116 PyFileObject *f;
117 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 if (f == NULL)
119 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000120#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000121 if (*mode == '*') {
122 FILE *fopenRF();
123 f->f_fp = fopenRF(name, mode+1);
124 }
125 else
126#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000127 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000128 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000129 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000130 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000131 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000132 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000133#ifdef NO_FOPEN_ERRNO
134 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000135 PyErr_SetString(PyExc_IOError, "Cannot open file");
136 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000137 return NULL;
138 }
139#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000140 PyErr_SetFromErrno(PyExc_IOError);
141 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000142 return NULL;
143 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000144 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145}
146
Guido van Rossumb6775db1994-08-01 11:34:53 +0000147void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000148PyFile_SetBufSize(f, bufsize)
149 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000150 int bufsize;
151{
152 if (bufsize >= 0) {
153#ifdef HAVE_SETVBUF
154 int type;
155 switch (bufsize) {
156 case 0:
157 type = _IONBF;
158 break;
159 case 1:
160 type = _IOLBF;
161 bufsize = BUFSIZ;
162 break;
163 default:
164 type = _IOFBF;
165 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000166 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
167 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000168#else /* !HAVE_SETVBUF */
169 if (bufsize <= 1)
170 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
171#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172 }
173}
174
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000175static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000176err_closed()
177{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000178 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000179 return NULL;
180}
181
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182/* Methods */
183
184static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000185file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000186 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000188 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000189 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000190 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000191 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000192 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 if (f->f_name != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000194 Py_DECREF(f->f_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195 if (f->f_mode != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000196 Py_DECREF(f->f_mode);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 free((char *)f);
198}
199
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000200static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000201file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000202 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000203{
204 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000205 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207 PyString_AsString(f->f_name),
208 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000209 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000210 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211}
212
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000213static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000214file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000215 PyFileObject *f;
216 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000218 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000219 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000221 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000222 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000223 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000224 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000225 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000226 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000227 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228 f->f_fp = NULL;
229 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000230 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000232 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 return PyInt_FromLong((long)sts);
234 Py_INCREF(Py_None);
235 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236}
237
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000238static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000239file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 PyFileObject *f;
241 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000243 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000244 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000245 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000246
Guido van Rossumd7297e61992-07-06 14:19:26 +0000247 if (f->f_fp == NULL)
248 return err_closed();
249 whence = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000250 if (!PyArg_Parse(args, "l", &offset)) {
251 PyErr_Clear();
252 if (!PyArg_Parse(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000253 return NULL;
254 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000255 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000256 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000257 ret = fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000258 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000259 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000260 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000261 clearerr(f->f_fp);
262 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000263 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000264 Py_INCREF(Py_None);
265 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000266}
267
Guido van Rossumd7047b31995-01-02 19:07:15 +0000268#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000269static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000270file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000271 PyFileObject *f;
272 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000273{
274 long newsize;
275 int ret;
276
277 if (f->f_fp == NULL)
278 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000279 if (!PyArg_Parse(args, "l", &newsize)) {
280 PyErr_Clear();
281 if (!PyArg_NoArgs(args))
Guido van Rossumd7047b31995-01-02 19:07:15 +0000282 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000283 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000284 errno = 0;
285 newsize = ftell(f->f_fp); /* default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000286 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000287 if (newsize == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000288 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000289 clearerr(f->f_fp);
290 return NULL;
291 }
292 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000293 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000294 errno = 0;
295 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000296 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000297 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000298 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000299 errno = 0;
300 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000301 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000302 }
303 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000304 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000305 clearerr(f->f_fp);
306 return NULL;
307 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000308 Py_INCREF(Py_None);
309 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000310}
311#endif /* HAVE_FTRUNCATE */
312
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000313static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000314file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000315 PyFileObject *f;
316 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000317{
318 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000319 if (f->f_fp == NULL)
320 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000321 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000324 errno = 0;
325 offset = ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000326 Py_END_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000327 if (offset == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000329 clearerr(f->f_fp);
330 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000331 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000332 return PyInt_FromLong(offset);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000333}
334
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000336file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000337 PyFileObject *f;
338 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000339{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000340 if (f->f_fp == NULL)
341 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000342 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000343 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000345}
346
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000348file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 PyFileObject *f;
350 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000351{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000352 int res;
353
Guido van Rossumd7297e61992-07-06 14:19:26 +0000354 if (f->f_fp == NULL)
355 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000359 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000360 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000361 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000362 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000363 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000364 clearerr(f->f_fp);
365 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000366 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000367 Py_INCREF(Py_None);
368 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000369}
370
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000371static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000372file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373 PyFileObject *f;
374 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000375{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000376 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000377 if (f->f_fp == NULL)
378 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000379 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000380 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000382 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383 Py_END_ALLOW_THREADS
384 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000385}
386
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000387/* We expect that fstat exists on most systems.
388 It's confirmed on Unix, Mac and Windows.
389 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
390#ifndef DONT_HAVE_FSTAT
391#define HAVE_FSTAT
392
393#include <sys/types.h>
394#include <sys/stat.h>
395
396#endif
397
398#if BUFSIZ < 8192
399#define SMALLCHUNK 8192
400#else
401#define SMALLCHUNK BUFSIZ
402#endif
403
404#define BIGCHUNK (512*1024)
405
406static size_t
407new_buffersize(f, currentsize)
408 PyFileObject *f;
409 size_t currentsize;
410{
411#ifdef HAVE_FSTAT
412 long pos, end;
413 struct stat st;
414 if (fstat(fileno(f->f_fp), &st) == 0) {
415 end = st.st_size;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000416 pos = ftell(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000417 if (end > pos && pos >= 0)
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000418 return end - pos + 1;
419 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000420 }
421#endif
422 if (currentsize > SMALLCHUNK) {
423 /* Keep doubling until we reach BIGCHUNK;
424 then keep adding BIGCHUNK. */
425 if (currentsize <= BIGCHUNK)
426 return currentsize + currentsize;
427 else
428 return currentsize + BIGCHUNK;
429 }
430 return currentsize + SMALLCHUNK;
431}
432
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000433static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000434file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000435 PyFileObject *f;
436 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000437{
Guido van Rossum789a1611997-05-10 22:33:55 +0000438 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000439 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000440 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000441
Guido van Rossumd7297e61992-07-06 14:19:26 +0000442 if (f->f_fp == NULL)
443 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000444 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
445 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000446 if (bytesrequested < 0)
447 buffersize = new_buffersize(f, 0);
448 else
449 buffersize = bytesrequested;
450 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000451 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000452 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000453 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000454 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000455 Py_BEGIN_ALLOW_THREADS
456 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000457 chunksize = fread(BUF(v) + bytesread, 1,
458 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000459 Py_END_ALLOW_THREADS
460 if (chunksize == 0) {
461 if (!ferror(f->f_fp))
462 break;
463 PyErr_SetFromErrno(PyExc_IOError);
464 clearerr(f->f_fp);
465 Py_DECREF(v);
466 return NULL;
467 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000468 bytesread += chunksize;
469 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000470 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000471 if (bytesrequested < 0) {
472 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000473 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000474 return NULL;
475 }
476 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000477 if (bytesread != buffersize)
478 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479 return v;
480}
481
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000482static PyObject *
483file_readinto(f, args)
484 PyFileObject *f;
485 PyObject *args;
486{
487 char *ptr;
488 int ntodo, ndone, nnow;
489
490 if (f->f_fp == NULL)
491 return err_closed();
492 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
493 return NULL;
494 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000495 while (ntodo > 0) {
496 Py_BEGIN_ALLOW_THREADS
497 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000498 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000499 Py_END_ALLOW_THREADS
500 if (nnow == 0) {
501 if (!ferror(f->f_fp))
502 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000503 PyErr_SetFromErrno(PyExc_IOError);
504 clearerr(f->f_fp);
505 return NULL;
506 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000507 ndone += nnow;
508 ntodo -= nnow;
509 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000510 return PyInt_FromLong(ndone);
511}
512
513
Guido van Rossum0bd24411991-04-04 15:21:57 +0000514/* Internal routine to get a line.
515 Size argument interpretation:
516 > 0: max length;
517 = 0: read arbitrary line;
518 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000519*/
520
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000521static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000522getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000524 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000526 register FILE *fp;
527 register int c;
528 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000529 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000530 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000531
Guido van Rossumc10aa771992-07-31 12:42:38 +0000532 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000533 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000534 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000535 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000536 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000537 buf = BUF(v);
538 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000539
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000540 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000541 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000542 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000543 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000544 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000545 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000546 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000547 return NULL;
548 }
549 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000550 Py_DECREF(v);
551 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000552 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000553 return NULL;
554 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000555 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000556 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000557 }
558 if ((*buf++ = c) == '\n') {
559 if (n < 0)
560 buf--;
561 break;
562 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000563 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000564 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000565 break;
566 n1 = n2;
567 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 Py_BLOCK_THREADS
569 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000570 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000571 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000572 buf = BUF(v) + n1;
573 end = BUF(v) + n2;
574 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000575 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000577
Guido van Rossumce5ba841991-03-06 13:06:18 +0000578 n1 = buf - BUF(v);
579 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000580 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000581 return v;
582}
583
Guido van Rossum0bd24411991-04-04 15:21:57 +0000584/* External C interface */
585
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000586PyObject *
587PyFile_GetLine(f, n)
588 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000589 int n;
590{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000591 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000593 return NULL;
594 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000595 if (!PyFile_Check(f)) {
596 PyObject *reader;
597 PyObject *args;
598 PyObject *result;
599 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000600 if (reader == NULL)
601 return NULL;
602 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000603 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000604 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000605 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000606 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000608 return NULL;
609 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000610 result = PyEval_CallObject(reader, args);
611 Py_DECREF(reader);
612 Py_DECREF(args);
613 if (result != NULL && !PyString_Check(result)) {
614 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000615 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000616 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000617 "object.readline() returned non-string");
618 }
619 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000620 char *s = PyString_AsString(result);
621 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000622 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000623 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000624 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000626 "EOF when reading a line");
627 }
628 else if (s[len-1] == '\n') {
629 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000630 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000631 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 PyObject *v;
633 v = PyString_FromStringAndSize(s,
634 len-1);
635 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000636 result = v;
637 }
638 }
639 }
640 return result;
641 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000642 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000643 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000644 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000645}
646
647/* Python method */
648
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000649static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000650file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000651 PyFileObject *f;
652 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000653{
Guido van Rossum789a1611997-05-10 22:33:55 +0000654 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000655
Guido van Rossumd7297e61992-07-06 14:19:26 +0000656 if (f->f_fp == NULL)
657 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000658 if (!PyArg_ParseTuple(args, "|i", &n))
659 return NULL;
660 if (n == 0)
661 return PyString_FromString("");
662 if (n < 0)
663 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000664 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000665}
666
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000667static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000668file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669 PyFileObject *f;
670 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000671{
Guido van Rossum789a1611997-05-10 22:33:55 +0000672 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000673 PyObject *list;
674 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000675 char small_buffer[SMALLCHUNK];
676 char *buffer = small_buffer;
677 size_t buffersize = SMALLCHUNK;
678 PyObject *big_buffer = NULL;
679 size_t nfilled = 0;
680 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000681 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000682 char *p, *q, *end;
683 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000684
Guido van Rossumd7297e61992-07-06 14:19:26 +0000685 if (f->f_fp == NULL)
686 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000687 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000688 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000689 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000690 return NULL;
691 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000692 Py_BEGIN_ALLOW_THREADS
693 errno = 0;
694 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
695 Py_END_ALLOW_THREADS
696 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000697 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000698 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000699 break;
700 PyErr_SetFromErrno(PyExc_IOError);
701 clearerr(f->f_fp);
702 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000703 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000704 list = NULL;
705 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000706 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000707 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000708 p = memchr(buffer+nfilled, '\n', nread);
709 if (p == NULL) {
710 /* Need a larger buffer to fit this line */
711 nfilled += nread;
712 buffersize *= 2;
713 if (big_buffer == NULL) {
714 /* Create the big buffer */
715 big_buffer = PyString_FromStringAndSize(
716 NULL, buffersize);
717 if (big_buffer == NULL)
718 goto error;
719 buffer = PyString_AS_STRING(big_buffer);
720 memcpy(buffer, small_buffer, nfilled);
721 }
722 else {
723 /* Grow the big buffer */
724 _PyString_Resize(&big_buffer, buffersize);
725 buffer = PyString_AS_STRING(big_buffer);
726 }
727 continue;
728 }
729 end = buffer+nfilled+nread;
730 q = buffer;
731 do {
732 /* Process complete lines */
733 p++;
734 line = PyString_FromStringAndSize(q, p-q);
735 if (line == NULL)
736 goto error;
737 err = PyList_Append(list, line);
738 Py_DECREF(line);
739 if (err != 0)
740 goto error;
741 q = p;
742 p = memchr(q, '\n', end-q);
743 } while (p != NULL);
744 /* Move the remaining incomplete line to the start */
745 nfilled = end-q;
746 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000747 if (sizehint > 0)
748 if (totalread >= (size_t)sizehint)
749 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000750 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000751 if (nfilled != 0) {
752 /* Partial last line */
753 line = PyString_FromStringAndSize(buffer, nfilled);
754 if (line == NULL)
755 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000756 if (sizehint > 0) {
757 /* Need to complete the last line */
758 PyObject *rest = getline(f, 0);
759 if (rest == NULL) {
760 Py_DECREF(line);
761 goto error;
762 }
763 PyString_Concat(&line, rest);
764 Py_DECREF(rest);
765 if (line == NULL)
766 goto error;
767 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000768 err = PyList_Append(list, line);
769 Py_DECREF(line);
770 if (err != 0)
771 goto error;
772 }
773 cleanup:
774 if (big_buffer)
775 Py_DECREF(big_buffer);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000776 return list;
777}
778
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000779static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000780file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000781 PyFileObject *f;
782 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000783{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000784 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000785 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000786 if (f->f_fp == NULL)
787 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000788 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000789 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000790 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000791 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000792 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000793 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000794 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000796 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000797 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000798 return NULL;
799 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000800 Py_INCREF(Py_None);
801 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000802}
803
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000804static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000805file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000806 PyFileObject *f;
807 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000808{
809 int i, n;
810 if (f->f_fp == NULL)
811 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000812 if (args == NULL || !PyList_Check(args)) {
813 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000814 "writelines() requires list of strings");
815 return NULL;
816 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000817 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000818 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000819 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000820 errno = 0;
821 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000822 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000823 int len;
824 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000825 if (!PyString_Check(line)) {
826 Py_BLOCK_THREADS
827 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000828 "writelines() requires list of strings");
829 return NULL;
830 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000831 len = PyString_Size(line);
832 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000833 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000834 Py_BLOCK_THREADS
835 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000836 clearerr(f->f_fp);
837 return NULL;
838 }
839 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000840 Py_END_ALLOW_THREADS
841 Py_INCREF(Py_None);
842 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000843}
844
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000845static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000846 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000847 {"read", (PyCFunction)file_read, 1},
848 {"write", (PyCFunction)file_write, 0},
849 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000850 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000851#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000852 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000853#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000854 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000855 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000856 {"readlines", (PyCFunction)file_readlines, 1},
857 {"writelines", (PyCFunction)file_writelines, 0},
858 {"flush", (PyCFunction)file_flush, 0},
859 {"close", (PyCFunction)file_close, 0},
860 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861 {NULL, NULL} /* sentinel */
862};
863
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000864#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000865
866static struct memberlist file_memberlist[] = {
867 {"softspace", T_INT, OFF(f_softspace)},
868 {"mode", T_OBJECT, OFF(f_mode), RO},
869 {"name", T_OBJECT, OFF(f_name), RO},
870 /* getattr(f, "closed") is implemented without this table */
871 {"closed", T_INT, 0, RO},
872 {NULL} /* Sentinel */
873};
874
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000875static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000876file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000877 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000878 char *name;
879{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000880 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000881
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000882 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000883 if (res != NULL)
884 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000885 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000887 return PyInt_FromLong((long)(f->f_fp == 0));
888 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000889}
890
891static int
892file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000893 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000894 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000895 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000896{
897 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000898 PyErr_SetString(PyExc_AttributeError,
899 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000900 return -1;
901 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000902 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000903}
904
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000905PyTypeObject PyFile_Type = {
906 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000907 0,
908 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000909 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000910 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000911 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000912 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000913 (getattrfunc)file_getattr, /*tp_getattr*/
914 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000915 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000916 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000917};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000918
919/* Interface for the 'soft space' between print items. */
920
921int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000922PyFile_SoftSpace(f, newflag)
923 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000924 int newflag;
925{
926 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000927 if (f == NULL) {
928 /* Do nothing */
929 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000930 else if (PyFile_Check(f)) {
931 oldflag = ((PyFileObject *)f)->f_softspace;
932 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000933 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000934 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000935 PyObject *v;
936 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000937 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000938 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000939 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000940 if (PyInt_Check(v))
941 oldflag = PyInt_AsLong(v);
942 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000943 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000944 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000945 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000946 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000947 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000948 if (PyObject_SetAttrString(f, "softspace", v) != 0)
949 PyErr_Clear();
950 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000951 }
952 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000953 return oldflag;
954}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000955
956/* Interfaces to write objects/strings to file-like objects */
957
958int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000959PyFile_WriteObject(v, f, flags)
960 PyObject *v;
961 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000962 int flags;
963{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000964 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000965 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000966 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000967 return -1;
968 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000969 else if (PyFile_Check(f)) {
970 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000971 if (fp == NULL) {
972 err_closed();
973 return -1;
974 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000975 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000976 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000977 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000978 if (writer == NULL)
979 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980 if (flags & Py_PRINT_RAW)
981 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000982 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000983 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000984 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000985 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +0000986 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000987 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000988 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +0000989 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000990 Py_DECREF(value);
991 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000992 return -1;
993 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000994 result = PyEval_CallObject(writer, args);
995 Py_DECREF(args);
996 Py_DECREF(value);
997 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000998 if (result == NULL)
999 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001000 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001001 return 0;
1002}
1003
Guido van Rossum27a60b11997-05-22 22:25:11 +00001004int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001005PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001006 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001007 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001008{
1009 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001010 /* Should be caused by a pre-existing error */
1011 if(!PyErr_Occurred())
1012 PyErr_SetString(PyExc_SystemError,
1013 "null file for PyFile_WriteString");
1014 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001015 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001016 else if (PyFile_Check(f)) {
1017 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001018 if (fp == NULL) {
1019 err_closed();
1020 return -1;
1021 }
1022 fputs(s, fp);
1023 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001024 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001025 else if (!PyErr_Occurred()) {
1026 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001027 int err;
1028 if (v == NULL)
1029 return -1;
1030 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1031 Py_DECREF(v);
1032 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001033 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001034 else
1035 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001036}