blob: 49517c5c264d399916faac7c48814484378cf5ec [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 Rossum5449b6e1997-05-09 22:27:31 +0000419 if (end > pos && pos >= 0)
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000420 return end - pos + 1;
421 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000422 }
423#endif
424 if (currentsize > SMALLCHUNK) {
425 /* Keep doubling until we reach BIGCHUNK;
426 then keep adding BIGCHUNK. */
427 if (currentsize <= BIGCHUNK)
428 return currentsize + currentsize;
429 else
430 return currentsize + BIGCHUNK;
431 }
432 return currentsize + SMALLCHUNK;
433}
434
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000435static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000436file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437 PyFileObject *f;
438 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000439{
Guido van Rossum789a1611997-05-10 22:33:55 +0000440 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000441 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000443
Guido van Rossumd7297e61992-07-06 14:19:26 +0000444 if (f->f_fp == NULL)
445 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000446 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
447 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000448 if (bytesrequested < 0)
449 buffersize = new_buffersize(f, 0);
450 else
451 buffersize = bytesrequested;
452 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000453 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000454 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000455 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000456 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000457 Py_BEGIN_ALLOW_THREADS
458 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000459 chunksize = fread(BUF(v) + bytesread, 1,
460 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000461 Py_END_ALLOW_THREADS
462 if (chunksize == 0) {
463 if (!ferror(f->f_fp))
464 break;
465 PyErr_SetFromErrno(PyExc_IOError);
466 clearerr(f->f_fp);
467 Py_DECREF(v);
468 return NULL;
469 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000470 bytesread += chunksize;
471 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000472 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000473 if (bytesrequested < 0) {
Guido van Rossum240c35a1998-03-18 17:59:20 +0000474 buffersize = bytesread + new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000475 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000476 return NULL;
477 }
478 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000479 if (bytesread != buffersize)
480 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481 return v;
482}
483
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000484static PyObject *
485file_readinto(f, args)
486 PyFileObject *f;
487 PyObject *args;
488{
489 char *ptr;
490 int ntodo, ndone, nnow;
491
492 if (f->f_fp == NULL)
493 return err_closed();
494 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
495 return NULL;
496 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000497 while (ntodo > 0) {
498 Py_BEGIN_ALLOW_THREADS
499 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000500 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000501 Py_END_ALLOW_THREADS
502 if (nnow == 0) {
503 if (!ferror(f->f_fp))
504 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000505 PyErr_SetFromErrno(PyExc_IOError);
506 clearerr(f->f_fp);
507 return NULL;
508 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000509 ndone += nnow;
510 ntodo -= nnow;
511 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000512 return PyInt_FromLong(ndone);
513}
514
515
Guido van Rossum0bd24411991-04-04 15:21:57 +0000516/* Internal routine to get a line.
517 Size argument interpretation:
518 > 0: max length;
519 = 0: read arbitrary line;
520 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000521*/
522
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000524getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000525 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000526 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000527{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000528 register FILE *fp;
529 register int c;
530 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000531 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000532 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000533
Guido van Rossumc10aa771992-07-31 12:42:38 +0000534 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000535 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000536 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000537 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000538 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000539 buf = BUF(v);
540 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000541
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000542 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000543 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000544 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000545 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000546 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000547 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000548 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000549 return NULL;
550 }
551 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552 Py_DECREF(v);
553 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000554 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000555 return NULL;
556 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000557 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000558 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000559 }
560 if ((*buf++ = c) == '\n') {
561 if (n < 0)
562 buf--;
563 break;
564 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000565 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000566 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000567 break;
568 n1 = n2;
569 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000570 Py_BLOCK_THREADS
571 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000572 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000573 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000574 buf = BUF(v) + n1;
575 end = BUF(v) + n2;
576 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000577 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000578 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000579
Guido van Rossumce5ba841991-03-06 13:06:18 +0000580 n1 = buf - BUF(v);
581 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000582 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000583 return v;
584}
585
Guido van Rossum0bd24411991-04-04 15:21:57 +0000586/* External C interface */
587
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000588PyObject *
589PyFile_GetLine(f, n)
590 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000591 int n;
592{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000593 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000594 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000595 return NULL;
596 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000597 if (!PyFile_Check(f)) {
598 PyObject *reader;
599 PyObject *args;
600 PyObject *result;
601 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000602 if (reader == NULL)
603 return NULL;
604 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000605 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000606 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000608 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000609 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000610 return NULL;
611 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000612 result = PyEval_CallObject(reader, args);
613 Py_DECREF(reader);
614 Py_DECREF(args);
615 if (result != NULL && !PyString_Check(result)) {
616 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000617 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000618 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000619 "object.readline() returned non-string");
620 }
621 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000622 char *s = PyString_AsString(result);
623 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000624 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000626 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000628 "EOF when reading a line");
629 }
630 else if (s[len-1] == '\n') {
631 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000633 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000634 PyObject *v;
635 v = PyString_FromStringAndSize(s,
636 len-1);
637 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000638 result = v;
639 }
640 }
641 }
642 return result;
643 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000644 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000645 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000646 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000647}
648
649/* Python method */
650
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000651static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000652file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000653 PyFileObject *f;
654 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000655{
Guido van Rossum789a1611997-05-10 22:33:55 +0000656 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000657
Guido van Rossumd7297e61992-07-06 14:19:26 +0000658 if (f->f_fp == NULL)
659 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000660 if (!PyArg_ParseTuple(args, "|i", &n))
661 return NULL;
662 if (n == 0)
663 return PyString_FromString("");
664 if (n < 0)
665 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000666 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000667}
668
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000670file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671 PyFileObject *f;
672 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000673{
Guido van Rossum789a1611997-05-10 22:33:55 +0000674 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000675 PyObject *list;
676 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000677 char small_buffer[SMALLCHUNK];
678 char *buffer = small_buffer;
679 size_t buffersize = SMALLCHUNK;
680 PyObject *big_buffer = NULL;
681 size_t nfilled = 0;
682 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000683 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000684 char *p, *q, *end;
685 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000686
Guido van Rossumd7297e61992-07-06 14:19:26 +0000687 if (f->f_fp == NULL)
688 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000689 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000690 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000691 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000692 return NULL;
693 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000694 Py_BEGIN_ALLOW_THREADS
695 errno = 0;
696 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
697 Py_END_ALLOW_THREADS
698 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000699 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000700 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000701 break;
702 PyErr_SetFromErrno(PyExc_IOError);
703 clearerr(f->f_fp);
704 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000705 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000706 list = NULL;
707 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000708 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000709 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000710 p = memchr(buffer+nfilled, '\n', nread);
711 if (p == NULL) {
712 /* Need a larger buffer to fit this line */
713 nfilled += nread;
714 buffersize *= 2;
715 if (big_buffer == NULL) {
716 /* Create the big buffer */
717 big_buffer = PyString_FromStringAndSize(
718 NULL, buffersize);
719 if (big_buffer == NULL)
720 goto error;
721 buffer = PyString_AS_STRING(big_buffer);
722 memcpy(buffer, small_buffer, nfilled);
723 }
724 else {
725 /* Grow the big buffer */
726 _PyString_Resize(&big_buffer, buffersize);
727 buffer = PyString_AS_STRING(big_buffer);
728 }
729 continue;
730 }
731 end = buffer+nfilled+nread;
732 q = buffer;
733 do {
734 /* Process complete lines */
735 p++;
736 line = PyString_FromStringAndSize(q, p-q);
737 if (line == NULL)
738 goto error;
739 err = PyList_Append(list, line);
740 Py_DECREF(line);
741 if (err != 0)
742 goto error;
743 q = p;
744 p = memchr(q, '\n', end-q);
745 } while (p != NULL);
746 /* Move the remaining incomplete line to the start */
747 nfilled = end-q;
748 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000749 if (sizehint > 0)
750 if (totalread >= (size_t)sizehint)
751 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000752 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000753 if (nfilled != 0) {
754 /* Partial last line */
755 line = PyString_FromStringAndSize(buffer, nfilled);
756 if (line == NULL)
757 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000758 if (sizehint > 0) {
759 /* Need to complete the last line */
760 PyObject *rest = getline(f, 0);
761 if (rest == NULL) {
762 Py_DECREF(line);
763 goto error;
764 }
765 PyString_Concat(&line, rest);
766 Py_DECREF(rest);
767 if (line == NULL)
768 goto error;
769 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000770 err = PyList_Append(list, line);
771 Py_DECREF(line);
772 if (err != 0)
773 goto error;
774 }
775 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000776 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000777 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000778 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000779 return list;
780}
781
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000782static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000783file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000784 PyFileObject *f;
785 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000787 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000788 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000789 if (f->f_fp == NULL)
790 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000791 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000792 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000793 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000794 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000796 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000797 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000798 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000799 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000800 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000801 return NULL;
802 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000803 Py_INCREF(Py_None);
804 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805}
806
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000807static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000808file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000809 PyFileObject *f;
810 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000811{
812 int i, n;
813 if (f->f_fp == NULL)
814 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000815 if (args == NULL || !PyList_Check(args)) {
816 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000817 "writelines() requires list of strings");
818 return NULL;
819 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000820 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000821 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000822 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000823 errno = 0;
824 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000825 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000826 int len;
827 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000828 if (!PyString_Check(line)) {
829 Py_BLOCK_THREADS
830 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000831 "writelines() requires list of strings");
832 return NULL;
833 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000834 len = PyString_Size(line);
835 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000836 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000837 Py_BLOCK_THREADS
838 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000839 clearerr(f->f_fp);
840 return NULL;
841 }
842 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000843 Py_END_ALLOW_THREADS
844 Py_INCREF(Py_None);
845 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000846}
847
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000848static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000849 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000850 {"read", (PyCFunction)file_read, 1},
851 {"write", (PyCFunction)file_write, 0},
852 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000853 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000854#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000855 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000856#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000857 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000858 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000859 {"readlines", (PyCFunction)file_readlines, 1},
860 {"writelines", (PyCFunction)file_writelines, 0},
861 {"flush", (PyCFunction)file_flush, 0},
862 {"close", (PyCFunction)file_close, 0},
863 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000864 {NULL, NULL} /* sentinel */
865};
866
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000867#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000868
869static struct memberlist file_memberlist[] = {
870 {"softspace", T_INT, OFF(f_softspace)},
871 {"mode", T_OBJECT, OFF(f_mode), RO},
872 {"name", T_OBJECT, OFF(f_name), RO},
873 /* getattr(f, "closed") is implemented without this table */
874 {"closed", T_INT, 0, RO},
875 {NULL} /* Sentinel */
876};
877
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000878static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000879file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000880 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000881 char *name;
882{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000883 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000884
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000885 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886 if (res != NULL)
887 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000889 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890 return PyInt_FromLong((long)(f->f_fp == 0));
891 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000892}
893
894static int
895file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000896 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000897 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000898 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000899{
900 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000901 PyErr_SetString(PyExc_AttributeError,
902 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000903 return -1;
904 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000905 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000906}
907
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908PyTypeObject PyFile_Type = {
909 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000910 0,
911 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000912 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000913 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000914 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000915 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000916 (getattrfunc)file_getattr, /*tp_getattr*/
917 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000918 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000919 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000921
922/* Interface for the 'soft space' between print items. */
923
924int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000925PyFile_SoftSpace(f, newflag)
926 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000927 int newflag;
928{
929 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000930 if (f == NULL) {
931 /* Do nothing */
932 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000933 else if (PyFile_Check(f)) {
934 oldflag = ((PyFileObject *)f)->f_softspace;
935 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000936 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000937 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000938 PyObject *v;
939 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000940 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000941 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000942 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000943 if (PyInt_Check(v))
944 oldflag = PyInt_AsLong(v);
945 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000946 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000947 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000948 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000949 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000950 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000951 if (PyObject_SetAttrString(f, "softspace", v) != 0)
952 PyErr_Clear();
953 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000954 }
955 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000956 return oldflag;
957}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000958
959/* Interfaces to write objects/strings to file-like objects */
960
961int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000962PyFile_WriteObject(v, f, flags)
963 PyObject *v;
964 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000965 int flags;
966{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000967 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000968 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000969 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000970 return -1;
971 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000972 else if (PyFile_Check(f)) {
973 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000974 if (fp == NULL) {
975 err_closed();
976 return -1;
977 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000978 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000979 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000981 if (writer == NULL)
982 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000983 if (flags & Py_PRINT_RAW)
984 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000985 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000986 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000987 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000988 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +0000989 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000990 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000991 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +0000992 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000993 Py_DECREF(value);
994 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000995 return -1;
996 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000997 result = PyEval_CallObject(writer, args);
998 Py_DECREF(args);
999 Py_DECREF(value);
1000 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001001 if (result == NULL)
1002 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001004 return 0;
1005}
1006
Guido van Rossum27a60b11997-05-22 22:25:11 +00001007int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001008PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001009 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001010 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001011{
1012 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001013 /* Should be caused by a pre-existing error */
1014 if(!PyErr_Occurred())
1015 PyErr_SetString(PyExc_SystemError,
1016 "null file for PyFile_WriteString");
1017 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001018 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001019 else if (PyFile_Check(f)) {
1020 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001021 if (fp == NULL) {
1022 err_closed();
1023 return -1;
1024 }
1025 fputs(s, fp);
1026 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001027 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001028 else if (!PyErr_Occurred()) {
1029 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001030 int err;
1031 if (v == NULL)
1032 return -1;
1033 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1034 Py_DECREF(v);
1035 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001036 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001037 else
1038 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001039}