blob: cee41a10e0c2bd5d38495f82faf50053c4d4f705 [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 Rossum295d1711995-02-19 15:55:19 +000041#ifdef THINK_C
42#define HAVE_FOPENRF
43#endif
Jack Jansene08dea191995-04-23 22:12:47 +000044#ifdef __MWERKS__
45/* Mwerks fopen() doesn't always set errno */
46#define NO_FOPEN_ERRNO
47#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000048
Guido van Rossumc0b618a1997-05-02 03:12:38 +000049#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000050
Guido van Rossumf1dc5661993-07-05 10:31:29 +000051#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052
53typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000054 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000055 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000056 PyObject *f_name;
57 PyObject *f_mode;
58 int (*f_close) Py_PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000059 int f_softspace; /* Flag used by 'print' command */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000060} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061
62FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +000063PyFile_AsFile(f)
64 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000066 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000068 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000069 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070}
71
Guido van Rossumc0b618a1997-05-02 03:12:38 +000072PyObject *
73PyFile_Name(f)
74 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000075{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000076 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000077 return NULL;
78 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000079 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000080}
81
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082PyObject *
83PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084 FILE *fp;
85 char *name;
86 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000087 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000089 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090 if (f == NULL)
91 return NULL;
92 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000093 f->f_name = PyString_FromString(name);
94 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000095 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000096 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000098 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099 return NULL;
100 }
101 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000102 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103}
104
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000105PyObject *
106PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107 char *name, *mode;
108{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 extern int fclose Py_PROTO((FILE *));
110 PyFileObject *f;
111 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 if (f == NULL)
113 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000114#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000115 if (*mode == '*') {
116 FILE *fopenRF();
117 f->f_fp = fopenRF(name, mode+1);
118 }
119 else
120#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000121 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000122 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000123 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000124 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000125 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000126 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000127#ifdef NO_FOPEN_ERRNO
128 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000129 PyErr_SetString(PyExc_IOError, "Cannot open file");
130 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000131 return NULL;
132 }
133#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000134 PyErr_SetFromErrno(PyExc_IOError);
135 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 return NULL;
137 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000138 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139}
140
Guido van Rossumb6775db1994-08-01 11:34:53 +0000141void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000142PyFile_SetBufSize(f, bufsize)
143 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000144 int bufsize;
145{
146 if (bufsize >= 0) {
147#ifdef HAVE_SETVBUF
148 int type;
149 switch (bufsize) {
150 case 0:
151 type = _IONBF;
152 break;
153 case 1:
154 type = _IOLBF;
155 bufsize = BUFSIZ;
156 break;
157 default:
158 type = _IOFBF;
159 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000160 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
161 type, bufsize);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162#endif /* HAVE_SETVBUF */
163 }
164}
165
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000166static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000167err_closed()
168{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000169 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000170 return NULL;
171}
172
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173/* Methods */
174
175static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000176file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000177 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000179 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000180 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000181 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000182 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000183 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184 if (f->f_name != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000185 Py_DECREF(f->f_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186 if (f->f_mode != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000187 Py_DECREF(f->f_mode);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188 free((char *)f);
189}
190
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000191static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000192file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000193 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194{
195 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000196 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000198 PyString_AsString(f->f_name),
199 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000200 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000201 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202}
203
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000205file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000206 PyFileObject *f;
207 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000209 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000210 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000213 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000214 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000215 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000216 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000217 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000218 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219 f->f_fp = NULL;
220 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000221 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000222 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000223 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224 return PyInt_FromLong((long)sts);
225 Py_INCREF(Py_None);
226 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227}
228
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000229static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000230file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 PyFileObject *f;
232 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000234 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000235 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000236 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000237
Guido van Rossumd7297e61992-07-06 14:19:26 +0000238 if (f->f_fp == NULL)
239 return err_closed();
240 whence = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000241 if (!PyArg_Parse(args, "l", &offset)) {
242 PyErr_Clear();
243 if (!PyArg_Parse(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000244 return NULL;
245 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000246 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000247 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000248 ret = fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000249 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000250 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000251 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000252 clearerr(f->f_fp);
253 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000254 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000255 Py_INCREF(Py_None);
256 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000257}
258
Guido van Rossumd7047b31995-01-02 19:07:15 +0000259#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000260static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000261file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000262 PyFileObject *f;
263 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000264{
265 long newsize;
266 int ret;
267
268 if (f->f_fp == NULL)
269 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000270 if (!PyArg_Parse(args, "l", &newsize)) {
271 PyErr_Clear();
272 if (!PyArg_NoArgs(args))
Guido van Rossumd7047b31995-01-02 19:07:15 +0000273 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000274 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000275 errno = 0;
276 newsize = ftell(f->f_fp); /* default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000277 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000278 if (newsize == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000279 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000280 clearerr(f->f_fp);
281 return NULL;
282 }
283 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000284 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000285 errno = 0;
286 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000287 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000288 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000289 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000290 errno = 0;
291 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000292 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000293 }
294 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000295 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000296 clearerr(f->f_fp);
297 return NULL;
298 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000299 Py_INCREF(Py_None);
300 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000301}
302#endif /* HAVE_FTRUNCATE */
303
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000304static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000305file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 PyFileObject *f;
307 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000308{
309 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000310 if (f->f_fp == NULL)
311 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000312 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000315 errno = 0;
316 offset = ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000317 Py_END_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000318 if (offset == -1L) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000319 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000320 clearerr(f->f_fp);
321 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000322 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323 return PyInt_FromLong(offset);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000324}
325
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000326static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000327file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 PyFileObject *f;
329 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000330{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000331 if (f->f_fp == NULL)
332 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000333 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000334 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000336}
337
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000338static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000339file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340 PyFileObject *f;
341 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000342{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000343 int res;
344
Guido van Rossumd7297e61992-07-06 14:19:26 +0000345 if (f->f_fp == NULL)
346 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000350 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000351 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000353 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000355 clearerr(f->f_fp);
356 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000357 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358 Py_INCREF(Py_None);
359 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000360}
361
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000362static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000363file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000364 PyFileObject *f;
365 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000366{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000367 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000368 if (f->f_fp == NULL)
369 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000370 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000371 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000372 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000373 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000374 Py_END_ALLOW_THREADS
375 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000376}
377
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000378static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000379file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 PyFileObject *f;
381 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000382{
383 int n, n1, n2, n3;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000384 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000385
Guido van Rossumd7297e61992-07-06 14:19:26 +0000386 if (f->f_fp == NULL)
387 return err_closed();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000388 if (args == NULL)
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000389 n = -1;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000390 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000391 if (!PyArg_Parse(args, "i", &n))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000392 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000393 }
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000394 n2 = n >= 0 ? n : BUFSIZ;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000395 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000396 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000398 n1 = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000399 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000400 for (;;) {
401 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
402 /* XXX Error check? */
403 if (n3 == 0)
404 break;
405 n1 += n3;
406 if (n1 == n)
407 break;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000408 if (n < 0) {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000409 n2 = n1 + BUFSIZ;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000410 Py_BLOCK_THREADS
411 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000412 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000413 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000414 }
415 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000416 Py_END_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000417 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000418 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000419 return v;
420}
421
Guido van Rossum0bd24411991-04-04 15:21:57 +0000422/* Internal routine to get a line.
423 Size argument interpretation:
424 > 0: max length;
425 = 0: read arbitrary line;
426 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000427*/
428
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000429static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000430getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000431 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000432 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000433{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000434 register FILE *fp;
435 register int c;
436 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000437 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000438 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000439
Guido van Rossumc10aa771992-07-31 12:42:38 +0000440 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000441 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000443 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000445 buf = BUF(v);
446 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000447
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000448 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000449 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000450 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000451 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452 if (PyErr_CheckSignals()) {
453 Py_BLOCK_THREADS
454 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000455 return NULL;
456 }
457 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000458 Py_BLOCK_THREADS
459 Py_DECREF(v);
460 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000461 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000462 return NULL;
463 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000464 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000465 }
466 if ((*buf++ = c) == '\n') {
467 if (n < 0)
468 buf--;
469 break;
470 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000471 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000472 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000473 break;
474 n1 = n2;
475 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000476 Py_BLOCK_THREADS
477 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000478 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000479 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000480 buf = BUF(v) + n1;
481 end = BUF(v) + n2;
482 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000484 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000485
Guido van Rossumce5ba841991-03-06 13:06:18 +0000486 n1 = buf - BUF(v);
487 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000488 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489 return v;
490}
491
Guido van Rossum0bd24411991-04-04 15:21:57 +0000492/* External C interface */
493
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000494PyObject *
495PyFile_GetLine(f, n)
496 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000497 int n;
498{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000499 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000500 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000501 return NULL;
502 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000503 if (!PyFile_Check(f)) {
504 PyObject *reader;
505 PyObject *args;
506 PyObject *result;
507 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000508 if (reader == NULL)
509 return NULL;
510 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000511 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000512 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000513 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000514 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000515 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000516 return NULL;
517 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000518 result = PyEval_CallObject(reader, args);
519 Py_DECREF(reader);
520 Py_DECREF(args);
521 if (result != NULL && !PyString_Check(result)) {
522 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000523 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000524 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000525 "object.readline() returned non-string");
526 }
527 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000528 char *s = PyString_AsString(result);
529 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000530 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000531 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000532 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000533 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000534 "EOF when reading a line");
535 }
536 else if (s[len-1] == '\n') {
537 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000538 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000539 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000540 PyObject *v;
541 v = PyString_FromStringAndSize(s,
542 len-1);
543 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000544 result = v;
545 }
546 }
547 }
548 return result;
549 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000550 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000551 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000553}
554
555/* Python method */
556
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000558file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 PyFileObject *f;
560 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000561{
562 int n;
563
Guido van Rossumd7297e61992-07-06 14:19:26 +0000564 if (f->f_fp == NULL)
565 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000566 if (args == NULL)
567 n = 0; /* Unlimited */
568 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000569 if (!PyArg_Parse(args, "i", &n))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000570 return NULL;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000571 if (n == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000572 return PyString_FromString("");
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000573 if (n < 0)
574 n = 0;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000575 }
576
Guido van Rossum51415a71992-03-27 17:23:38 +0000577 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000578}
579
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000580static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000581file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000582 PyFileObject *f;
583 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000584{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000585 PyObject *list;
586 PyObject *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000587
Guido van Rossumd7297e61992-07-06 14:19:26 +0000588 if (f->f_fp == NULL)
589 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000590 if (!PyArg_NoArgs(args))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000591 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000593 return NULL;
594 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000595 line = getline(f, 0);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000596 if (line != NULL && PyString_Size(line) == 0) {
597 Py_DECREF(line);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000598 break;
599 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 if (line == NULL || PyList_Append(list, line) != 0) {
601 Py_DECREF(list);
602 Py_XDECREF(line);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000603 return NULL;
604 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000605 Py_DECREF(line);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000606 }
607 return list;
608}
609
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000610static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000611file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000612 PyFileObject *f;
613 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000615 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000616 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000617 if (f->f_fp == NULL)
618 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000619 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000620 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000621 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000622 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000623 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000624 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000626 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000628 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000629 return NULL;
630 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000631 Py_INCREF(Py_None);
632 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000633}
634
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000635static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000636file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000637 PyFileObject *f;
638 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000639{
640 int i, n;
641 if (f->f_fp == NULL)
642 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000643 if (args == NULL || !PyList_Check(args)) {
644 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000645 "writelines() requires list of strings");
646 return NULL;
647 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000648 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000649 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000650 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000651 errno = 0;
652 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000653 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000654 int len;
655 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000656 if (!PyString_Check(line)) {
657 Py_BLOCK_THREADS
658 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000659 "writelines() requires list of strings");
660 return NULL;
661 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000662 len = PyString_Size(line);
663 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000664 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000665 Py_BLOCK_THREADS
666 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000667 clearerr(f->f_fp);
668 return NULL;
669 }
670 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671 Py_END_ALLOW_THREADS
672 Py_INCREF(Py_None);
673 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000674}
675
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000676static PyMethodDef file_methods[] = {
677 {"close", (PyCFunction)file_close, 0},
678 {"flush", (PyCFunction)file_flush, 0},
679 {"fileno", (PyCFunction)file_fileno, 0},
680 {"isatty", (PyCFunction)file_isatty, 0},
681 {"read", (PyCFunction)file_read, 0},
682 {"readline", (PyCFunction)file_readline, 0},
683 {"readlines", (PyCFunction)file_readlines, 0},
684 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000685#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000686 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000687#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000688 {"tell", (PyCFunction)file_tell, 0},
689 {"write", (PyCFunction)file_write, 0},
690 {"writelines", (PyCFunction)file_writelines, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691 {NULL, NULL} /* sentinel */
692};
693
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000694#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000695
696static struct memberlist file_memberlist[] = {
697 {"softspace", T_INT, OFF(f_softspace)},
698 {"mode", T_OBJECT, OFF(f_mode), RO},
699 {"name", T_OBJECT, OFF(f_name), RO},
700 /* getattr(f, "closed") is implemented without this table */
701 {"closed", T_INT, 0, RO},
702 {NULL} /* Sentinel */
703};
704
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000705static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000706file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000707 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000708 char *name;
709{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000710 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000711
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000712 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000713 if (res != NULL)
714 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000715 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000716 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000717 return PyInt_FromLong((long)(f->f_fp == 0));
718 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000719}
720
721static int
722file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000723 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000724 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000725 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000726{
727 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000728 PyErr_SetString(PyExc_AttributeError,
729 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000730 return -1;
731 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000732 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000733}
734
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000735PyTypeObject PyFile_Type = {
736 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000737 0,
738 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000739 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000741 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000742 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000743 (getattrfunc)file_getattr, /*tp_getattr*/
744 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000745 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000746 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000747};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000748
749/* Interface for the 'soft space' between print items. */
750
751int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000752PyFile_SoftSpace(f, newflag)
753 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000754 int newflag;
755{
756 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000757 if (f == NULL) {
758 /* Do nothing */
759 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000760 else if (PyFile_Check(f)) {
761 oldflag = ((PyFileObject *)f)->f_softspace;
762 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000763 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000764 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000765 PyObject *v;
766 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000767 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000768 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000769 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000770 if (PyInt_Check(v))
771 oldflag = PyInt_AsLong(v);
772 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000773 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000774 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000775 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000776 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000777 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000778 if (PyObject_SetAttrString(f, "softspace", v) != 0)
779 PyErr_Clear();
780 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000781 }
782 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000783 return oldflag;
784}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000785
786/* Interfaces to write objects/strings to file-like objects */
787
788int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000789PyFile_WriteObject(v, f, flags)
790 PyObject *v;
791 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000792 int flags;
793{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000794 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000795 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000796 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000797 return -1;
798 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000799 else if (PyFile_Check(f)) {
800 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000801 if (fp == NULL) {
802 err_closed();
803 return -1;
804 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000805 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000806 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000807 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000808 if (writer == NULL)
809 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000810 if (flags & Py_PRINT_RAW)
811 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000812 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000813 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000814 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000815 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +0000816 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000817 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000818 args = Py_BuildValue("(O)", value);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000819 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000820 Py_DECREF(value);
821 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000822 return -1;
823 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000824 result = PyEval_CallObject(writer, args);
825 Py_DECREF(args);
826 Py_DECREF(value);
827 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000828 if (result == NULL)
829 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000830 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000831 return 0;
832}
833
834void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000835PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000836 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000837 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000838{
839 if (f == NULL) {
840 /* Do nothing */
841 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000842 else if (PyFile_Check(f)) {
843 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000844 if (fp != NULL)
845 fputs(s, fp);
846 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000847 else if (!PyErr_Occurred()) {
848 PyObject *v = PyString_FromString(s);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000849 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000850 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000851 }
852 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000853 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) != 0)
854 PyErr_Clear();
855 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000856 }
857 }
858}