blob: a4b1d4baa6eda9b12048e5db8a1e2cfe32f94ca7 [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 Rossumfdf95dd1997-05-05 22:15:02 +0000422static PyObject *
423file_readinto(f, args)
424 PyFileObject *f;
425 PyObject *args;
426{
427 char *ptr;
428 int ntodo, ndone, nnow;
429
430 if (f->f_fp == NULL)
431 return err_closed();
432 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
433 return NULL;
434 ndone = 0;
435 /*
436 ** XXXX Is this correct? Other threads may see partially-completed
437 ** reads if they look at the object we're reading into...
438 */
439 Py_BEGIN_ALLOW_THREADS
440 while(ntodo > 0) {
441 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
442 if (nnow < 0 ) {
443 PyErr_SetFromErrno(PyExc_IOError);
444 clearerr(f->f_fp);
445 return NULL;
446 }
447 if (nnow == 0)
448 break;
449 ndone += nnow;
450 ntodo -= nnow;
451 }
452 Py_END_ALLOW_THREADS
453 return PyInt_FromLong(ndone);
454}
455
456
Guido van Rossum0bd24411991-04-04 15:21:57 +0000457/* Internal routine to get a line.
458 Size argument interpretation:
459 > 0: max length;
460 = 0: read arbitrary line;
461 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000462*/
463
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000464static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000465getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000466 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000467 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000468{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000469 register FILE *fp;
470 register int c;
471 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000472 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000473 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000474
Guido van Rossumc10aa771992-07-31 12:42:38 +0000475 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000476 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000477 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000478 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000480 buf = BUF(v);
481 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000482
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000483 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000484 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000485 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000486 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000487 if (PyErr_CheckSignals()) {
488 Py_BLOCK_THREADS
489 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000490 return NULL;
491 }
492 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000493 Py_BLOCK_THREADS
494 Py_DECREF(v);
495 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000496 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000497 return NULL;
498 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000499 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000500 }
501 if ((*buf++ = c) == '\n') {
502 if (n < 0)
503 buf--;
504 break;
505 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000506 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000507 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000508 break;
509 n1 = n2;
510 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000511 Py_BLOCK_THREADS
512 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000513 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000514 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000515 buf = BUF(v) + n1;
516 end = BUF(v) + n2;
517 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000518 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000519 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000520
Guido van Rossumce5ba841991-03-06 13:06:18 +0000521 n1 = buf - BUF(v);
522 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000524 return v;
525}
526
Guido van Rossum0bd24411991-04-04 15:21:57 +0000527/* External C interface */
528
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000529PyObject *
530PyFile_GetLine(f, n)
531 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000532 int n;
533{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000534 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000535 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000536 return NULL;
537 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000538 if (!PyFile_Check(f)) {
539 PyObject *reader;
540 PyObject *args;
541 PyObject *result;
542 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000543 if (reader == NULL)
544 return NULL;
545 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000546 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000547 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000548 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000549 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000550 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000551 return NULL;
552 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000553 result = PyEval_CallObject(reader, args);
554 Py_DECREF(reader);
555 Py_DECREF(args);
556 if (result != NULL && !PyString_Check(result)) {
557 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000558 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000560 "object.readline() returned non-string");
561 }
562 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000563 char *s = PyString_AsString(result);
564 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000565 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000566 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000567 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000569 "EOF when reading a line");
570 }
571 else if (s[len-1] == '\n') {
572 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000573 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000574 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000575 PyObject *v;
576 v = PyString_FromStringAndSize(s,
577 len-1);
578 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000579 result = v;
580 }
581 }
582 }
583 return result;
584 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000585 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000586 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000587 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000588}
589
590/* Python method */
591
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000592static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000593file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000594 PyFileObject *f;
595 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000596{
597 int n;
598
Guido van Rossumd7297e61992-07-06 14:19:26 +0000599 if (f->f_fp == NULL)
600 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000601 if (args == NULL)
602 n = 0; /* Unlimited */
603 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 if (!PyArg_Parse(args, "i", &n))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000605 return NULL;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000606 if (n == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 return PyString_FromString("");
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000608 if (n < 0)
609 n = 0;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000610 }
611
Guido van Rossum51415a71992-03-27 17:23:38 +0000612 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000613}
614
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000615static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000616file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000617 PyFileObject *f;
618 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000619{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000620 PyObject *list;
621 PyObject *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000622
Guido van Rossumd7297e61992-07-06 14:19:26 +0000623 if (f->f_fp == NULL)
624 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 if (!PyArg_NoArgs(args))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000626 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000628 return NULL;
629 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000630 line = getline(f, 0);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000631 if (line != NULL && PyString_Size(line) == 0) {
632 Py_DECREF(line);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000633 break;
634 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000635 if (line == NULL || PyList_Append(list, line) != 0) {
636 Py_DECREF(list);
637 Py_XDECREF(line);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000638 return NULL;
639 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000640 Py_DECREF(line);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000641 }
642 return list;
643}
644
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000645static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000646file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000647 PyFileObject *f;
648 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000649{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000650 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000651 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000652 if (f->f_fp == NULL)
653 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000655 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000656 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000657 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000659 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000660 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000661 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000662 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000663 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 return NULL;
665 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000666 Py_INCREF(Py_None);
667 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000668}
669
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000670static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000671file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000672 PyFileObject *f;
673 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000674{
675 int i, n;
676 if (f->f_fp == NULL)
677 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000678 if (args == NULL || !PyList_Check(args)) {
679 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000680 "writelines() requires list of strings");
681 return NULL;
682 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000683 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000684 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000685 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000686 errno = 0;
687 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000688 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000689 int len;
690 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000691 if (!PyString_Check(line)) {
692 Py_BLOCK_THREADS
693 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000694 "writelines() requires list of strings");
695 return NULL;
696 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000697 len = PyString_Size(line);
698 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000699 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000700 Py_BLOCK_THREADS
701 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000702 clearerr(f->f_fp);
703 return NULL;
704 }
705 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000706 Py_END_ALLOW_THREADS
707 Py_INCREF(Py_None);
708 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000709}
710
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000711static PyMethodDef file_methods[] = {
712 {"close", (PyCFunction)file_close, 0},
713 {"flush", (PyCFunction)file_flush, 0},
714 {"fileno", (PyCFunction)file_fileno, 0},
715 {"isatty", (PyCFunction)file_isatty, 0},
716 {"read", (PyCFunction)file_read, 0},
717 {"readline", (PyCFunction)file_readline, 0},
718 {"readlines", (PyCFunction)file_readlines, 0},
719 {"seek", (PyCFunction)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000720#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000721 {"truncate", (PyCFunction)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000722#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000723 {"tell", (PyCFunction)file_tell, 0},
724 {"write", (PyCFunction)file_write, 0},
725 {"writelines", (PyCFunction)file_writelines, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000726 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000727 {NULL, NULL} /* sentinel */
728};
729
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000730#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000731
732static struct memberlist file_memberlist[] = {
733 {"softspace", T_INT, OFF(f_softspace)},
734 {"mode", T_OBJECT, OFF(f_mode), RO},
735 {"name", T_OBJECT, OFF(f_name), RO},
736 /* getattr(f, "closed") is implemented without this table */
737 {"closed", T_INT, 0, RO},
738 {NULL} /* Sentinel */
739};
740
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000741static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000742file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000743 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000744 char *name;
745{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000746 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000747
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000748 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000749 if (res != NULL)
750 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000751 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000752 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000753 return PyInt_FromLong((long)(f->f_fp == 0));
754 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000755}
756
757static int
758file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000759 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000760 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000761 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000762{
763 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000764 PyErr_SetString(PyExc_AttributeError,
765 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000766 return -1;
767 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000768 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000769}
770
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000771PyTypeObject PyFile_Type = {
772 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000773 0,
774 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000775 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000777 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000778 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000779 (getattrfunc)file_getattr, /*tp_getattr*/
780 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000781 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000782 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000783};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000784
785/* Interface for the 'soft space' between print items. */
786
787int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000788PyFile_SoftSpace(f, newflag)
789 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000790 int newflag;
791{
792 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000793 if (f == NULL) {
794 /* Do nothing */
795 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000796 else if (PyFile_Check(f)) {
797 oldflag = ((PyFileObject *)f)->f_softspace;
798 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000799 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000800 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000801 PyObject *v;
802 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000803 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000804 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000805 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000806 if (PyInt_Check(v))
807 oldflag = PyInt_AsLong(v);
808 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000809 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000810 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000811 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000812 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000813 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000814 if (PyObject_SetAttrString(f, "softspace", v) != 0)
815 PyErr_Clear();
816 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000817 }
818 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000819 return oldflag;
820}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000821
822/* Interfaces to write objects/strings to file-like objects */
823
824int
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000825PyFile_WriteObject(v, f, flags)
826 PyObject *v;
827 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000828 int flags;
829{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000830 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000831 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000832 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000833 return -1;
834 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000835 else if (PyFile_Check(f)) {
836 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000837 if (fp == NULL) {
838 err_closed();
839 return -1;
840 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000841 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000842 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000843 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000844 if (writer == NULL)
845 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000846 if (flags & Py_PRINT_RAW)
847 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000848 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000849 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000850 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000851 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +0000852 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000853 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000854 args = Py_BuildValue("(O)", value);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000855 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000856 Py_DECREF(value);
857 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000858 return -1;
859 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000860 result = PyEval_CallObject(writer, args);
861 Py_DECREF(args);
862 Py_DECREF(value);
863 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000864 if (result == NULL)
865 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000866 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000867 return 0;
868}
869
870void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000871PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000872 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000873 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000874{
875 if (f == NULL) {
876 /* Do nothing */
877 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000878 else if (PyFile_Check(f)) {
879 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000880 if (fp != NULL)
881 fputs(s, fp);
882 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000883 else if (!PyErr_Occurred()) {
884 PyObject *v = PyString_FromString(s);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000885 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000886 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000887 }
888 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000889 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) != 0)
890 PyErr_Clear();
891 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000892 }
893 }
894}