blob: d43f113ea8cf6fb8ab47c4f34c12545b3cacf277 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* File object implementation */
33
Guido van Rossumc0b618a1997-05-02 03:12:38 +000034#include "Python.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000035#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036
Guido van Rossum685a38e1996-12-05 21:54:17 +000037#ifdef HAVE_UNISTD_H
38#include <unistd.h>
39#endif
40
Guido van Rossumb8199141997-05-06 15:23:24 +000041#ifdef MS_WIN32
42#define ftruncate _chsize
43#define fileno _fileno
44#define HAVE_FTRUNCATE
45#endif
46
Guido van Rossumf2044e11998-04-28 16:05:59 +000047#ifdef macintosh
48#ifdef USE_GUSI
49#define HAVE_FTRUNCATE
50#endif
51#endif
52
Guido van Rossum295d1711995-02-19 15:55:19 +000053#ifdef THINK_C
54#define HAVE_FOPENRF
55#endif
Jack Jansene08dea191995-04-23 22:12:47 +000056#ifdef __MWERKS__
57/* Mwerks fopen() doesn't always set errno */
58#define NO_FOPEN_ERRNO
59#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000060
Guido van Rossumc0b618a1997-05-02 03:12:38 +000061#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000062
Guido van Rossumf1dc5661993-07-05 10:31:29 +000063#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000064
65typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000066 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000068 PyObject *f_name;
69 PyObject *f_mode;
70 int (*f_close) Py_PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000071 int f_softspace; /* Flag used by 'print' command */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000072} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073
74FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +000075PyFile_AsFile(f)
76 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000078 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000080 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000081 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082}
83
Guido van Rossumc0b618a1997-05-02 03:12:38 +000084PyObject *
85PyFile_Name(f)
86 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000087{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000089 return NULL;
90 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000092}
93
Guido van Rossumc0b618a1997-05-02 03:12:38 +000094PyObject *
95PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 FILE *fp;
97 char *name;
98 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000099 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000101 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102 if (f == NULL)
103 return NULL;
104 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000105 f->f_name = PyString_FromString(name);
106 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000107 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000108 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000110 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 return NULL;
112 }
113 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000114 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115}
116
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000117PyObject *
118PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119 char *name, *mode;
120{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000121 extern int fclose Py_PROTO((FILE *));
122 PyFileObject *f;
123 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124 if (f == NULL)
125 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000126#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000127 if (*mode == '*') {
128 FILE *fopenRF();
129 f->f_fp = fopenRF(name, mode+1);
130 }
131 else
132#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000133 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000134 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000135 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000136 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000137 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000138 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000139#ifdef NO_FOPEN_ERRNO
140 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000141 PyErr_SetString(PyExc_IOError, "Cannot open file");
142 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000143 return NULL;
144 }
145#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000146 PyErr_SetFromErrno(PyExc_IOError);
147 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148 return NULL;
149 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000150 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151}
152
Guido van Rossumb6775db1994-08-01 11:34:53 +0000153void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000154PyFile_SetBufSize(f, bufsize)
155 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000156 int bufsize;
157{
158 if (bufsize >= 0) {
159#ifdef HAVE_SETVBUF
160 int type;
161 switch (bufsize) {
162 case 0:
163 type = _IONBF;
164 break;
165 case 1:
166 type = _IOLBF;
167 bufsize = BUFSIZ;
168 break;
169 default:
170 type = _IOFBF;
171 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000172 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
173 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000174#else /* !HAVE_SETVBUF */
175 if (bufsize <= 1)
176 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
177#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178 }
179}
180
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000181static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000182err_closed()
183{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000184 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000185 return NULL;
186}
187
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188/* Methods */
189
190static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000191file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000192 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000194 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000195 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000196 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000197 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000198 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000199 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000200 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000201 }
202 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000203 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000204 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205 free((char *)f);
206}
207
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000208static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000209file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000210 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211{
212 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000213 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000215 PyString_AsString(f->f_name),
216 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000217 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000218 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219}
220
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000222file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000223 PyFileObject *f;
224 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000226 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000227 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000230 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000232 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000233 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000235 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236 f->f_fp = NULL;
237 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000238 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000239 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000240 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000241 return PyInt_FromLong((long)sts);
242 Py_INCREF(Py_None);
243 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000244}
245
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000246static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000247file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248 PyFileObject *f;
249 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000251 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000252 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000253 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000254
Guido van Rossumd7297e61992-07-06 14:19:26 +0000255 if (f->f_fp == NULL)
256 return err_closed();
257 whence = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000258 if (!PyArg_Parse(args, "l", &offset)) {
259 PyErr_Clear();
260 if (!PyArg_Parse(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000261 return NULL;
262 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000263 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000264 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000265 ret = fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000266 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000267 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000268 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000269 clearerr(f->f_fp);
270 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000271 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000272 Py_INCREF(Py_None);
273 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000274}
275
Guido van Rossumd7047b31995-01-02 19:07:15 +0000276#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000277static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000278file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000279 PyFileObject *f;
280 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000281{
282 long newsize;
283 int ret;
284
285 if (f->f_fp == NULL)
286 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000287 if (!PyArg_Parse(args, "l", &newsize)) {
288 PyErr_Clear();
289 if (!PyArg_NoArgs(args))
Guido van Rossumd7047b31995-01-02 19:07:15 +0000290 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000291 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000292 errno = 0;
293 newsize = ftell(f->f_fp); /* default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000294 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000295 if (newsize == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000296 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000297 clearerr(f->f_fp);
298 return NULL;
299 }
300 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000301 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000302 errno = 0;
303 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000304 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000305 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000307 errno = 0;
308 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000309 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000310 }
311 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000312 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000313 clearerr(f->f_fp);
314 return NULL;
315 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000316 Py_INCREF(Py_None);
317 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000318}
319#endif /* HAVE_FTRUNCATE */
320
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000321static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000322file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323 PyFileObject *f;
324 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000325{
326 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000327 if (f->f_fp == NULL)
328 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000329 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000331 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000332 errno = 0;
333 offset = ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000334 Py_END_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000335 if (offset == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000336 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000337 clearerr(f->f_fp);
338 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000339 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340 return PyInt_FromLong(offset);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000341}
342
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000343static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000344file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000345 PyFileObject *f;
346 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000347{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000348 if (f->f_fp == NULL)
349 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000350 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000351 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000353}
354
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000356file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000357 PyFileObject *f;
358 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000359{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000360 int res;
361
Guido van Rossumd7297e61992-07-06 14:19:26 +0000362 if (f->f_fp == NULL)
363 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000364 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000366 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000367 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000368 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000369 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000370 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000371 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000372 clearerr(f->f_fp);
373 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000374 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000375 Py_INCREF(Py_None);
376 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000377}
378
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000379static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000380file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381 PyFileObject *f;
382 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000383{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000384 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000385 if (f->f_fp == NULL)
386 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000387 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000388 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000390 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000391 Py_END_ALLOW_THREADS
392 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000393}
394
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000395/* We expect that fstat exists on most systems.
396 It's confirmed on Unix, Mac and Windows.
397 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
398#ifndef DONT_HAVE_FSTAT
399#define HAVE_FSTAT
400
401#include <sys/types.h>
402#include <sys/stat.h>
403
404#endif
405
406#if BUFSIZ < 8192
407#define SMALLCHUNK 8192
408#else
409#define SMALLCHUNK BUFSIZ
410#endif
411
412#define BIGCHUNK (512*1024)
413
414static size_t
415new_buffersize(f, currentsize)
416 PyFileObject *f;
417 size_t currentsize;
418{
419#ifdef HAVE_FSTAT
420 long pos, end;
421 struct stat st;
422 if (fstat(fileno(f->f_fp), &st) == 0) {
423 end = st.st_size;
Guido van Rossum91aaa921998-05-05 22:21:35 +0000424 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
425 if (pos >= 0)
426 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000427 if (pos < 0)
428 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000429 if (end > pos && pos >= 0)
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000430 return end - pos + 1;
431 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000432 }
433#endif
434 if (currentsize > SMALLCHUNK) {
435 /* Keep doubling until we reach BIGCHUNK;
436 then keep adding BIGCHUNK. */
437 if (currentsize <= BIGCHUNK)
438 return currentsize + currentsize;
439 else
440 return currentsize + BIGCHUNK;
441 }
442 return currentsize + SMALLCHUNK;
443}
444
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000445static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000446file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000447 PyFileObject *f;
448 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000449{
Guido van Rossum789a1611997-05-10 22:33:55 +0000450 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000451 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000453
Guido van Rossumd7297e61992-07-06 14:19:26 +0000454 if (f->f_fp == NULL)
455 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000456 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
457 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000458 if (bytesrequested < 0)
459 buffersize = new_buffersize(f, 0);
460 else
461 buffersize = bytesrequested;
462 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000463 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000464 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000465 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000466 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000467 Py_BEGIN_ALLOW_THREADS
468 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000469 chunksize = fread(BUF(v) + bytesread, 1,
470 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000471 Py_END_ALLOW_THREADS
472 if (chunksize == 0) {
473 if (!ferror(f->f_fp))
474 break;
475 PyErr_SetFromErrno(PyExc_IOError);
476 clearerr(f->f_fp);
477 Py_DECREF(v);
478 return NULL;
479 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000480 bytesread += chunksize;
481 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000482 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000483 if (bytesrequested < 0) {
Guido van Rossum240c35a1998-03-18 17:59:20 +0000484 buffersize = bytesread + new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000485 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000486 return NULL;
487 }
488 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000489 if (bytesread != buffersize)
490 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000491 return v;
492}
493
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000494static PyObject *
495file_readinto(f, args)
496 PyFileObject *f;
497 PyObject *args;
498{
499 char *ptr;
500 int ntodo, ndone, nnow;
501
502 if (f->f_fp == NULL)
503 return err_closed();
504 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
505 return NULL;
506 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000507 while (ntodo > 0) {
508 Py_BEGIN_ALLOW_THREADS
509 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000510 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000511 Py_END_ALLOW_THREADS
512 if (nnow == 0) {
513 if (!ferror(f->f_fp))
514 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000515 PyErr_SetFromErrno(PyExc_IOError);
516 clearerr(f->f_fp);
517 return NULL;
518 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000519 ndone += nnow;
520 ntodo -= nnow;
521 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000522 return PyInt_FromLong(ndone);
523}
524
525
Guido van Rossum0bd24411991-04-04 15:21:57 +0000526/* Internal routine to get a line.
527 Size argument interpretation:
528 > 0: max length;
529 = 0: read arbitrary line;
530 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000531*/
532
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000533static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000534getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000535 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000536 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000537{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000538 register FILE *fp;
539 register int c;
540 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000541 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000542 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000543
Guido van Rossumc10aa771992-07-31 12:42:38 +0000544 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000545 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000546 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000547 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000548 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000549 buf = BUF(v);
550 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000551
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000553 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000554 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000555 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000556 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000558 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000559 return NULL;
560 }
561 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000562 Py_DECREF(v);
563 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000564 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000565 return NULL;
566 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000567 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000568 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000569 }
570 if ((*buf++ = c) == '\n') {
571 if (n < 0)
572 buf--;
573 break;
574 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000575 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000576 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000577 break;
578 n1 = n2;
579 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000580 Py_BLOCK_THREADS
581 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000582 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000583 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000584 buf = BUF(v) + n1;
585 end = BUF(v) + n2;
586 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000587 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000588 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000589
Guido van Rossumce5ba841991-03-06 13:06:18 +0000590 n1 = buf - BUF(v);
591 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000593 return v;
594}
595
Guido van Rossum0bd24411991-04-04 15:21:57 +0000596/* External C interface */
597
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000598PyObject *
599PyFile_GetLine(f, n)
600 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000601 int n;
602{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000603 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000605 return NULL;
606 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 if (!PyFile_Check(f)) {
608 PyObject *reader;
609 PyObject *args;
610 PyObject *result;
611 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000612 if (reader == NULL)
613 return NULL;
614 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000615 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000616 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000617 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000618 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000619 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000620 return NULL;
621 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000622 result = PyEval_CallObject(reader, args);
623 Py_DECREF(reader);
624 Py_DECREF(args);
625 if (result != NULL && !PyString_Check(result)) {
626 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000627 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000628 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000629 "object.readline() returned non-string");
630 }
631 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 char *s = PyString_AsString(result);
633 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000634 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000635 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000636 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000637 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000638 "EOF when reading a line");
639 }
640 else if (s[len-1] == '\n') {
641 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000642 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000643 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000644 PyObject *v;
645 v = PyString_FromStringAndSize(s,
646 len-1);
647 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000648 result = v;
649 }
650 }
651 }
652 return result;
653 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000655 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000656 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000657}
658
659/* Python method */
660
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000661static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000662file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663 PyFileObject *f;
664 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000665{
Guido van Rossum789a1611997-05-10 22:33:55 +0000666 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000667
Guido van Rossumd7297e61992-07-06 14:19:26 +0000668 if (f->f_fp == NULL)
669 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000670 if (!PyArg_ParseTuple(args, "|i", &n))
671 return NULL;
672 if (n == 0)
673 return PyString_FromString("");
674 if (n < 0)
675 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000676 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000677}
678
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000679static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000680file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000681 PyFileObject *f;
682 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000683{
Guido van Rossum789a1611997-05-10 22:33:55 +0000684 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000685 PyObject *list;
686 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000687 char small_buffer[SMALLCHUNK];
688 char *buffer = small_buffer;
689 size_t buffersize = SMALLCHUNK;
690 PyObject *big_buffer = NULL;
691 size_t nfilled = 0;
692 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000693 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000694 char *p, *q, *end;
695 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000696
Guido van Rossumd7297e61992-07-06 14:19:26 +0000697 if (f->f_fp == NULL)
698 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000699 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000700 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000701 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000702 return NULL;
703 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000704 Py_BEGIN_ALLOW_THREADS
705 errno = 0;
706 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
707 Py_END_ALLOW_THREADS
708 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000709 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000710 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000711 break;
712 PyErr_SetFromErrno(PyExc_IOError);
713 clearerr(f->f_fp);
714 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000715 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000716 list = NULL;
717 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000718 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000719 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000720 p = memchr(buffer+nfilled, '\n', nread);
721 if (p == NULL) {
722 /* Need a larger buffer to fit this line */
723 nfilled += nread;
724 buffersize *= 2;
725 if (big_buffer == NULL) {
726 /* Create the big buffer */
727 big_buffer = PyString_FromStringAndSize(
728 NULL, buffersize);
729 if (big_buffer == NULL)
730 goto error;
731 buffer = PyString_AS_STRING(big_buffer);
732 memcpy(buffer, small_buffer, nfilled);
733 }
734 else {
735 /* Grow the big buffer */
736 _PyString_Resize(&big_buffer, buffersize);
737 buffer = PyString_AS_STRING(big_buffer);
738 }
739 continue;
740 }
741 end = buffer+nfilled+nread;
742 q = buffer;
743 do {
744 /* Process complete lines */
745 p++;
746 line = PyString_FromStringAndSize(q, p-q);
747 if (line == NULL)
748 goto error;
749 err = PyList_Append(list, line);
750 Py_DECREF(line);
751 if (err != 0)
752 goto error;
753 q = p;
754 p = memchr(q, '\n', end-q);
755 } while (p != NULL);
756 /* Move the remaining incomplete line to the start */
757 nfilled = end-q;
758 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000759 if (sizehint > 0)
760 if (totalread >= (size_t)sizehint)
761 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000762 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000763 if (nfilled != 0) {
764 /* Partial last line */
765 line = PyString_FromStringAndSize(buffer, nfilled);
766 if (line == NULL)
767 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000768 if (sizehint > 0) {
769 /* Need to complete the last line */
770 PyObject *rest = getline(f, 0);
771 if (rest == NULL) {
772 Py_DECREF(line);
773 goto error;
774 }
775 PyString_Concat(&line, rest);
776 Py_DECREF(rest);
777 if (line == NULL)
778 goto error;
779 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000780 err = PyList_Append(list, line);
781 Py_DECREF(line);
782 if (err != 0)
783 goto error;
784 }
785 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000786 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000787 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000788 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000789 return list;
790}
791
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000792static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000793file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000794 PyFileObject *f;
795 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000796{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000797 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000798 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000799 if (f->f_fp == NULL)
800 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000801 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000802 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000803 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000804 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000806 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000807 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000808 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000809 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000810 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000811 return NULL;
812 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000813 Py_INCREF(Py_None);
814 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000815}
816
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000817static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000818file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000819 PyFileObject *f;
820 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000821{
822 int i, n;
823 if (f->f_fp == NULL)
824 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000825 if (args == NULL || !PyList_Check(args)) {
826 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000827 "writelines() requires list of strings");
828 return NULL;
829 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000830 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000831 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000832 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000833 errno = 0;
834 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000835 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000836 int len;
837 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000838 if (!PyString_Check(line)) {
839 Py_BLOCK_THREADS
840 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000841 "writelines() requires list of strings");
842 return NULL;
843 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000844 len = PyString_Size(line);
845 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000846 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000847 Py_BLOCK_THREADS
848 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000849 clearerr(f->f_fp);
850 return NULL;
851 }
852 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000853 Py_END_ALLOW_THREADS
854 Py_INCREF(Py_None);
855 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000856}
857
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000858static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000859 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000860 {"read", (PyCFunction)file_read, 1},
861 {"write", (PyCFunction)file_write, 0},
862 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000863 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000864#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000865 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000866#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000867 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000868 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000869 {"readlines", (PyCFunction)file_readlines, 1},
870 {"writelines", (PyCFunction)file_writelines, 0},
871 {"flush", (PyCFunction)file_flush, 0},
872 {"close", (PyCFunction)file_close, 0},
873 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000874 {NULL, NULL} /* sentinel */
875};
876
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000877#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000878
879static struct memberlist file_memberlist[] = {
880 {"softspace", T_INT, OFF(f_softspace)},
881 {"mode", T_OBJECT, OFF(f_mode), RO},
882 {"name", T_OBJECT, OFF(f_name), RO},
883 /* getattr(f, "closed") is implemented without this table */
884 {"closed", T_INT, 0, RO},
885 {NULL} /* Sentinel */
886};
887
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000889file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000891 char *name;
892{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000893 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000894
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000895 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000896 if (res != NULL)
897 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000898 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000899 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000900 return PyInt_FromLong((long)(f->f_fp == 0));
901 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000902}
903
904static int
905file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000906 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000907 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000909{
910 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000911 PyErr_SetString(PyExc_AttributeError,
912 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000913 return -1;
914 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000915 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000916}
917
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000918PyTypeObject PyFile_Type = {
919 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920 0,
921 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000922 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000923 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000924 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000925 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000926 (getattrfunc)file_getattr, /*tp_getattr*/
927 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000928 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000929 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000931
932/* Interface for the 'soft space' between print items. */
933
934int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000935PyFile_SoftSpace(f, newflag)
936 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000937 int newflag;
938{
939 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000940 if (f == NULL) {
941 /* Do nothing */
942 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000943 else if (PyFile_Check(f)) {
944 oldflag = ((PyFileObject *)f)->f_softspace;
945 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000946 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000947 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000948 PyObject *v;
949 v = PyObject_GetAttrString(f, "softspace");
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 (PyInt_Check(v))
954 oldflag = PyInt_AsLong(v);
955 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000956 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000957 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000958 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000959 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000960 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000961 if (PyObject_SetAttrString(f, "softspace", v) != 0)
962 PyErr_Clear();
963 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000964 }
965 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000966 return oldflag;
967}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000968
969/* Interfaces to write objects/strings to file-like objects */
970
971int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000972PyFile_WriteObject(v, f, flags)
973 PyObject *v;
974 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000975 int flags;
976{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000977 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000978 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000979 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000980 return -1;
981 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000982 else if (PyFile_Check(f)) {
983 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000984 if (fp == NULL) {
985 err_closed();
986 return -1;
987 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000988 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000989 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000990 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000991 if (writer == NULL)
992 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000993 if (flags & Py_PRINT_RAW)
994 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000995 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000996 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000997 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000998 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +0000999 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001000 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001001 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001002 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003 Py_DECREF(value);
1004 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001005 return -1;
1006 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001007 result = PyEval_CallObject(writer, args);
1008 Py_DECREF(args);
1009 Py_DECREF(value);
1010 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001011 if (result == NULL)
1012 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001014 return 0;
1015}
1016
Guido van Rossum27a60b11997-05-22 22:25:11 +00001017int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001018PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001019 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001020 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001021{
1022 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001023 /* Should be caused by a pre-existing error */
1024 if(!PyErr_Occurred())
1025 PyErr_SetString(PyExc_SystemError,
1026 "null file for PyFile_WriteString");
1027 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001028 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001029 else if (PyFile_Check(f)) {
1030 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001031 if (fp == NULL) {
1032 err_closed();
1033 return -1;
1034 }
1035 fputs(s, fp);
1036 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001037 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001038 else if (!PyErr_Occurred()) {
1039 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001040 int err;
1041 if (v == NULL)
1042 return -1;
1043 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1044 Py_DECREF(v);
1045 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001046 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001047 else
1048 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001049}