blob: 1b3206134bd75b2c48ff8b94c5ca35bb4bbd529e [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 Rossumc0b618a1997-05-02 03:12:38 +0000384static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000385file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000386 PyFileObject *f;
387 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000388{
389 int n, n1, n2, n3;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000391
Guido van Rossumd7297e61992-07-06 14:19:26 +0000392 if (f->f_fp == NULL)
393 return err_closed();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000394 if (args == NULL)
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000395 n = -1;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000396 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000397 if (!PyArg_Parse(args, "i", &n))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000398 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000399 }
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000400 n2 = n >= 0 ? n : BUFSIZ;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000402 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000403 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000404 n1 = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000405 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000406 for (;;) {
407 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
408 /* XXX Error check? */
409 if (n3 == 0)
410 break;
411 n1 += n3;
412 if (n1 == n)
413 break;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000414 if (n < 0) {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000415 n2 = n1 + BUFSIZ;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000416 Py_BLOCK_THREADS
417 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000418 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000419 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000420 }
421 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 Py_END_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000423 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000424 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000425 return v;
426}
427
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000428static PyObject *
429file_readinto(f, args)
430 PyFileObject *f;
431 PyObject *args;
432{
433 char *ptr;
434 int ntodo, ndone, nnow;
435
436 if (f->f_fp == NULL)
437 return err_closed();
438 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
439 return NULL;
440 ndone = 0;
441 /*
442 ** XXXX Is this correct? Other threads may see partially-completed
443 ** reads if they look at the object we're reading into...
444 */
445 Py_BEGIN_ALLOW_THREADS
446 while(ntodo > 0) {
447 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
448 if (nnow < 0 ) {
449 PyErr_SetFromErrno(PyExc_IOError);
450 clearerr(f->f_fp);
451 return NULL;
452 }
453 if (nnow == 0)
454 break;
455 ndone += nnow;
456 ntodo -= nnow;
457 }
458 Py_END_ALLOW_THREADS
459 return PyInt_FromLong(ndone);
460}
461
462
Guido van Rossum0bd24411991-04-04 15:21:57 +0000463/* Internal routine to get a line.
464 Size argument interpretation:
465 > 0: max length;
466 = 0: read arbitrary line;
467 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000468*/
469
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000470static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000471getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000472 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000473 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000475 register FILE *fp;
476 register int c;
477 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000478 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000479 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000480
Guido van Rossumc10aa771992-07-31 12:42:38 +0000481 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000482 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000483 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000484 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000485 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000486 buf = BUF(v);
487 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000488
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000490 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000491 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000492 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000493 if (PyErr_CheckSignals()) {
494 Py_BLOCK_THREADS
495 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000496 return NULL;
497 }
498 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000499 Py_BLOCK_THREADS
500 Py_DECREF(v);
501 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000502 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000503 return NULL;
504 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000505 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000506 }
507 if ((*buf++ = c) == '\n') {
508 if (n < 0)
509 buf--;
510 break;
511 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000512 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000513 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000514 break;
515 n1 = n2;
516 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000517 Py_BLOCK_THREADS
518 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000519 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000520 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000521 buf = BUF(v) + n1;
522 end = BUF(v) + n2;
523 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000524 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000525 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000526
Guido van Rossumce5ba841991-03-06 13:06:18 +0000527 n1 = buf - BUF(v);
528 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000529 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000530 return v;
531}
532
Guido van Rossum0bd24411991-04-04 15:21:57 +0000533/* External C interface */
534
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000535PyObject *
536PyFile_GetLine(f, n)
537 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000538 int n;
539{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000540 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000541 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000542 return NULL;
543 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000544 if (!PyFile_Check(f)) {
545 PyObject *reader;
546 PyObject *args;
547 PyObject *result;
548 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000549 if (reader == NULL)
550 return NULL;
551 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000553 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000555 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000556 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000557 return NULL;
558 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 result = PyEval_CallObject(reader, args);
560 Py_DECREF(reader);
561 Py_DECREF(args);
562 if (result != NULL && !PyString_Check(result)) {
563 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000564 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000565 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000566 "object.readline() returned non-string");
567 }
568 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000569 char *s = PyString_AsString(result);
570 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000571 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000572 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000573 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000574 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000575 "EOF when reading a line");
576 }
577 else if (s[len-1] == '\n') {
578 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000579 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000580 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000581 PyObject *v;
582 v = PyString_FromStringAndSize(s,
583 len-1);
584 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000585 result = v;
586 }
587 }
588 }
589 return result;
590 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000591 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000592 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000593 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000594}
595
596/* Python method */
597
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000598static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000599file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 PyFileObject *f;
601 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000602{
603 int n;
604
Guido van Rossumd7297e61992-07-06 14:19:26 +0000605 if (f->f_fp == NULL)
606 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000607 if (args == NULL)
608 n = 0; /* Unlimited */
609 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000610 if (!PyArg_Parse(args, "i", &n))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000611 return NULL;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000612 if (n == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000613 return PyString_FromString("");
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000614 if (n < 0)
615 n = 0;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000616 }
617
Guido van Rossum51415a71992-03-27 17:23:38 +0000618 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000619}
620
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000621static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000622file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000623 PyFileObject *f;
624 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000625{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000626 PyObject *list;
627 PyObject *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000628
Guido van Rossumd7297e61992-07-06 14:19:26 +0000629 if (f->f_fp == NULL)
630 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000631 if (!PyArg_NoArgs(args))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000632 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000633 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000634 return NULL;
635 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000636 line = getline(f, 0);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000637 if (line != NULL && PyString_Size(line) == 0) {
638 Py_DECREF(line);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000639 break;
640 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000641 if (line == NULL || PyList_Append(list, line) != 0) {
642 Py_DECREF(list);
643 Py_XDECREF(line);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000644 return NULL;
645 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000646 Py_DECREF(line);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000647 }
648 return list;
649}
650
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000651static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000652file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000653 PyFileObject *f;
654 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000655{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000656 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000657 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000658 if (f->f_fp == NULL)
659 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000660 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000661 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000662 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000665 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000666 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000667 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000668 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000669 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000670 return NULL;
671 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000672 Py_INCREF(Py_None);
673 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000674}
675
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000676static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000677file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000678 PyFileObject *f;
679 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000680{
681 int i, n;
682 if (f->f_fp == NULL)
683 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000684 if (args == NULL || !PyList_Check(args)) {
685 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000686 "writelines() requires list of strings");
687 return NULL;
688 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000689 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000690 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000691 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000692 errno = 0;
693 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000694 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000695 int len;
696 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000697 if (!PyString_Check(line)) {
698 Py_BLOCK_THREADS
699 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000700 "writelines() requires list of strings");
701 return NULL;
702 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000703 len = PyString_Size(line);
704 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000705 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000706 Py_BLOCK_THREADS
707 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000708 clearerr(f->f_fp);
709 return NULL;
710 }
711 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000712 Py_END_ALLOW_THREADS
713 Py_INCREF(Py_None);
714 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000715}
716
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000717static PyMethodDef file_methods[] = {
718 {"close", (PyCFunction)file_close, 0},
719 {"flush", (PyCFunction)file_flush, 0},
720 {"fileno", (PyCFunction)file_fileno, 0},
721 {"isatty", (PyCFunction)file_isatty, 0},
722 {"read", (PyCFunction)file_read, 0},
723 {"readline", (PyCFunction)file_readline, 0},
724 {"readlines", (PyCFunction)file_readlines, 0},
725 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000726#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000727 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000728#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000729 {"tell", (PyCFunction)file_tell, 0},
730 {"write", (PyCFunction)file_write, 0},
731 {"writelines", (PyCFunction)file_writelines, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000732 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000733 {NULL, NULL} /* sentinel */
734};
735
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000736#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000737
738static struct memberlist file_memberlist[] = {
739 {"softspace", T_INT, OFF(f_softspace)},
740 {"mode", T_OBJECT, OFF(f_mode), RO},
741 {"name", T_OBJECT, OFF(f_name), RO},
742 /* getattr(f, "closed") is implemented without this table */
743 {"closed", T_INT, 0, RO},
744 {NULL} /* Sentinel */
745};
746
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000747static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000748file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000749 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000750 char *name;
751{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000752 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000753
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000754 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000755 if (res != NULL)
756 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000757 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000758 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000759 return PyInt_FromLong((long)(f->f_fp == 0));
760 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000761}
762
763static int
764file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000765 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000766 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000767 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000768{
769 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000770 PyErr_SetString(PyExc_AttributeError,
771 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000772 return -1;
773 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000774 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000775}
776
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000777PyTypeObject PyFile_Type = {
778 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000779 0,
780 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000781 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000782 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000783 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000784 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000785 (getattrfunc)file_getattr, /*tp_getattr*/
786 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000788 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000789};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000790
791/* Interface for the 'soft space' between print items. */
792
793int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000794PyFile_SoftSpace(f, newflag)
795 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000796 int newflag;
797{
798 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000799 if (f == NULL) {
800 /* Do nothing */
801 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000802 else if (PyFile_Check(f)) {
803 oldflag = ((PyFileObject *)f)->f_softspace;
804 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000805 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000806 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000807 PyObject *v;
808 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000809 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000810 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000811 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000812 if (PyInt_Check(v))
813 oldflag = PyInt_AsLong(v);
814 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000815 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000816 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000817 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000818 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000819 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000820 if (PyObject_SetAttrString(f, "softspace", v) != 0)
821 PyErr_Clear();
822 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000823 }
824 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000825 return oldflag;
826}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000827
828/* Interfaces to write objects/strings to file-like objects */
829
830int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000831PyFile_WriteObject(v, f, flags)
832 PyObject *v;
833 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000834 int flags;
835{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000836 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000837 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000838 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000839 return -1;
840 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000841 else if (PyFile_Check(f)) {
842 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000843 if (fp == NULL) {
844 err_closed();
845 return -1;
846 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000847 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000848 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000849 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000850 if (writer == NULL)
851 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000852 if (flags & Py_PRINT_RAW)
853 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000854 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000855 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000856 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000857 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +0000858 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000859 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000860 args = Py_BuildValue("(O)", value);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000861 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000862 Py_DECREF(value);
863 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000864 return -1;
865 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000866 result = PyEval_CallObject(writer, args);
867 Py_DECREF(args);
868 Py_DECREF(value);
869 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000870 if (result == NULL)
871 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000872 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000873 return 0;
874}
875
876void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000877PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000878 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000879 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000880{
881 if (f == NULL) {
882 /* Do nothing */
883 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000884 else if (PyFile_Check(f)) {
885 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000886 if (fp != NULL)
887 fputs(s, fp);
888 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000889 else if (!PyErr_Occurred()) {
890 PyObject *v = PyString_FromString(s);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000891 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000892 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000893 }
894 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000895 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) != 0)
896 PyErr_Clear();
897 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000898 }
899 }
900}