blob: 3215c6e6444a66e3df11e5165d9c7880081417bf [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;
413 pos = ftell(f->f_fp);
414 if (end > pos && pos >= 0)
415 return end - pos + 1;
416 }
417#endif
418 if (currentsize > SMALLCHUNK) {
419 /* Keep doubling until we reach BIGCHUNK;
420 then keep adding BIGCHUNK. */
421 if (currentsize <= BIGCHUNK)
422 return currentsize + currentsize;
423 else
424 return currentsize + BIGCHUNK;
425 }
426 return currentsize + SMALLCHUNK;
427}
428
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000429static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000430file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000431 PyFileObject *f;
432 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000433{
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000434 long bytesrequested;
435 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000436 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000437
Guido van Rossumd7297e61992-07-06 14:19:26 +0000438 if (f->f_fp == NULL)
439 return err_closed();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000440 if (args == NULL)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000441 bytesrequested = -1;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000442 else {
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000443 if (!PyArg_Parse(args, "l", &bytesrequested))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000444 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000445 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000446 if (bytesrequested < 0)
447 buffersize = new_buffersize(f, 0);
448 else
449 buffersize = bytesrequested;
450 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000451 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000452 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000453 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000454 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000455 Py_BEGIN_ALLOW_THREADS
456 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000457 chunksize = fread(BUF(v) + bytesread, 1,
458 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000459 Py_END_ALLOW_THREADS
460 if (chunksize == 0) {
461 if (!ferror(f->f_fp))
462 break;
463 PyErr_SetFromErrno(PyExc_IOError);
464 clearerr(f->f_fp);
465 Py_DECREF(v);
466 return NULL;
467 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000468 bytesread += chunksize;
469 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000470 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000471 if (bytesrequested < 0) {
472 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000473 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000474 return NULL;
475 }
476 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000477 if (bytesread != buffersize)
478 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479 return v;
480}
481
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000482static PyObject *
483file_readinto(f, args)
484 PyFileObject *f;
485 PyObject *args;
486{
487 char *ptr;
488 int ntodo, ndone, nnow;
489
490 if (f->f_fp == NULL)
491 return err_closed();
492 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
493 return NULL;
494 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000495 while (ntodo > 0) {
496 Py_BEGIN_ALLOW_THREADS
497 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000498 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000499 Py_END_ALLOW_THREADS
500 if (nnow == 0) {
501 if (!ferror(f->f_fp))
502 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000503 PyErr_SetFromErrno(PyExc_IOError);
504 clearerr(f->f_fp);
505 return NULL;
506 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000507 ndone += nnow;
508 ntodo -= nnow;
509 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000510 return PyInt_FromLong(ndone);
511}
512
513
Guido van Rossum0bd24411991-04-04 15:21:57 +0000514/* Internal routine to get a line.
515 Size argument interpretation:
516 > 0: max length;
517 = 0: read arbitrary line;
518 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000519*/
520
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000521static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000522getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000524 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000526 register FILE *fp;
527 register int c;
528 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000529 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000530 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000531
Guido van Rossumc10aa771992-07-31 12:42:38 +0000532 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000533 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000534 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000535 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000536 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000537 buf = BUF(v);
538 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000539
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000540 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000541 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000542 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000543 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000544 if (PyErr_CheckSignals()) {
545 Py_BLOCK_THREADS
546 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000547 return NULL;
548 }
549 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000550 Py_BLOCK_THREADS
551 Py_DECREF(v);
552 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000553 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000554 return NULL;
555 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000556 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000557 }
558 if ((*buf++ = c) == '\n') {
559 if (n < 0)
560 buf--;
561 break;
562 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000563 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000564 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000565 break;
566 n1 = n2;
567 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 Py_BLOCK_THREADS
569 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000570 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000571 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000572 buf = BUF(v) + n1;
573 end = BUF(v) + n2;
574 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000575 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000577
Guido van Rossumce5ba841991-03-06 13:06:18 +0000578 n1 = buf - BUF(v);
579 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000580 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000581 return v;
582}
583
Guido van Rossum0bd24411991-04-04 15:21:57 +0000584/* External C interface */
585
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000586PyObject *
587PyFile_GetLine(f, n)
588 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000589 int n;
590{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000591 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000593 return NULL;
594 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000595 if (!PyFile_Check(f)) {
596 PyObject *reader;
597 PyObject *args;
598 PyObject *result;
599 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000600 if (reader == NULL)
601 return NULL;
602 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000603 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000604 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000605 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000606 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000608 return NULL;
609 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000610 result = PyEval_CallObject(reader, args);
611 Py_DECREF(reader);
612 Py_DECREF(args);
613 if (result != NULL && !PyString_Check(result)) {
614 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000615 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000616 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000617 "object.readline() returned non-string");
618 }
619 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000620 char *s = PyString_AsString(result);
621 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000622 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000623 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000624 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000626 "EOF when reading a line");
627 }
628 else if (s[len-1] == '\n') {
629 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000630 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000631 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 PyObject *v;
633 v = PyString_FromStringAndSize(s,
634 len-1);
635 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000636 result = v;
637 }
638 }
639 }
640 return result;
641 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000642 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000643 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000644 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000645}
646
647/* Python method */
648
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000649static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000650file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000651 PyFileObject *f;
652 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000653{
654 int n;
655
Guido van Rossumd7297e61992-07-06 14:19:26 +0000656 if (f->f_fp == NULL)
657 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000658 if (args == NULL)
659 n = 0; /* Unlimited */
660 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000661 if (!PyArg_Parse(args, "i", &n))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000662 return NULL;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000663 if (n == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000664 return PyString_FromString("");
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000665 if (n < 0)
666 n = 0;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000667 }
668
Guido van Rossum51415a71992-03-27 17:23:38 +0000669 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000670}
671
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000672static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000673file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000674 PyFileObject *f;
675 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000676{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000677 PyObject *list;
678 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000679 char small_buffer[SMALLCHUNK];
680 char *buffer = small_buffer;
681 size_t buffersize = SMALLCHUNK;
682 PyObject *big_buffer = NULL;
683 size_t nfilled = 0;
684 size_t nread;
685 char *p, *q, *end;
686 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000687
Guido van Rossumd7297e61992-07-06 14:19:26 +0000688 if (f->f_fp == NULL)
689 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000690 if (!PyArg_NoArgs(args))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000691 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000692 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000693 return NULL;
694 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000695 Py_BEGIN_ALLOW_THREADS
696 errno = 0;
697 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
698 Py_END_ALLOW_THREADS
699 if (nread == 0) {
700 if (nread == 0)
701 break;
702 PyErr_SetFromErrno(PyExc_IOError);
703 clearerr(f->f_fp);
704 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000705 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000706 list = NULL;
707 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000708 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000709 p = memchr(buffer+nfilled, '\n', nread);
710 if (p == NULL) {
711 /* Need a larger buffer to fit this line */
712 nfilled += nread;
713 buffersize *= 2;
714 if (big_buffer == NULL) {
715 /* Create the big buffer */
716 big_buffer = PyString_FromStringAndSize(
717 NULL, buffersize);
718 if (big_buffer == NULL)
719 goto error;
720 buffer = PyString_AS_STRING(big_buffer);
721 memcpy(buffer, small_buffer, nfilled);
722 }
723 else {
724 /* Grow the big buffer */
725 _PyString_Resize(&big_buffer, buffersize);
726 buffer = PyString_AS_STRING(big_buffer);
727 }
728 continue;
729 }
730 end = buffer+nfilled+nread;
731 q = buffer;
732 do {
733 /* Process complete lines */
734 p++;
735 line = PyString_FromStringAndSize(q, p-q);
736 if (line == NULL)
737 goto error;
738 err = PyList_Append(list, line);
739 Py_DECREF(line);
740 if (err != 0)
741 goto error;
742 q = p;
743 p = memchr(q, '\n', end-q);
744 } while (p != NULL);
745 /* Move the remaining incomplete line to the start */
746 nfilled = end-q;
747 memmove(buffer, q, nfilled);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000748 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000749 if (nfilled != 0) {
750 /* Partial last line */
751 line = PyString_FromStringAndSize(buffer, nfilled);
752 if (line == NULL)
753 goto error;
754 err = PyList_Append(list, line);
755 Py_DECREF(line);
756 if (err != 0)
757 goto error;
758 }
759 cleanup:
760 if (big_buffer)
761 Py_DECREF(big_buffer);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000762 return list;
763}
764
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000765static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000766file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000767 PyFileObject *f;
768 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000769{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000770 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000771 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000772 if (f->f_fp == NULL)
773 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000774 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000775 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000776 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000777 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000779 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000780 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000781 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000782 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000783 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000784 return NULL;
785 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000786 Py_INCREF(Py_None);
787 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000788}
789
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000790static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000791file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000792 PyFileObject *f;
793 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000794{
795 int i, n;
796 if (f->f_fp == NULL)
797 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000798 if (args == NULL || !PyList_Check(args)) {
799 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000800 "writelines() requires list of strings");
801 return NULL;
802 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000803 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000804 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000805 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000806 errno = 0;
807 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000808 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000809 int len;
810 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000811 if (!PyString_Check(line)) {
812 Py_BLOCK_THREADS
813 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000814 "writelines() requires list of strings");
815 return NULL;
816 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000817 len = PyString_Size(line);
818 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000819 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000820 Py_BLOCK_THREADS
821 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000822 clearerr(f->f_fp);
823 return NULL;
824 }
825 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000826 Py_END_ALLOW_THREADS
827 Py_INCREF(Py_None);
828 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000829}
830
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000831static PyMethodDef file_methods[] = {
832 {"close", (PyCFunction)file_close, 0},
833 {"flush", (PyCFunction)file_flush, 0},
834 {"fileno", (PyCFunction)file_fileno, 0},
835 {"isatty", (PyCFunction)file_isatty, 0},
836 {"read", (PyCFunction)file_read, 0},
837 {"readline", (PyCFunction)file_readline, 0},
838 {"readlines", (PyCFunction)file_readlines, 0},
839 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000840#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000841 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000842#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000843 {"tell", (PyCFunction)file_tell, 0},
844 {"write", (PyCFunction)file_write, 0},
845 {"writelines", (PyCFunction)file_writelines, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000846 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000847 {NULL, NULL} /* sentinel */
848};
849
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000850#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000851
852static struct memberlist file_memberlist[] = {
853 {"softspace", T_INT, OFF(f_softspace)},
854 {"mode", T_OBJECT, OFF(f_mode), RO},
855 {"name", T_OBJECT, OFF(f_name), RO},
856 /* getattr(f, "closed") is implemented without this table */
857 {"closed", T_INT, 0, RO},
858 {NULL} /* Sentinel */
859};
860
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000861static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000862file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000863 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000864 char *name;
865{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000866 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000867
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000868 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000869 if (res != NULL)
870 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000871 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000872 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000873 return PyInt_FromLong((long)(f->f_fp == 0));
874 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000875}
876
877static int
878file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000879 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000880 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000881 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000882{
883 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000884 PyErr_SetString(PyExc_AttributeError,
885 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886 return -1;
887 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000889}
890
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000891PyTypeObject PyFile_Type = {
892 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000893 0,
894 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000895 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000896 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000897 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000898 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000899 (getattrfunc)file_getattr, /*tp_getattr*/
900 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000901 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000902 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000903};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000904
905/* Interface for the 'soft space' between print items. */
906
907int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908PyFile_SoftSpace(f, newflag)
909 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000910 int newflag;
911{
912 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000913 if (f == NULL) {
914 /* Do nothing */
915 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000916 else if (PyFile_Check(f)) {
917 oldflag = ((PyFileObject *)f)->f_softspace;
918 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000919 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000920 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000921 PyObject *v;
922 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000923 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000924 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000925 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000926 if (PyInt_Check(v))
927 oldflag = PyInt_AsLong(v);
928 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000929 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000930 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000931 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000932 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000933 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000934 if (PyObject_SetAttrString(f, "softspace", v) != 0)
935 PyErr_Clear();
936 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000937 }
938 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000939 return oldflag;
940}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000941
942/* Interfaces to write objects/strings to file-like objects */
943
944int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000945PyFile_WriteObject(v, f, flags)
946 PyObject *v;
947 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000948 int flags;
949{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000950 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000951 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000952 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000953 return -1;
954 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000955 else if (PyFile_Check(f)) {
956 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000957 if (fp == NULL) {
958 err_closed();
959 return -1;
960 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000961 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000962 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000963 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000964 if (writer == NULL)
965 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000966 if (flags & Py_PRINT_RAW)
967 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000968 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000969 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000970 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000971 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +0000972 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000973 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000974 args = Py_BuildValue("(O)", value);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000975 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000976 Py_DECREF(value);
977 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000978 return -1;
979 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980 result = PyEval_CallObject(writer, args);
981 Py_DECREF(args);
982 Py_DECREF(value);
983 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000984 if (result == NULL)
985 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000986 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000987 return 0;
988}
989
990void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000991PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000992 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000993 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000994{
995 if (f == NULL) {
996 /* Do nothing */
997 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000998 else if (PyFile_Check(f)) {
999 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001000 if (fp != NULL)
1001 fputs(s, fp);
1002 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003 else if (!PyErr_Occurred()) {
1004 PyObject *v = PyString_FromString(s);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001005 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001006 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001007 }
1008 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001009 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) != 0)
1010 PyErr_Clear();
1011 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001012 }
1013 }
1014}