blob: b9fa0fc11465c2e3de867a82b6efea87f1efdc39 [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 Rossumc0b618a1997-05-02 03:12:38 +0000259 if (!PyArg_Parse(args, "l", &offset)) {
260 PyErr_Clear();
261 if (!PyArg_Parse(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000262 return NULL;
263 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000264 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000265 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000266 ret = fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000267 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000268 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000269 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000270 clearerr(f->f_fp);
271 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000272 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000273 Py_INCREF(Py_None);
274 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000275}
276
Guido van Rossumd7047b31995-01-02 19:07:15 +0000277#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000278static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000279file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000280 PyFileObject *f;
281 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000282{
283 long newsize;
284 int ret;
285
286 if (f->f_fp == NULL)
287 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000288 if (!PyArg_Parse(args, "l", &newsize)) {
289 PyErr_Clear();
290 if (!PyArg_NoArgs(args))
Guido van Rossumd7047b31995-01-02 19:07:15 +0000291 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000292 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000293 errno = 0;
294 newsize = ftell(f->f_fp); /* default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000295 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000296 if (newsize == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000297 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000298 clearerr(f->f_fp);
299 return NULL;
300 }
301 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000302 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000303 errno = 0;
304 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000305 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000306 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000307 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000308 errno = 0;
309 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000311 }
312 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000313 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000314 clearerr(f->f_fp);
315 return NULL;
316 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000317 Py_INCREF(Py_None);
318 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000319}
320#endif /* HAVE_FTRUNCATE */
321
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000322static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000323file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000324 PyFileObject *f;
325 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000326{
327 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000328 if (f->f_fp == NULL)
329 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000330 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000332 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000333 errno = 0;
334 offset = ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335 Py_END_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000336 if (offset == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000337 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000338 clearerr(f->f_fp);
339 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000340 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000341 return PyInt_FromLong(offset);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000342}
343
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000345file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 PyFileObject *f;
347 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000348{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000349 if (f->f_fp == NULL)
350 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000352 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000354}
355
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000357file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358 PyFileObject *f;
359 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000360{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000361 int res;
362
Guido van Rossumd7297e61992-07-06 14:19:26 +0000363 if (f->f_fp == NULL)
364 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000365 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000366 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000367 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000368 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000369 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000370 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000371 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000372 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000373 clearerr(f->f_fp);
374 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000375 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000376 Py_INCREF(Py_None);
377 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000378}
379
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000381file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000382 PyFileObject *f;
383 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000384{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000385 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000386 if (f->f_fp == NULL)
387 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000388 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000389 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000391 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 Py_END_ALLOW_THREADS
393 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000394}
395
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000396/* We expect that fstat exists on most systems.
397 It's confirmed on Unix, Mac and Windows.
398 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
399#ifndef DONT_HAVE_FSTAT
400#define HAVE_FSTAT
401
402#include <sys/types.h>
403#include <sys/stat.h>
404
405#endif
406
407#if BUFSIZ < 8192
408#define SMALLCHUNK 8192
409#else
410#define SMALLCHUNK BUFSIZ
411#endif
412
413#define BIGCHUNK (512*1024)
414
415static size_t
416new_buffersize(f, currentsize)
417 PyFileObject *f;
418 size_t currentsize;
419{
420#ifdef HAVE_FSTAT
421 long pos, end;
422 struct stat st;
423 if (fstat(fileno(f->f_fp), &st) == 0) {
424 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000425 /* The following is not a bug: we really need to call lseek()
426 *and* ftell(). The reason is that some stdio libraries
427 mistakenly flush their buffer when ftell() is called and
428 the lseek() call it makes fails, thereby throwing away
429 data that cannot be recovered in any way. To avoid this,
430 we first test lseek(), and only call ftell() if lseek()
431 works. We can't use the lseek() value either, because we
432 need to take the amount of buffered data into account.
433 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000434 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
435 if (pos >= 0)
436 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000437 if (pos < 0)
438 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000439 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000440 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000441 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000442 }
443#endif
444 if (currentsize > SMALLCHUNK) {
445 /* Keep doubling until we reach BIGCHUNK;
446 then keep adding BIGCHUNK. */
447 if (currentsize <= BIGCHUNK)
448 return currentsize + currentsize;
449 else
450 return currentsize + BIGCHUNK;
451 }
452 return currentsize + SMALLCHUNK;
453}
454
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000455static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000456file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457 PyFileObject *f;
458 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000459{
Guido van Rossum789a1611997-05-10 22:33:55 +0000460 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000461 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000462 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000463
Guido van Rossumd7297e61992-07-06 14:19:26 +0000464 if (f->f_fp == NULL)
465 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000466 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
467 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000468 if (bytesrequested < 0)
469 buffersize = new_buffersize(f, 0);
470 else
471 buffersize = bytesrequested;
472 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000473 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000475 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000476 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000477 Py_BEGIN_ALLOW_THREADS
478 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000479 chunksize = fread(BUF(v) + bytesread, 1,
480 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000481 Py_END_ALLOW_THREADS
482 if (chunksize == 0) {
483 if (!ferror(f->f_fp))
484 break;
485 PyErr_SetFromErrno(PyExc_IOError);
486 clearerr(f->f_fp);
487 Py_DECREF(v);
488 return NULL;
489 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000490 bytesread += chunksize;
491 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000492 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000493 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000494 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000495 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000496 return NULL;
497 }
498 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000499 if (bytesread != buffersize)
500 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501 return v;
502}
503
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000504static PyObject *
505file_readinto(f, args)
506 PyFileObject *f;
507 PyObject *args;
508{
509 char *ptr;
510 int ntodo, ndone, nnow;
511
512 if (f->f_fp == NULL)
513 return err_closed();
514 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
515 return NULL;
516 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000517 while (ntodo > 0) {
518 Py_BEGIN_ALLOW_THREADS
519 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000520 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000521 Py_END_ALLOW_THREADS
522 if (nnow == 0) {
523 if (!ferror(f->f_fp))
524 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000525 PyErr_SetFromErrno(PyExc_IOError);
526 clearerr(f->f_fp);
527 return NULL;
528 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000529 ndone += nnow;
530 ntodo -= nnow;
531 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000532 return PyInt_FromLong(ndone);
533}
534
535
Guido van Rossum0bd24411991-04-04 15:21:57 +0000536/* Internal routine to get a line.
537 Size argument interpretation:
538 > 0: max length;
539 = 0: read arbitrary line;
540 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000541*/
542
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000543static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000544getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000545 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000546 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000547{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000548 register FILE *fp;
549 register int c;
550 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000551 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000553
Guido van Rossumc10aa771992-07-31 12:42:38 +0000554 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000555 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000556 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000557 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000558 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000559 buf = BUF(v);
560 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000561
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000562 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000563 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000564 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000565 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000566 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000567 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000569 return NULL;
570 }
571 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000572 Py_DECREF(v);
573 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000574 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000575 return NULL;
576 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000577 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000578 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000579 }
580 if ((*buf++ = c) == '\n') {
581 if (n < 0)
582 buf--;
583 break;
584 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000585 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000586 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000587 break;
588 n1 = n2;
589 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000590 Py_BLOCK_THREADS
591 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000592 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000593 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000594 buf = BUF(v) + n1;
595 end = BUF(v) + n2;
596 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000597 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000598 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000599
Guido van Rossumce5ba841991-03-06 13:06:18 +0000600 n1 = buf - BUF(v);
601 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603 return v;
604}
605
Guido van Rossum0bd24411991-04-04 15:21:57 +0000606/* External C interface */
607
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608PyObject *
609PyFile_GetLine(f, n)
610 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000611 int n;
612{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000613 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000614 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000615 return NULL;
616 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000617 if (!PyFile_Check(f)) {
618 PyObject *reader;
619 PyObject *args;
620 PyObject *result;
621 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000622 if (reader == NULL)
623 return NULL;
624 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000626 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000628 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000630 return NULL;
631 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 result = PyEval_CallObject(reader, args);
633 Py_DECREF(reader);
634 Py_DECREF(args);
635 if (result != NULL && !PyString_Check(result)) {
636 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000637 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000638 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000639 "object.readline() returned non-string");
640 }
641 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000642 char *s = PyString_AsString(result);
643 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000644 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000645 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000646 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000647 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000648 "EOF when reading a line");
649 }
650 else if (s[len-1] == '\n') {
651 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000652 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000653 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 PyObject *v;
655 v = PyString_FromStringAndSize(s,
656 len-1);
657 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000658 result = v;
659 }
660 }
661 }
662 return result;
663 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000664 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000665 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000666 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000667}
668
669/* Python method */
670
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000672file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000673 PyFileObject *f;
674 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000675{
Guido van Rossum789a1611997-05-10 22:33:55 +0000676 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000677
Guido van Rossumd7297e61992-07-06 14:19:26 +0000678 if (f->f_fp == NULL)
679 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000680 if (!PyArg_ParseTuple(args, "|i", &n))
681 return NULL;
682 if (n == 0)
683 return PyString_FromString("");
684 if (n < 0)
685 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000686 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000687}
688
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000689static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000690file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000691 PyFileObject *f;
692 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000693{
Guido van Rossum789a1611997-05-10 22:33:55 +0000694 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000695 PyObject *list;
696 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000697 char small_buffer[SMALLCHUNK];
698 char *buffer = small_buffer;
699 size_t buffersize = SMALLCHUNK;
700 PyObject *big_buffer = NULL;
701 size_t nfilled = 0;
702 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000703 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000704 char *p, *q, *end;
705 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000706
Guido van Rossumd7297e61992-07-06 14:19:26 +0000707 if (f->f_fp == NULL)
708 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000709 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000710 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000711 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000712 return NULL;
713 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000714 Py_BEGIN_ALLOW_THREADS
715 errno = 0;
716 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
717 Py_END_ALLOW_THREADS
718 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000719 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000720 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000721 break;
722 PyErr_SetFromErrno(PyExc_IOError);
723 clearerr(f->f_fp);
724 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000725 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000726 list = NULL;
727 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000728 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000729 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000730 p = memchr(buffer+nfilled, '\n', nread);
731 if (p == NULL) {
732 /* Need a larger buffer to fit this line */
733 nfilled += nread;
734 buffersize *= 2;
735 if (big_buffer == NULL) {
736 /* Create the big buffer */
737 big_buffer = PyString_FromStringAndSize(
738 NULL, buffersize);
739 if (big_buffer == NULL)
740 goto error;
741 buffer = PyString_AS_STRING(big_buffer);
742 memcpy(buffer, small_buffer, nfilled);
743 }
744 else {
745 /* Grow the big buffer */
746 _PyString_Resize(&big_buffer, buffersize);
747 buffer = PyString_AS_STRING(big_buffer);
748 }
749 continue;
750 }
751 end = buffer+nfilled+nread;
752 q = buffer;
753 do {
754 /* Process complete lines */
755 p++;
756 line = PyString_FromStringAndSize(q, p-q);
757 if (line == NULL)
758 goto error;
759 err = PyList_Append(list, line);
760 Py_DECREF(line);
761 if (err != 0)
762 goto error;
763 q = p;
764 p = memchr(q, '\n', end-q);
765 } while (p != NULL);
766 /* Move the remaining incomplete line to the start */
767 nfilled = end-q;
768 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000769 if (sizehint > 0)
770 if (totalread >= (size_t)sizehint)
771 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000772 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000773 if (nfilled != 0) {
774 /* Partial last line */
775 line = PyString_FromStringAndSize(buffer, nfilled);
776 if (line == NULL)
777 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000778 if (sizehint > 0) {
779 /* Need to complete the last line */
780 PyObject *rest = getline(f, 0);
781 if (rest == NULL) {
782 Py_DECREF(line);
783 goto error;
784 }
785 PyString_Concat(&line, rest);
786 Py_DECREF(rest);
787 if (line == NULL)
788 goto error;
789 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000790 err = PyList_Append(list, line);
791 Py_DECREF(line);
792 if (err != 0)
793 goto error;
794 }
795 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000796 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000797 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000798 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000799 return list;
800}
801
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000802static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000803file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000804 PyFileObject *f;
805 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000806{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000807 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000808 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000809 if (f->f_fp == NULL)
810 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000811 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000812 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000813 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000814 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000815 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000816 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000817 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000819 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000820 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000821 return NULL;
822 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000823 Py_INCREF(Py_None);
824 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000825}
826
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000827static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000828file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000829 PyFileObject *f;
830 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000831{
832 int i, n;
833 if (f->f_fp == NULL)
834 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000835 if (args == NULL || !PyList_Check(args)) {
836 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000837 "writelines() requires list of strings");
838 return NULL;
839 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000840 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000841 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000842 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000843 errno = 0;
844 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000845 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000846 int len;
847 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000848 if (!PyString_Check(line)) {
849 Py_BLOCK_THREADS
850 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000851 "writelines() requires list of strings");
852 return NULL;
853 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000854 len = PyString_Size(line);
855 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000856 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000857 Py_BLOCK_THREADS
858 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000859 clearerr(f->f_fp);
860 return NULL;
861 }
862 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000863 Py_END_ALLOW_THREADS
864 Py_INCREF(Py_None);
865 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000866}
867
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000868static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000869 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000870 {"read", (PyCFunction)file_read, 1},
871 {"write", (PyCFunction)file_write, 0},
872 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000873 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000874#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000875 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000876#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000877 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000878 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000879 {"readlines", (PyCFunction)file_readlines, 1},
880 {"writelines", (PyCFunction)file_writelines, 0},
881 {"flush", (PyCFunction)file_flush, 0},
882 {"close", (PyCFunction)file_close, 0},
883 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000884 {NULL, NULL} /* sentinel */
885};
886
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000887#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000888
889static struct memberlist file_memberlist[] = {
890 {"softspace", T_INT, OFF(f_softspace)},
891 {"mode", T_OBJECT, OFF(f_mode), RO},
892 {"name", T_OBJECT, OFF(f_name), RO},
893 /* getattr(f, "closed") is implemented without this table */
894 {"closed", T_INT, 0, RO},
895 {NULL} /* Sentinel */
896};
897
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000898static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000899file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000900 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000901 char *name;
902{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000904
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000905 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000906 if (res != NULL)
907 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000909 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000910 return PyInt_FromLong((long)(f->f_fp == 0));
911 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000912}
913
914static int
915file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000916 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000917 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000918 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000919{
920 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000921 PyErr_SetString(PyExc_AttributeError,
922 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000923 return -1;
924 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000925 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000926}
927
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000928PyTypeObject PyFile_Type = {
929 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930 0,
931 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000932 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000933 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000934 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000935 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000936 (getattrfunc)file_getattr, /*tp_getattr*/
937 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000938 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000939 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000940};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000941
942/* Interface for the 'soft space' between print items. */
943
944int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000945PyFile_SoftSpace(f, newflag)
946 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000947 int newflag;
948{
949 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000950 if (f == NULL) {
951 /* Do nothing */
952 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000953 else if (PyFile_Check(f)) {
954 oldflag = ((PyFileObject *)f)->f_softspace;
955 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000956 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000957 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000958 PyObject *v;
959 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000960 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000961 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000962 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000963 if (PyInt_Check(v))
964 oldflag = PyInt_AsLong(v);
965 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000966 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000967 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000968 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000969 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000970 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000971 if (PyObject_SetAttrString(f, "softspace", v) != 0)
972 PyErr_Clear();
973 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000974 }
975 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000976 return oldflag;
977}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000978
979/* Interfaces to write objects/strings to file-like objects */
980
981int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000982PyFile_WriteObject(v, f, flags)
983 PyObject *v;
984 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000985 int flags;
986{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000987 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000988 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000989 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000990 return -1;
991 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000992 else if (PyFile_Check(f)) {
993 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000994 if (fp == NULL) {
995 err_closed();
996 return -1;
997 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000998 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000999 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001000 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001001 if (writer == NULL)
1002 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003 if (flags & Py_PRINT_RAW)
1004 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001005 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001006 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001007 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001008 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001009 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001010 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001011 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001012 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013 Py_DECREF(value);
1014 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001015 return -1;
1016 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001017 result = PyEval_CallObject(writer, args);
1018 Py_DECREF(args);
1019 Py_DECREF(value);
1020 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001021 if (result == NULL)
1022 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001023 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001024 return 0;
1025}
1026
Guido van Rossum27a60b11997-05-22 22:25:11 +00001027int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001028PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001029 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001030 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001031{
1032 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001033 /* Should be caused by a pre-existing error */
1034 if(!PyErr_Occurred())
1035 PyErr_SetString(PyExc_SystemError,
1036 "null file for PyFile_WriteString");
1037 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001038 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001039 else if (PyFile_Check(f)) {
1040 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001041 if (fp == NULL) {
1042 err_closed();
1043 return -1;
1044 }
1045 fputs(s, fp);
1046 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001047 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001048 else if (!PyErr_Occurred()) {
1049 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001050 int err;
1051 if (v == NULL)
1052 return -1;
1053 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1054 Py_DECREF(v);
1055 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001056 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001057 else
1058 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001059}