blob: f8c58ba45430e0d3462584ce2c8a6831679bd83a [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* File object implementation */
33
Guido van Rossumc0b618a1997-05-02 03:12:38 +000034#include "Python.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000035#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036
Guido van Rossum685a38e1996-12-05 21:54:17 +000037#ifdef HAVE_UNISTD_H
38#include <unistd.h>
39#endif
40
Guido van Rossumb8199141997-05-06 15:23:24 +000041#ifdef MS_WIN32
42#define ftruncate _chsize
43#define fileno _fileno
44#define HAVE_FTRUNCATE
45#endif
46
Guido van Rossum295d1711995-02-19 15:55:19 +000047#ifdef THINK_C
48#define HAVE_FOPENRF
49#endif
Jack Jansene08dea191995-04-23 22:12:47 +000050#ifdef __MWERKS__
51/* Mwerks fopen() doesn't always set errno */
52#define NO_FOPEN_ERRNO
53#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000054
Guido van Rossumc0b618a1997-05-02 03:12:38 +000055#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000056
Guido van Rossumf1dc5661993-07-05 10:31:29 +000057#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000058
59typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000060 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000062 PyObject *f_name;
63 PyObject *f_mode;
64 int (*f_close) Py_PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000065 int f_softspace; /* Flag used by 'print' command */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000066} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067
68FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +000069PyFile_AsFile(f)
70 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000072 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000074 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000075 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076}
77
Guido van Rossumc0b618a1997-05-02 03:12:38 +000078PyObject *
79PyFile_Name(f)
80 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000081{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000083 return NULL;
84 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000085 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000086}
87
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088PyObject *
89PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090 FILE *fp;
91 char *name;
92 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000093 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000095 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 if (f == NULL)
97 return NULL;
98 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000099 f->f_name = PyString_FromString(name);
100 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000101 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000102 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000104 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105 return NULL;
106 }
107 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000108 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109}
110
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000111PyObject *
112PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 char *name, *mode;
114{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115 extern int fclose Py_PROTO((FILE *));
116 PyFileObject *f;
117 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 if (f == NULL)
119 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000120#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000121 if (*mode == '*') {
122 FILE *fopenRF();
123 f->f_fp = fopenRF(name, mode+1);
124 }
125 else
126#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000127 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000128 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000129 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000130 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000131 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000132 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000133#ifdef NO_FOPEN_ERRNO
134 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000135 PyErr_SetString(PyExc_IOError, "Cannot open file");
136 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000137 return NULL;
138 }
139#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000140 PyErr_SetFromErrno(PyExc_IOError);
141 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000142 return NULL;
143 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000144 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145}
146
Guido van Rossumb6775db1994-08-01 11:34:53 +0000147void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000148PyFile_SetBufSize(f, bufsize)
149 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000150 int bufsize;
151{
152 if (bufsize >= 0) {
153#ifdef HAVE_SETVBUF
154 int type;
155 switch (bufsize) {
156 case 0:
157 type = _IONBF;
158 break;
159 case 1:
160 type = _IOLBF;
161 bufsize = BUFSIZ;
162 break;
163 default:
164 type = _IOFBF;
165 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000166 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
167 type, bufsize);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#endif /* HAVE_SETVBUF */
169 }
170}
171
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000172static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000173err_closed()
174{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000175 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000176 return NULL;
177}
178
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179/* Methods */
180
181static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000182file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000183 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000185 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000186 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000187 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000188 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000189 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000190 if (f->f_name != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000191 Py_DECREF(f->f_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192 if (f->f_mode != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000193 Py_DECREF(f->f_mode);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 free((char *)f);
195}
196
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000197static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000198file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000199 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200{
201 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000202 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000203 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 PyString_AsString(f->f_name),
205 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000206 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208}
209
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000210static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000211file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000212 PyFileObject *f;
213 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000215 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000216 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000219 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000220 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000221 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000222 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000223 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000224 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225 f->f_fp = NULL;
226 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000227 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000229 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230 return PyInt_FromLong((long)sts);
231 Py_INCREF(Py_None);
232 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233}
234
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000236file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 PyFileObject *f;
238 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000239{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000240 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000241 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000242 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000243
Guido van Rossumd7297e61992-07-06 14:19:26 +0000244 if (f->f_fp == NULL)
245 return err_closed();
246 whence = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000247 if (!PyArg_Parse(args, "l", &offset)) {
248 PyErr_Clear();
249 if (!PyArg_Parse(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000250 return NULL;
251 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000252 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000253 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000254 ret = fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000255 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000256 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000257 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000258 clearerr(f->f_fp);
259 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000260 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000261 Py_INCREF(Py_None);
262 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000263}
264
Guido van Rossumd7047b31995-01-02 19:07:15 +0000265#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000266static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000267file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000268 PyFileObject *f;
269 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000270{
271 long newsize;
272 int ret;
273
274 if (f->f_fp == NULL)
275 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000276 if (!PyArg_Parse(args, "l", &newsize)) {
277 PyErr_Clear();
278 if (!PyArg_NoArgs(args))
Guido van Rossumd7047b31995-01-02 19:07:15 +0000279 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000280 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000281 errno = 0;
282 newsize = ftell(f->f_fp); /* default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000283 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000284 if (newsize == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000285 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000286 clearerr(f->f_fp);
287 return NULL;
288 }
289 }
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 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000293 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000294 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000295 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000296 errno = 0;
297 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000298 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000299 }
300 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000301 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000302 clearerr(f->f_fp);
303 return NULL;
304 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000305 Py_INCREF(Py_None);
306 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000307}
308#endif /* HAVE_FTRUNCATE */
309
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000311file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000312 PyFileObject *f;
313 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000314{
315 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000316 if (f->f_fp == NULL)
317 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000318 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000320 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000321 errno = 0;
322 offset = ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323 Py_END_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000324 if (offset == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000325 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000326 clearerr(f->f_fp);
327 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000328 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000329 return PyInt_FromLong(offset);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000330}
331
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000332static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000333file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000334 PyFileObject *f;
335 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000336{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000337 if (f->f_fp == NULL)
338 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000339 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000340 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000341 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000342}
343
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000345file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 PyFileObject *f;
347 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000348{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000349 int res;
350
Guido van Rossumd7297e61992-07-06 14:19:26 +0000351 if (f->f_fp == NULL)
352 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000356 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000357 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000359 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000360 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000361 clearerr(f->f_fp);
362 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000363 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000364 Py_INCREF(Py_None);
365 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000366}
367
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000368static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000369file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000370 PyFileObject *f;
371 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000372{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000373 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000374 if (f->f_fp == NULL)
375 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000376 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000377 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000378 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000379 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 Py_END_ALLOW_THREADS
381 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000382}
383
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000384/* We expect that fstat exists on most systems.
385 It's confirmed on Unix, Mac and Windows.
386 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
387#ifndef DONT_HAVE_FSTAT
388#define HAVE_FSTAT
389
390#include <sys/types.h>
391#include <sys/stat.h>
392
393#endif
394
395#if BUFSIZ < 8192
396#define SMALLCHUNK 8192
397#else
398#define SMALLCHUNK BUFSIZ
399#endif
400
401#define BIGCHUNK (512*1024)
402
403static size_t
404new_buffersize(f, currentsize)
405 PyFileObject *f;
406 size_t currentsize;
407{
408#ifdef HAVE_FSTAT
409 long pos, end;
410 struct stat st;
411 if (fstat(fileno(f->f_fp), &st) == 0) {
412 end = st.st_size;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000413 pos = ftell(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000414 if (end > pos && pos >= 0)
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000415 return end - pos + 1;
416 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000417 }
418#endif
419 if (currentsize > SMALLCHUNK) {
420 /* Keep doubling until we reach BIGCHUNK;
421 then keep adding BIGCHUNK. */
422 if (currentsize <= BIGCHUNK)
423 return currentsize + currentsize;
424 else
425 return currentsize + BIGCHUNK;
426 }
427 return currentsize + SMALLCHUNK;
428}
429
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000431file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432 PyFileObject *f;
433 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000434{
Guido van Rossum789a1611997-05-10 22:33:55 +0000435 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000436 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000438
Guido van Rossumd7297e61992-07-06 14:19:26 +0000439 if (f->f_fp == NULL)
440 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000441 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
442 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000443 if (bytesrequested < 0)
444 buffersize = new_buffersize(f, 0);
445 else
446 buffersize = bytesrequested;
447 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000448 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000449 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000450 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000451 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000452 Py_BEGIN_ALLOW_THREADS
453 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000454 chunksize = fread(BUF(v) + bytesread, 1,
455 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000456 Py_END_ALLOW_THREADS
457 if (chunksize == 0) {
458 if (!ferror(f->f_fp))
459 break;
460 PyErr_SetFromErrno(PyExc_IOError);
461 clearerr(f->f_fp);
462 Py_DECREF(v);
463 return NULL;
464 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000465 bytesread += chunksize;
466 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000467 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000468 if (bytesrequested < 0) {
469 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000470 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000471 return NULL;
472 }
473 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000474 if (bytesread != buffersize)
475 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000476 return v;
477}
478
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000479static PyObject *
480file_readinto(f, args)
481 PyFileObject *f;
482 PyObject *args;
483{
484 char *ptr;
485 int ntodo, ndone, nnow;
486
487 if (f->f_fp == NULL)
488 return err_closed();
489 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
490 return NULL;
491 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000492 while (ntodo > 0) {
493 Py_BEGIN_ALLOW_THREADS
494 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000495 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000496 Py_END_ALLOW_THREADS
497 if (nnow == 0) {
498 if (!ferror(f->f_fp))
499 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000500 PyErr_SetFromErrno(PyExc_IOError);
501 clearerr(f->f_fp);
502 return NULL;
503 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000504 ndone += nnow;
505 ntodo -= nnow;
506 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000507 return PyInt_FromLong(ndone);
508}
509
510
Guido van Rossum0bd24411991-04-04 15:21:57 +0000511/* Internal routine to get a line.
512 Size argument interpretation:
513 > 0: max length;
514 = 0: read arbitrary line;
515 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000516*/
517
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000518static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000519getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000520 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000521 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000522{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000523 register FILE *fp;
524 register int c;
525 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000526 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000527 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000528
Guido van Rossumc10aa771992-07-31 12:42:38 +0000529 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000530 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000531 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000532 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000533 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000534 buf = BUF(v);
535 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000536
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000537 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000538 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000539 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000540 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000541 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000542 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000543 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000544 return NULL;
545 }
546 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000547 Py_DECREF(v);
548 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000549 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000550 return NULL;
551 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000552 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000553 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000554 }
555 if ((*buf++ = c) == '\n') {
556 if (n < 0)
557 buf--;
558 break;
559 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000560 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000561 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000562 break;
563 n1 = n2;
564 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000565 Py_BLOCK_THREADS
566 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000567 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000569 buf = BUF(v) + n1;
570 end = BUF(v) + n2;
571 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000572 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000573 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000574
Guido van Rossumce5ba841991-03-06 13:06:18 +0000575 n1 = buf - BUF(v);
576 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000577 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000578 return v;
579}
580
Guido van Rossum0bd24411991-04-04 15:21:57 +0000581/* External C interface */
582
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000583PyObject *
584PyFile_GetLine(f, n)
585 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000586 int n;
587{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000588 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000589 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000590 return NULL;
591 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592 if (!PyFile_Check(f)) {
593 PyObject *reader;
594 PyObject *args;
595 PyObject *result;
596 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000597 if (reader == NULL)
598 return NULL;
599 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000601 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000603 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000605 return NULL;
606 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 result = PyEval_CallObject(reader, args);
608 Py_DECREF(reader);
609 Py_DECREF(args);
610 if (result != NULL && !PyString_Check(result)) {
611 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000612 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000613 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000614 "object.readline() returned non-string");
615 }
616 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000617 char *s = PyString_AsString(result);
618 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000619 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000620 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000621 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000622 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000623 "EOF when reading a line");
624 }
625 else if (s[len-1] == '\n') {
626 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000628 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629 PyObject *v;
630 v = PyString_FromStringAndSize(s,
631 len-1);
632 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000633 result = v;
634 }
635 }
636 }
637 return result;
638 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000639 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000640 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000641 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000642}
643
644/* Python method */
645
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000646static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000647file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000648 PyFileObject *f;
649 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000650{
Guido van Rossum789a1611997-05-10 22:33:55 +0000651 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000652
Guido van Rossumd7297e61992-07-06 14:19:26 +0000653 if (f->f_fp == NULL)
654 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000655 if (!PyArg_ParseTuple(args, "|i", &n))
656 return NULL;
657 if (n == 0)
658 return PyString_FromString("");
659 if (n < 0)
660 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000661 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000662}
663
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000664static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000665file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000666 PyFileObject *f;
667 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000668{
Guido van Rossum789a1611997-05-10 22:33:55 +0000669 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000670 PyObject *list;
671 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000672 char small_buffer[SMALLCHUNK];
673 char *buffer = small_buffer;
674 size_t buffersize = SMALLCHUNK;
675 PyObject *big_buffer = NULL;
676 size_t nfilled = 0;
677 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000678 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000679 char *p, *q, *end;
680 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000681
Guido van Rossumd7297e61992-07-06 14:19:26 +0000682 if (f->f_fp == NULL)
683 return err_closed();
Guido van Rossum789a1611997-05-10 22:33:55 +0000684 if (!PyArg_ParseTuple(args, "|l", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000685 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000686 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000687 return NULL;
688 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000689 Py_BEGIN_ALLOW_THREADS
690 errno = 0;
691 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
692 Py_END_ALLOW_THREADS
693 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000694 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000695 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000696 break;
697 PyErr_SetFromErrno(PyExc_IOError);
698 clearerr(f->f_fp);
699 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000700 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000701 list = NULL;
702 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000703 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000704 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000705 p = memchr(buffer+nfilled, '\n', nread);
706 if (p == NULL) {
707 /* Need a larger buffer to fit this line */
708 nfilled += nread;
709 buffersize *= 2;
710 if (big_buffer == NULL) {
711 /* Create the big buffer */
712 big_buffer = PyString_FromStringAndSize(
713 NULL, buffersize);
714 if (big_buffer == NULL)
715 goto error;
716 buffer = PyString_AS_STRING(big_buffer);
717 memcpy(buffer, small_buffer, nfilled);
718 }
719 else {
720 /* Grow the big buffer */
721 _PyString_Resize(&big_buffer, buffersize);
722 buffer = PyString_AS_STRING(big_buffer);
723 }
724 continue;
725 }
726 end = buffer+nfilled+nread;
727 q = buffer;
728 do {
729 /* Process complete lines */
730 p++;
731 line = PyString_FromStringAndSize(q, p-q);
732 if (line == NULL)
733 goto error;
734 err = PyList_Append(list, line);
735 Py_DECREF(line);
736 if (err != 0)
737 goto error;
738 q = p;
739 p = memchr(q, '\n', end-q);
740 } while (p != NULL);
741 /* Move the remaining incomplete line to the start */
742 nfilled = end-q;
743 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000744 if (sizehint > 0)
745 if (totalread >= (size_t)sizehint)
746 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000747 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000748 if (nfilled != 0) {
749 /* Partial last line */
750 line = PyString_FromStringAndSize(buffer, nfilled);
751 if (line == NULL)
752 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000753 if (sizehint > 0) {
754 /* Need to complete the last line */
755 PyObject *rest = getline(f, 0);
756 if (rest == NULL) {
757 Py_DECREF(line);
758 goto error;
759 }
760 PyString_Concat(&line, rest);
761 Py_DECREF(rest);
762 if (line == NULL)
763 goto error;
764 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000765 err = PyList_Append(list, line);
766 Py_DECREF(line);
767 if (err != 0)
768 goto error;
769 }
770 cleanup:
771 if (big_buffer)
772 Py_DECREF(big_buffer);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000773 return list;
774}
775
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000776static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000777file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000778 PyFileObject *f;
779 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000781 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000782 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000783 if (f->f_fp == NULL)
784 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000785 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000787 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000788 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000789 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000790 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000791 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000792 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000793 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000794 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795 return NULL;
796 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000797 Py_INCREF(Py_None);
798 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000799}
800
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000801static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000802file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000803 PyFileObject *f;
804 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000805{
806 int i, n;
807 if (f->f_fp == NULL)
808 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000809 if (args == NULL || !PyList_Check(args)) {
810 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000811 "writelines() requires list of strings");
812 return NULL;
813 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000814 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000815 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000816 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000817 errno = 0;
818 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000819 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000820 int len;
821 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000822 if (!PyString_Check(line)) {
823 Py_BLOCK_THREADS
824 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000825 "writelines() requires list of strings");
826 return NULL;
827 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000828 len = PyString_Size(line);
829 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000830 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000831 Py_BLOCK_THREADS
832 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000833 clearerr(f->f_fp);
834 return NULL;
835 }
836 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000837 Py_END_ALLOW_THREADS
838 Py_INCREF(Py_None);
839 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000840}
841
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000842static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000843 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000844 {"read", (PyCFunction)file_read, 1},
845 {"write", (PyCFunction)file_write, 0},
846 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000847 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000848#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000849 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000850#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000851 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000852 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000853 {"readlines", (PyCFunction)file_readlines, 1},
854 {"writelines", (PyCFunction)file_writelines, 0},
855 {"flush", (PyCFunction)file_flush, 0},
856 {"close", (PyCFunction)file_close, 0},
857 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000858 {NULL, NULL} /* sentinel */
859};
860
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000861#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000862
863static struct memberlist file_memberlist[] = {
864 {"softspace", T_INT, OFF(f_softspace)},
865 {"mode", T_OBJECT, OFF(f_mode), RO},
866 {"name", T_OBJECT, OFF(f_name), RO},
867 /* getattr(f, "closed") is implemented without this table */
868 {"closed", T_INT, 0, RO},
869 {NULL} /* Sentinel */
870};
871
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000872static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000873file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000874 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000875 char *name;
876{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000877 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000878
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000879 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000880 if (res != NULL)
881 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000882 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000883 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000884 return PyInt_FromLong((long)(f->f_fp == 0));
885 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886}
887
888static int
889file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000891 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000892 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000893{
894 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000895 PyErr_SetString(PyExc_AttributeError,
896 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000897 return -1;
898 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000899 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000900}
901
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000902PyTypeObject PyFile_Type = {
903 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000904 0,
905 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000906 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000907 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000908 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000909 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000910 (getattrfunc)file_getattr, /*tp_getattr*/
911 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000912 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000913 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000914};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000915
916/* Interface for the 'soft space' between print items. */
917
918int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000919PyFile_SoftSpace(f, newflag)
920 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000921 int newflag;
922{
923 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000924 if (f == NULL) {
925 /* Do nothing */
926 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000927 else if (PyFile_Check(f)) {
928 oldflag = ((PyFileObject *)f)->f_softspace;
929 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000930 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000931 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000932 PyObject *v;
933 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000934 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000935 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000936 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000937 if (PyInt_Check(v))
938 oldflag = PyInt_AsLong(v);
939 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000940 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000941 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000942 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000943 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000944 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000945 if (PyObject_SetAttrString(f, "softspace", v) != 0)
946 PyErr_Clear();
947 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000948 }
949 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000950 return oldflag;
951}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000952
953/* Interfaces to write objects/strings to file-like objects */
954
955int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000956PyFile_WriteObject(v, f, flags)
957 PyObject *v;
958 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000959 int flags;
960{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000961 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000962 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000963 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000964 return -1;
965 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000966 else if (PyFile_Check(f)) {
967 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000968 if (fp == NULL) {
969 err_closed();
970 return -1;
971 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000972 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000973 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000974 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000975 if (writer == NULL)
976 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000977 if (flags & Py_PRINT_RAW)
978 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000979 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000981 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000982 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +0000983 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000984 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000985 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +0000986 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000987 Py_DECREF(value);
988 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000989 return -1;
990 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000991 result = PyEval_CallObject(writer, args);
992 Py_DECREF(args);
993 Py_DECREF(value);
994 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000995 if (result == NULL)
996 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000997 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000998 return 0;
999}
1000
Guido van Rossum27a60b11997-05-22 22:25:11 +00001001int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001002PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001003 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001004 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001005{
1006 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001007 /* Should be caused by a pre-existing error */
1008 if(!PyErr_Occurred())
1009 PyErr_SetString(PyExc_SystemError,
1010 "null file for PyFile_WriteString");
1011 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001012 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013 else if (PyFile_Check(f)) {
1014 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001015 if (fp == NULL) {
1016 err_closed();
1017 return -1;
1018 }
1019 fputs(s, fp);
1020 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001021 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001022 else if (!PyErr_Occurred()) {
1023 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001024 int err;
1025 if (v == NULL)
1026 return -1;
1027 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1028 Py_DECREF(v);
1029 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001030 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001031 else
1032 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001033}