blob: b744ab427bf8ee1e78d8cc8778bade1674672d4f [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 Rossum1109fbc1998-04-10 22:16:39 +0000193 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000194 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000195 }
196 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000197 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000198 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000199 free((char *)f);
200}
201
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000202static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000203file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205{
206 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000207 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209 PyString_AsString(f->f_name),
210 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000211 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000212 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213}
214
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000215static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000216file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000217 PyFileObject *f;
218 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000220 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000224 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000225 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000226 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000227 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000229 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 f->f_fp = NULL;
231 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000232 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000234 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 return PyInt_FromLong((long)sts);
236 Py_INCREF(Py_None);
237 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238}
239
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000241file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242 PyFileObject *f;
243 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000244{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000245 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000246 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000247 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000248
Guido van Rossumd7297e61992-07-06 14:19:26 +0000249 if (f->f_fp == NULL)
250 return err_closed();
251 whence = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000252 if (!PyArg_Parse(args, "l", &offset)) {
253 PyErr_Clear();
254 if (!PyArg_Parse(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000255 return NULL;
256 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000257 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000258 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000259 ret = fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000260 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000261 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000262 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000263 clearerr(f->f_fp);
264 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000265 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000266 Py_INCREF(Py_None);
267 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000268}
269
Guido van Rossumd7047b31995-01-02 19:07:15 +0000270#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000271static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000272file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000273 PyFileObject *f;
274 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000275{
276 long newsize;
277 int ret;
278
279 if (f->f_fp == NULL)
280 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000281 if (!PyArg_Parse(args, "l", &newsize)) {
282 PyErr_Clear();
283 if (!PyArg_NoArgs(args))
Guido van Rossumd7047b31995-01-02 19:07:15 +0000284 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000285 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000286 errno = 0;
287 newsize = ftell(f->f_fp); /* default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000288 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000289 if (newsize == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000290 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000291 clearerr(f->f_fp);
292 return NULL;
293 }
294 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000295 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000296 errno = 0;
297 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000298 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000299 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000300 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000301 errno = 0;
302 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000303 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000304 }
305 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000307 clearerr(f->f_fp);
308 return NULL;
309 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310 Py_INCREF(Py_None);
311 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000312}
313#endif /* HAVE_FTRUNCATE */
314
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000315static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000316file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000317 PyFileObject *f;
318 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000319{
320 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000321 if (f->f_fp == NULL)
322 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000325 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000326 errno = 0;
327 offset = ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 Py_END_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000329 if (offset == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000330 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000331 clearerr(f->f_fp);
332 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000333 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000334 return PyInt_FromLong(offset);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000335}
336
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000337static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000338file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000339 PyFileObject *f;
340 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000341{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000342 if (f->f_fp == NULL)
343 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000345 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000347}
348
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000350file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 PyFileObject *f;
352 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000353{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000354 int res;
355
Guido van Rossumd7297e61992-07-06 14:19:26 +0000356 if (f->f_fp == NULL)
357 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000359 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000360 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000361 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000362 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000363 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000364 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000365 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000366 clearerr(f->f_fp);
367 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000368 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000369 Py_INCREF(Py_None);
370 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000371}
372
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000374file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000375 PyFileObject *f;
376 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000377{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000378 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000379 if (f->f_fp == NULL)
380 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000382 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000384 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000385 Py_END_ALLOW_THREADS
386 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000387}
388
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000389/* We expect that fstat exists on most systems.
390 It's confirmed on Unix, Mac and Windows.
391 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
392#ifndef DONT_HAVE_FSTAT
393#define HAVE_FSTAT
394
395#include <sys/types.h>
396#include <sys/stat.h>
397
398#endif
399
400#if BUFSIZ < 8192
401#define SMALLCHUNK 8192
402#else
403#define SMALLCHUNK BUFSIZ
404#endif
405
406#define BIGCHUNK (512*1024)
407
408static size_t
409new_buffersize(f, currentsize)
410 PyFileObject *f;
411 size_t currentsize;
412{
413#ifdef HAVE_FSTAT
414 long pos, end;
415 struct stat st;
416 if (fstat(fileno(f->f_fp), &st) == 0) {
417 end = st.st_size;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000418 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000419 if (pos < 0)
420 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000421 if (end > pos && pos >= 0)
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000422 return end - pos + 1;
423 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000424 }
425#endif
426 if (currentsize > SMALLCHUNK) {
427 /* Keep doubling until we reach BIGCHUNK;
428 then keep adding BIGCHUNK. */
429 if (currentsize <= BIGCHUNK)
430 return currentsize + currentsize;
431 else
432 return currentsize + BIGCHUNK;
433 }
434 return currentsize + SMALLCHUNK;
435}
436
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000438file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000439 PyFileObject *f;
440 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000441{
Guido van Rossum789a1611997-05-10 22:33:55 +0000442 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000443 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000444 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000445
Guido van Rossumd7297e61992-07-06 14:19:26 +0000446 if (f->f_fp == NULL)
447 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000448 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
449 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000450 if (bytesrequested < 0)
451 buffersize = new_buffersize(f, 0);
452 else
453 buffersize = bytesrequested;
454 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000455 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000456 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000457 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000458 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000459 Py_BEGIN_ALLOW_THREADS
460 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000461 chunksize = fread(BUF(v) + bytesread, 1,
462 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000463 Py_END_ALLOW_THREADS
464 if (chunksize == 0) {
465 if (!ferror(f->f_fp))
466 break;
467 PyErr_SetFromErrno(PyExc_IOError);
468 clearerr(f->f_fp);
469 Py_DECREF(v);
470 return NULL;
471 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000472 bytesread += chunksize;
473 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000474 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000475 if (bytesrequested < 0) {
Guido van Rossum240c35a1998-03-18 17:59:20 +0000476 buffersize = bytesread + new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000477 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000478 return NULL;
479 }
480 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000481 if (bytesread != buffersize)
482 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483 return v;
484}
485
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000486static PyObject *
487file_readinto(f, args)
488 PyFileObject *f;
489 PyObject *args;
490{
491 char *ptr;
492 int ntodo, ndone, nnow;
493
494 if (f->f_fp == NULL)
495 return err_closed();
496 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
497 return NULL;
498 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000499 while (ntodo > 0) {
500 Py_BEGIN_ALLOW_THREADS
501 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000502 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000503 Py_END_ALLOW_THREADS
504 if (nnow == 0) {
505 if (!ferror(f->f_fp))
506 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000507 PyErr_SetFromErrno(PyExc_IOError);
508 clearerr(f->f_fp);
509 return NULL;
510 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000511 ndone += nnow;
512 ntodo -= nnow;
513 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000514 return PyInt_FromLong(ndone);
515}
516
517
Guido van Rossum0bd24411991-04-04 15:21:57 +0000518/* Internal routine to get a line.
519 Size argument interpretation:
520 > 0: max length;
521 = 0: read arbitrary line;
522 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000523*/
524
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000525static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000526getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000527 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000528 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000530 register FILE *fp;
531 register int c;
532 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000533 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000534 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000535
Guido van Rossumc10aa771992-07-31 12:42:38 +0000536 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000537 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000538 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000539 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000540 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000541 buf = BUF(v);
542 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000543
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000544 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000545 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000546 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000547 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000548 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000549 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000550 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000551 return NULL;
552 }
553 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554 Py_DECREF(v);
555 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000556 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000557 return NULL;
558 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000559 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000560 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000561 }
562 if ((*buf++ = c) == '\n') {
563 if (n < 0)
564 buf--;
565 break;
566 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000567 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000568 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000569 break;
570 n1 = n2;
571 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000572 Py_BLOCK_THREADS
573 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000574 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000575 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000576 buf = BUF(v) + n1;
577 end = BUF(v) + n2;
578 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000579 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000580 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000581
Guido van Rossumce5ba841991-03-06 13:06:18 +0000582 n1 = buf - BUF(v);
583 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000584 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000585 return v;
586}
587
Guido van Rossum0bd24411991-04-04 15:21:57 +0000588/* External C interface */
589
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000590PyObject *
591PyFile_GetLine(f, n)
592 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000593 int n;
594{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000595 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000596 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000597 return NULL;
598 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000599 if (!PyFile_Check(f)) {
600 PyObject *reader;
601 PyObject *args;
602 PyObject *result;
603 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000604 if (reader == NULL)
605 return NULL;
606 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000608 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000609 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000610 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000611 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000612 return NULL;
613 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000614 result = PyEval_CallObject(reader, args);
615 Py_DECREF(reader);
616 Py_DECREF(args);
617 if (result != NULL && !PyString_Check(result)) {
618 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000619 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000620 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000621 "object.readline() returned non-string");
622 }
623 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000624 char *s = PyString_AsString(result);
625 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000626 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000628 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000630 "EOF when reading a line");
631 }
632 else if (s[len-1] == '\n') {
633 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000634 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000635 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000636 PyObject *v;
637 v = PyString_FromStringAndSize(s,
638 len-1);
639 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000640 result = v;
641 }
642 }
643 }
644 return result;
645 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000646 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000647 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000648 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000649}
650
651/* Python method */
652
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000653static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000654file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000655 PyFileObject *f;
656 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000657{
Guido van Rossum789a1611997-05-10 22:33:55 +0000658 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000659
Guido van Rossumd7297e61992-07-06 14:19:26 +0000660 if (f->f_fp == NULL)
661 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000662 if (!PyArg_ParseTuple(args, "|i", &n))
663 return NULL;
664 if (n == 0)
665 return PyString_FromString("");
666 if (n < 0)
667 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000668 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000669}
670
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000672file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000673 PyFileObject *f;
674 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000675{
Guido van Rossum789a1611997-05-10 22:33:55 +0000676 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000677 PyObject *list;
678 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000679 char small_buffer[SMALLCHUNK];
680 char *buffer = small_buffer;
681 size_t buffersize = SMALLCHUNK;
682 PyObject *big_buffer = NULL;
683 size_t nfilled = 0;
684 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000685 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000686 char *p, *q, *end;
687 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000688
Guido van Rossumd7297e61992-07-06 14:19:26 +0000689 if (f->f_fp == NULL)
690 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000691 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000692 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000693 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000694 return NULL;
695 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000696 Py_BEGIN_ALLOW_THREADS
697 errno = 0;
698 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
699 Py_END_ALLOW_THREADS
700 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000701 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000702 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000703 break;
704 PyErr_SetFromErrno(PyExc_IOError);
705 clearerr(f->f_fp);
706 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000707 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000708 list = NULL;
709 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000710 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000711 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000712 p = memchr(buffer+nfilled, '\n', nread);
713 if (p == NULL) {
714 /* Need a larger buffer to fit this line */
715 nfilled += nread;
716 buffersize *= 2;
717 if (big_buffer == NULL) {
718 /* Create the big buffer */
719 big_buffer = PyString_FromStringAndSize(
720 NULL, buffersize);
721 if (big_buffer == NULL)
722 goto error;
723 buffer = PyString_AS_STRING(big_buffer);
724 memcpy(buffer, small_buffer, nfilled);
725 }
726 else {
727 /* Grow the big buffer */
728 _PyString_Resize(&big_buffer, buffersize);
729 buffer = PyString_AS_STRING(big_buffer);
730 }
731 continue;
732 }
733 end = buffer+nfilled+nread;
734 q = buffer;
735 do {
736 /* Process complete lines */
737 p++;
738 line = PyString_FromStringAndSize(q, p-q);
739 if (line == NULL)
740 goto error;
741 err = PyList_Append(list, line);
742 Py_DECREF(line);
743 if (err != 0)
744 goto error;
745 q = p;
746 p = memchr(q, '\n', end-q);
747 } while (p != NULL);
748 /* Move the remaining incomplete line to the start */
749 nfilled = end-q;
750 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000751 if (sizehint > 0)
752 if (totalread >= (size_t)sizehint)
753 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000754 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000755 if (nfilled != 0) {
756 /* Partial last line */
757 line = PyString_FromStringAndSize(buffer, nfilled);
758 if (line == NULL)
759 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000760 if (sizehint > 0) {
761 /* Need to complete the last line */
762 PyObject *rest = getline(f, 0);
763 if (rest == NULL) {
764 Py_DECREF(line);
765 goto error;
766 }
767 PyString_Concat(&line, rest);
768 Py_DECREF(rest);
769 if (line == NULL)
770 goto error;
771 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000772 err = PyList_Append(list, line);
773 Py_DECREF(line);
774 if (err != 0)
775 goto error;
776 }
777 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000778 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000779 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000780 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000781 return list;
782}
783
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000784static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000785file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000786 PyFileObject *f;
787 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000788{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000789 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000790 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000791 if (f->f_fp == NULL)
792 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000793 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000794 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000795 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000796 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000797 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000798 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000799 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000800 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000801 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000802 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000803 return NULL;
804 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000805 Py_INCREF(Py_None);
806 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000807}
808
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000809static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000810file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000811 PyFileObject *f;
812 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000813{
814 int i, n;
815 if (f->f_fp == NULL)
816 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000817 if (args == NULL || !PyList_Check(args)) {
818 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000819 "writelines() requires list of strings");
820 return NULL;
821 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000822 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000823 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000824 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000825 errno = 0;
826 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000827 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000828 int len;
829 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000830 if (!PyString_Check(line)) {
831 Py_BLOCK_THREADS
832 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000833 "writelines() requires list of strings");
834 return NULL;
835 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000836 len = PyString_Size(line);
837 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000838 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000839 Py_BLOCK_THREADS
840 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000841 clearerr(f->f_fp);
842 return NULL;
843 }
844 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000845 Py_END_ALLOW_THREADS
846 Py_INCREF(Py_None);
847 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000848}
849
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000850static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000851 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000852 {"read", (PyCFunction)file_read, 1},
853 {"write", (PyCFunction)file_write, 0},
854 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000855 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000856#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000857 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000858#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000859 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000860 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000861 {"readlines", (PyCFunction)file_readlines, 1},
862 {"writelines", (PyCFunction)file_writelines, 0},
863 {"flush", (PyCFunction)file_flush, 0},
864 {"close", (PyCFunction)file_close, 0},
865 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000866 {NULL, NULL} /* sentinel */
867};
868
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000869#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000870
871static struct memberlist file_memberlist[] = {
872 {"softspace", T_INT, OFF(f_softspace)},
873 {"mode", T_OBJECT, OFF(f_mode), RO},
874 {"name", T_OBJECT, OFF(f_name), RO},
875 /* getattr(f, "closed") is implemented without this table */
876 {"closed", T_INT, 0, RO},
877 {NULL} /* Sentinel */
878};
879
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000880static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000881file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000882 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000883 char *name;
884{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000885 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000887 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000888 if (res != NULL)
889 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000891 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000892 return PyInt_FromLong((long)(f->f_fp == 0));
893 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000894}
895
896static int
897file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000898 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000899 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000900 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000901{
902 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 PyErr_SetString(PyExc_AttributeError,
904 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000905 return -1;
906 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000907 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000908}
909
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000910PyTypeObject PyFile_Type = {
911 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000912 0,
913 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000914 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000915 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000916 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000917 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000918 (getattrfunc)file_getattr, /*tp_getattr*/
919 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000921 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000922};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000923
924/* Interface for the 'soft space' between print items. */
925
926int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000927PyFile_SoftSpace(f, newflag)
928 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000929 int newflag;
930{
931 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000932 if (f == NULL) {
933 /* Do nothing */
934 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000935 else if (PyFile_Check(f)) {
936 oldflag = ((PyFileObject *)f)->f_softspace;
937 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000938 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000939 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000940 PyObject *v;
941 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000942 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000943 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000944 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000945 if (PyInt_Check(v))
946 oldflag = PyInt_AsLong(v);
947 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000948 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000949 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000950 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000951 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000952 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000953 if (PyObject_SetAttrString(f, "softspace", v) != 0)
954 PyErr_Clear();
955 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000956 }
957 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000958 return oldflag;
959}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000960
961/* Interfaces to write objects/strings to file-like objects */
962
963int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000964PyFile_WriteObject(v, f, flags)
965 PyObject *v;
966 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000967 int flags;
968{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000969 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000970 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000971 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000972 return -1;
973 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000974 else if (PyFile_Check(f)) {
975 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000976 if (fp == NULL) {
977 err_closed();
978 return -1;
979 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000981 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000982 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000983 if (writer == NULL)
984 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000985 if (flags & Py_PRINT_RAW)
986 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000987 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000988 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000989 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000990 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +0000991 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000992 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000993 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +0000994 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000995 Py_DECREF(value);
996 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000997 return -1;
998 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000999 result = PyEval_CallObject(writer, args);
1000 Py_DECREF(args);
1001 Py_DECREF(value);
1002 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001003 if (result == NULL)
1004 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001005 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001006 return 0;
1007}
1008
Guido van Rossum27a60b11997-05-22 22:25:11 +00001009int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001010PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001011 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001012 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001013{
1014 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001015 /* Should be caused by a pre-existing error */
1016 if(!PyErr_Occurred())
1017 PyErr_SetString(PyExc_SystemError,
1018 "null file for PyFile_WriteString");
1019 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001020 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001021 else if (PyFile_Check(f)) {
1022 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001023 if (fp == NULL) {
1024 err_closed();
1025 return -1;
1026 }
1027 fputs(s, fp);
1028 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001029 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001030 else if (!PyErr_Occurred()) {
1031 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001032 int err;
1033 if (v == NULL)
1034 return -1;
1035 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1036 Py_DECREF(v);
1037 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001038 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001039 else
1040 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001041}