blob: c57232c6204309c0520e4b829047626bf19739b0 [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
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000140 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000141 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000142 PyErr_SetString(PyExc_IOError, "Cannot open file");
143 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000144 return NULL;
145 }
146#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000147 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000148 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149 return NULL;
150 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000151 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152}
153
Guido van Rossumb6775db1994-08-01 11:34:53 +0000154void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000155PyFile_SetBufSize(f, bufsize)
156 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000157 int bufsize;
158{
159 if (bufsize >= 0) {
160#ifdef HAVE_SETVBUF
161 int type;
162 switch (bufsize) {
163 case 0:
164 type = _IONBF;
165 break;
166 case 1:
167 type = _IOLBF;
168 bufsize = BUFSIZ;
169 break;
170 default:
171 type = _IOFBF;
172 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000173 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
174 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000175#else /* !HAVE_SETVBUF */
176 if (bufsize <= 1)
177 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
178#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179 }
180}
181
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000182static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000183err_closed()
184{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000185 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000186 return NULL;
187}
188
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189/* Methods */
190
191static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000192file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000193 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000195 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000196 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000197 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000198 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000199 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000200 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000201 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000202 }
203 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000205 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 free((char *)f);
207}
208
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000210file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000211 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212{
213 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000214 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000216 PyString_AsString(f->f_name),
217 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000218 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000219 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220}
221
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000222static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000223file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224 PyFileObject *f;
225 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000227 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000231 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000232 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000233 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000234 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000236 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237 f->f_fp = NULL;
238 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000239 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000241 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242 return PyInt_FromLong((long)sts);
243 Py_INCREF(Py_None);
244 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245}
246
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000247static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000248file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000249 PyFileObject *f;
250 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000252 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000253 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000254 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000255
Guido van Rossumd7297e61992-07-06 14:19:26 +0000256 if (f->f_fp == NULL)
257 return err_closed();
258 whence = 0;
Guido van Rossum88303191999-01-04 17:22:18 +0000259 if (!PyArg_ParseTuple(args, "l|i", &offset, &whence))
260 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000261 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000262 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000263 ret = fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000264 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000265 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000266 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000267 clearerr(f->f_fp);
268 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000269 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000270 Py_INCREF(Py_None);
271 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000272}
273
Guido van Rossumd7047b31995-01-02 19:07:15 +0000274#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000275static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000276file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000277 PyFileObject *f;
278 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000279{
280 long newsize;
281 int ret;
282
283 if (f->f_fp == NULL)
284 return err_closed();
Guido van Rossum88303191999-01-04 17:22:18 +0000285 newsize = -1;
286 if (!PyArg_ParseTuple(args, "|l", &newsize)) {
287 return NULL;
288 }
289 if (newsize < 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000290 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000291 errno = 0;
292 newsize = ftell(f->f_fp); /* default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000293 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000294 if (newsize == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000295 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000296 clearerr(f->f_fp);
297 return NULL;
298 }
299 }
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 = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000303 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000304 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000305 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000306 errno = 0;
307 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000308 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000309 }
310 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000311 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000312 clearerr(f->f_fp);
313 return NULL;
314 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000315 Py_INCREF(Py_None);
316 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000317}
318#endif /* HAVE_FTRUNCATE */
319
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000320static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000321file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000322 PyFileObject *f;
323 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000324{
325 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000326 if (f->f_fp == NULL)
327 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000330 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000331 errno = 0;
332 offset = ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000333 Py_END_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000334 if (offset == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000336 clearerr(f->f_fp);
337 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000338 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000339 return PyInt_FromLong(offset);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000340}
341
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000342static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000343file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344 PyFileObject *f;
345 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000346{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000347 if (f->f_fp == NULL)
348 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000350 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000352}
353
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000355file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356 PyFileObject *f;
357 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000358{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000359 int res;
360
Guido van Rossumd7297e61992-07-06 14:19:26 +0000361 if (f->f_fp == NULL)
362 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000363 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000364 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000365 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000366 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000367 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000368 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000369 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000370 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000371 clearerr(f->f_fp);
372 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000373 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000374 Py_INCREF(Py_None);
375 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000376}
377
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000378static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000379file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 PyFileObject *f;
381 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000382{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000383 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000384 if (f->f_fp == NULL)
385 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000386 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000387 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000388 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000389 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 Py_END_ALLOW_THREADS
391 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000392}
393
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000394/* We expect that fstat exists on most systems.
395 It's confirmed on Unix, Mac and Windows.
396 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
397#ifndef DONT_HAVE_FSTAT
398#define HAVE_FSTAT
399
400#include <sys/types.h>
401#include <sys/stat.h>
402
403#endif
404
405#if BUFSIZ < 8192
406#define SMALLCHUNK 8192
407#else
408#define SMALLCHUNK BUFSIZ
409#endif
410
411#define BIGCHUNK (512*1024)
412
413static size_t
414new_buffersize(f, currentsize)
415 PyFileObject *f;
416 size_t currentsize;
417{
418#ifdef HAVE_FSTAT
419 long pos, end;
420 struct stat st;
421 if (fstat(fileno(f->f_fp), &st) == 0) {
422 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000423 /* The following is not a bug: we really need to call lseek()
424 *and* ftell(). The reason is that some stdio libraries
425 mistakenly flush their buffer when ftell() is called and
426 the lseek() call it makes fails, thereby throwing away
427 data that cannot be recovered in any way. To avoid this,
428 we first test lseek(), and only call ftell() if lseek()
429 works. We can't use the lseek() value either, because we
430 need to take the amount of buffered data into account.
431 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000432 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
433 if (pos >= 0)
434 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000435 if (pos < 0)
436 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000437 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000438 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000439 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000440 }
441#endif
442 if (currentsize > SMALLCHUNK) {
443 /* Keep doubling until we reach BIGCHUNK;
444 then keep adding BIGCHUNK. */
445 if (currentsize <= BIGCHUNK)
446 return currentsize + currentsize;
447 else
448 return currentsize + BIGCHUNK;
449 }
450 return currentsize + SMALLCHUNK;
451}
452
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000453static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000454file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000455 PyFileObject *f;
456 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000457{
Guido van Rossum789a1611997-05-10 22:33:55 +0000458 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000459 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000460 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000461
Guido van Rossumd7297e61992-07-06 14:19:26 +0000462 if (f->f_fp == NULL)
463 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000464 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
465 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000466 if (bytesrequested < 0)
467 buffersize = new_buffersize(f, 0);
468 else
469 buffersize = bytesrequested;
470 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000471 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000472 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000473 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000474 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000475 Py_BEGIN_ALLOW_THREADS
476 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000477 chunksize = fread(BUF(v) + bytesread, 1,
478 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000479 Py_END_ALLOW_THREADS
480 if (chunksize == 0) {
481 if (!ferror(f->f_fp))
482 break;
483 PyErr_SetFromErrno(PyExc_IOError);
484 clearerr(f->f_fp);
485 Py_DECREF(v);
486 return NULL;
487 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000488 bytesread += chunksize;
489 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000490 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000491 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000492 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000493 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000494 return NULL;
495 }
496 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000497 if (bytesread != buffersize)
498 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000499 return v;
500}
501
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000502static PyObject *
503file_readinto(f, args)
504 PyFileObject *f;
505 PyObject *args;
506{
507 char *ptr;
508 int ntodo, ndone, nnow;
509
510 if (f->f_fp == NULL)
511 return err_closed();
512 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
513 return NULL;
514 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000515 while (ntodo > 0) {
516 Py_BEGIN_ALLOW_THREADS
517 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000518 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000519 Py_END_ALLOW_THREADS
520 if (nnow == 0) {
521 if (!ferror(f->f_fp))
522 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000523 PyErr_SetFromErrno(PyExc_IOError);
524 clearerr(f->f_fp);
525 return NULL;
526 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000527 ndone += nnow;
528 ntodo -= nnow;
529 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000530 return PyInt_FromLong(ndone);
531}
532
533
Guido van Rossum0bd24411991-04-04 15:21:57 +0000534/* Internal routine to get a line.
535 Size argument interpretation:
536 > 0: max length;
537 = 0: read arbitrary line;
538 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000539*/
540
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000541static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000542getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000543 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000544 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000546 register FILE *fp;
547 register int c;
548 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000549 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000550 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000551
Guido van Rossumc10aa771992-07-31 12:42:38 +0000552 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000553 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000555 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000556 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000557 buf = BUF(v);
558 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000559
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000560 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000561 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000562 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000563 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000564 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000565 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000566 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000567 return NULL;
568 }
569 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000570 Py_DECREF(v);
571 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000572 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000573 return NULL;
574 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000575 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000576 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000577 }
578 if ((*buf++ = c) == '\n') {
579 if (n < 0)
580 buf--;
581 break;
582 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000583 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000584 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000585 break;
586 n1 = n2;
587 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000588 Py_BLOCK_THREADS
589 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000590 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000591 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000592 buf = BUF(v) + n1;
593 end = BUF(v) + n2;
594 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000595 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000596 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000597
Guido van Rossumce5ba841991-03-06 13:06:18 +0000598 n1 = buf - BUF(v);
599 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000601 return v;
602}
603
Guido van Rossum0bd24411991-04-04 15:21:57 +0000604/* External C interface */
605
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000606PyObject *
607PyFile_GetLine(f, n)
608 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000609 int n;
610{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000611 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000612 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000613 return NULL;
614 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000615 if (!PyFile_Check(f)) {
616 PyObject *reader;
617 PyObject *args;
618 PyObject *result;
619 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000620 if (reader == NULL)
621 return NULL;
622 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000623 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000624 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000626 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000628 return NULL;
629 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000630 result = PyEval_CallObject(reader, args);
631 Py_DECREF(reader);
632 Py_DECREF(args);
633 if (result != NULL && !PyString_Check(result)) {
634 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000635 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000636 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000637 "object.readline() returned non-string");
638 }
639 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000640 char *s = PyString_AsString(result);
641 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000642 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000643 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000644 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000645 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000646 "EOF when reading a line");
647 }
648 else if (s[len-1] == '\n') {
649 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000650 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000651 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000652 PyObject *v;
653 v = PyString_FromStringAndSize(s,
654 len-1);
655 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000656 result = v;
657 }
658 }
659 }
660 return result;
661 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000662 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000663 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000664 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000665}
666
667/* Python method */
668
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000670file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671 PyFileObject *f;
672 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000673{
Guido van Rossum789a1611997-05-10 22:33:55 +0000674 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000675
Guido van Rossumd7297e61992-07-06 14:19:26 +0000676 if (f->f_fp == NULL)
677 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000678 if (!PyArg_ParseTuple(args, "|i", &n))
679 return NULL;
680 if (n == 0)
681 return PyString_FromString("");
682 if (n < 0)
683 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000684 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000685}
686
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000687static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000688file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000689 PyFileObject *f;
690 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000691{
Guido van Rossum789a1611997-05-10 22:33:55 +0000692 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000693 PyObject *list;
694 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000695 char small_buffer[SMALLCHUNK];
696 char *buffer = small_buffer;
697 size_t buffersize = SMALLCHUNK;
698 PyObject *big_buffer = NULL;
699 size_t nfilled = 0;
700 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000701 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000702 char *p, *q, *end;
703 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000704
Guido van Rossumd7297e61992-07-06 14:19:26 +0000705 if (f->f_fp == NULL)
706 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000707 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000708 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000709 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000710 return NULL;
711 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000712 Py_BEGIN_ALLOW_THREADS
713 errno = 0;
714 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
715 Py_END_ALLOW_THREADS
716 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000717 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000718 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000719 break;
720 PyErr_SetFromErrno(PyExc_IOError);
721 clearerr(f->f_fp);
722 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000723 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000724 list = NULL;
725 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000726 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000727 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000728 p = memchr(buffer+nfilled, '\n', nread);
729 if (p == NULL) {
730 /* Need a larger buffer to fit this line */
731 nfilled += nread;
732 buffersize *= 2;
733 if (big_buffer == NULL) {
734 /* Create the big buffer */
735 big_buffer = PyString_FromStringAndSize(
736 NULL, buffersize);
737 if (big_buffer == NULL)
738 goto error;
739 buffer = PyString_AS_STRING(big_buffer);
740 memcpy(buffer, small_buffer, nfilled);
741 }
742 else {
743 /* Grow the big buffer */
744 _PyString_Resize(&big_buffer, buffersize);
745 buffer = PyString_AS_STRING(big_buffer);
746 }
747 continue;
748 }
749 end = buffer+nfilled+nread;
750 q = buffer;
751 do {
752 /* Process complete lines */
753 p++;
754 line = PyString_FromStringAndSize(q, p-q);
755 if (line == NULL)
756 goto error;
757 err = PyList_Append(list, line);
758 Py_DECREF(line);
759 if (err != 0)
760 goto error;
761 q = p;
762 p = memchr(q, '\n', end-q);
763 } while (p != NULL);
764 /* Move the remaining incomplete line to the start */
765 nfilled = end-q;
766 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000767 if (sizehint > 0)
768 if (totalread >= (size_t)sizehint)
769 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000770 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000771 if (nfilled != 0) {
772 /* Partial last line */
773 line = PyString_FromStringAndSize(buffer, nfilled);
774 if (line == NULL)
775 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000776 if (sizehint > 0) {
777 /* Need to complete the last line */
778 PyObject *rest = getline(f, 0);
779 if (rest == NULL) {
780 Py_DECREF(line);
781 goto error;
782 }
783 PyString_Concat(&line, rest);
784 Py_DECREF(rest);
785 if (line == NULL)
786 goto error;
787 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000788 err = PyList_Append(list, line);
789 Py_DECREF(line);
790 if (err != 0)
791 goto error;
792 }
793 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000794 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000795 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000796 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000797 return list;
798}
799
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000800static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000801file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000802 PyFileObject *f;
803 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000804{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000805 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000806 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000807 if (f->f_fp == NULL)
808 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000809 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000810 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000811 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000812 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000814 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000815 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000816 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000817 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000818 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000819 return NULL;
820 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000821 Py_INCREF(Py_None);
822 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000823}
824
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000825static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000826file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000827 PyFileObject *f;
828 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000829{
830 int i, n;
831 if (f->f_fp == NULL)
832 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000833 if (args == NULL || !PyList_Check(args)) {
834 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000835 "writelines() requires list of strings");
836 return NULL;
837 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000838 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000839 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000840 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000841 errno = 0;
842 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000843 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000844 int len;
845 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000846 if (!PyString_Check(line)) {
847 Py_BLOCK_THREADS
848 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000849 "writelines() requires list of strings");
850 return NULL;
851 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000852 len = PyString_Size(line);
853 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000854 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000855 Py_BLOCK_THREADS
856 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000857 clearerr(f->f_fp);
858 return NULL;
859 }
860 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000861 Py_END_ALLOW_THREADS
862 Py_INCREF(Py_None);
863 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000864}
865
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000866static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000867 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000868 {"read", (PyCFunction)file_read, 1},
869 {"write", (PyCFunction)file_write, 0},
870 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +0000871 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000872#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +0000873 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000874#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000875 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000876 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000877 {"readlines", (PyCFunction)file_readlines, 1},
878 {"writelines", (PyCFunction)file_writelines, 0},
879 {"flush", (PyCFunction)file_flush, 0},
880 {"close", (PyCFunction)file_close, 0},
881 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000882 {NULL, NULL} /* sentinel */
883};
884
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000885#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886
887static struct memberlist file_memberlist[] = {
888 {"softspace", T_INT, OFF(f_softspace)},
889 {"mode", T_OBJECT, OFF(f_mode), RO},
890 {"name", T_OBJECT, OFF(f_name), RO},
891 /* getattr(f, "closed") is implemented without this table */
892 {"closed", T_INT, 0, RO},
893 {NULL} /* Sentinel */
894};
895
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000896static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000897file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000898 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000899 char *name;
900{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000901 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000902
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000904 if (res != NULL)
905 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000906 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000907 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908 return PyInt_FromLong((long)(f->f_fp == 0));
909 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000910}
911
912static int
913file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000914 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000915 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000916 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000917{
918 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000919 PyErr_SetString(PyExc_AttributeError,
920 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000921 return -1;
922 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000923 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000924}
925
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000926PyTypeObject PyFile_Type = {
927 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000928 0,
929 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000930 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000931 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000932 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000933 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000934 (getattrfunc)file_getattr, /*tp_getattr*/
935 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000936 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000937 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000938};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000939
940/* Interface for the 'soft space' between print items. */
941
942int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000943PyFile_SoftSpace(f, newflag)
944 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000945 int newflag;
946{
947 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000948 if (f == NULL) {
949 /* Do nothing */
950 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000951 else if (PyFile_Check(f)) {
952 oldflag = ((PyFileObject *)f)->f_softspace;
953 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000954 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000955 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000956 PyObject *v;
957 v = PyObject_GetAttrString(f, "softspace");
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 (PyInt_Check(v))
962 oldflag = PyInt_AsLong(v);
963 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000964 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000965 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000966 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000967 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000968 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000969 if (PyObject_SetAttrString(f, "softspace", v) != 0)
970 PyErr_Clear();
971 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000972 }
973 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000974 return oldflag;
975}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000976
977/* Interfaces to write objects/strings to file-like objects */
978
979int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980PyFile_WriteObject(v, f, flags)
981 PyObject *v;
982 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000983 int flags;
984{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000985 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000986 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000987 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000988 return -1;
989 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000990 else if (PyFile_Check(f)) {
991 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000992 if (fp == NULL) {
993 err_closed();
994 return -1;
995 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000996 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000997 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000998 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000999 if (writer == NULL)
1000 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001001 if (flags & Py_PRINT_RAW)
1002 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001003 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001004 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001005 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001006 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001007 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001008 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001009 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001010 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001011 Py_DECREF(value);
1012 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001013 return -1;
1014 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001015 result = PyEval_CallObject(writer, args);
1016 Py_DECREF(args);
1017 Py_DECREF(value);
1018 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001019 if (result == NULL)
1020 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001021 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001022 return 0;
1023}
1024
Guido van Rossum27a60b11997-05-22 22:25:11 +00001025int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001026PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001027 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001028 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001029{
1030 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001031 /* Should be caused by a pre-existing error */
1032 if(!PyErr_Occurred())
1033 PyErr_SetString(PyExc_SystemError,
1034 "null file for PyFile_WriteString");
1035 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001036 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001037 else if (PyFile_Check(f)) {
1038 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001039 if (fp == NULL) {
1040 err_closed();
1041 return -1;
1042 }
1043 fputs(s, fp);
1044 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001045 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001046 else if (!PyErr_Occurred()) {
1047 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001048 int err;
1049 if (v == NULL)
1050 return -1;
1051 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1052 Py_DECREF(v);
1053 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001054 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001055 else
1056 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001057}