blob: c8b083e5f238ff46e7b23e554930cc452fae0939 [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 Rossumff7e83d1999-08-27 20:39:37 +000037#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum41498431999-01-07 22:09:51 +000038#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000039#endif /* DONT_HAVE_SYS_TYPES_H */
Guido van Rossum41498431999-01-07 22:09:51 +000040
Guido van Rossum685a38e1996-12-05 21:54:17 +000041#ifdef HAVE_UNISTD_H
42#include <unistd.h>
43#endif
44
Guido van Rossumb8199141997-05-06 15:23:24 +000045#ifdef MS_WIN32
46#define ftruncate _chsize
47#define fileno _fileno
48#define HAVE_FTRUNCATE
49#endif
50
Guido van Rossumf2044e11998-04-28 16:05:59 +000051#ifdef macintosh
52#ifdef USE_GUSI
53#define HAVE_FTRUNCATE
54#endif
55#endif
56
Guido van Rossum295d1711995-02-19 15:55:19 +000057#ifdef THINK_C
58#define HAVE_FOPENRF
59#endif
Jack Jansene08dea191995-04-23 22:12:47 +000060#ifdef __MWERKS__
61/* Mwerks fopen() doesn't always set errno */
62#define NO_FOPEN_ERRNO
63#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000064
Guido van Rossumc0b618a1997-05-02 03:12:38 +000065#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000066
Guido van Rossumff7e83d1999-08-27 20:39:37 +000067#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000068#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000069#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070
71typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000072 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000074 PyObject *f_name;
75 PyObject *f_mode;
76 int (*f_close) Py_PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000077 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000078 int f_binary; /* Flag which indicates whether the file is open
79 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000080} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081
82FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +000083PyFile_AsFile(f)
84 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000086 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000088 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000089 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090}
91
Guido van Rossumc0b618a1997-05-02 03:12:38 +000092PyObject *
93PyFile_Name(f)
94 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000095{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000096 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000097 return NULL;
98 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000099 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +0000100}
101
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000102PyObject *
103PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104 FILE *fp;
105 char *name;
106 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 if (f == NULL)
111 return NULL;
112 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113 f->f_name = PyString_FromString(name);
114 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000115 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000116 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +0000117 if (strchr(mode,'b') != NULL)
118 f->f_binary = 1;
119 else
120 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000122 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123 return NULL;
124 }
125 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000126 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127}
128
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000129PyObject *
130PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131 char *name, *mode;
132{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000133 extern int fclose Py_PROTO((FILE *));
134 PyFileObject *f;
135 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 if (f == NULL)
137 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000138#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000139 if (*mode == '*') {
140 FILE *fopenRF();
141 f->f_fp = fopenRF(name, mode+1);
142 }
143 else
144#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000145 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000146 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000147 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000148 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000149 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000150 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000151#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000152 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000153 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000154 PyErr_SetString(PyExc_IOError, "Cannot open file");
155 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000156 return NULL;
157 }
158#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000159 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000160 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 return NULL;
162 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000163 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164}
165
Guido van Rossumb6775db1994-08-01 11:34:53 +0000166void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000167PyFile_SetBufSize(f, bufsize)
168 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000169 int bufsize;
170{
171 if (bufsize >= 0) {
172#ifdef HAVE_SETVBUF
173 int type;
174 switch (bufsize) {
175 case 0:
176 type = _IONBF;
177 break;
178 case 1:
179 type = _IOLBF;
180 bufsize = BUFSIZ;
181 break;
182 default:
183 type = _IOFBF;
184 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000185 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
186 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000187#else /* !HAVE_SETVBUF */
188 if (bufsize <= 1)
189 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
190#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000191 }
192}
193
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000194static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000195err_closed()
196{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000197 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000198 return NULL;
199}
200
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201/* Methods */
202
203static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000204file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000207 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000208 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000209 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000210 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000211 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000212 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000213 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000214 }
215 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000216 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000217 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218 free((char *)f);
219}
220
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000222file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000223 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000224{
225 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000226 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 PyString_AsString(f->f_name),
229 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000230 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232}
233
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000235file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000236 PyFileObject *f;
237 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000239 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000243 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000244 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000245 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000246 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000247 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000248 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249 f->f_fp = NULL;
250 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000251 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000252 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000253 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000254 return PyInt_FromLong((long)sts);
255 Py_INCREF(Py_None);
256 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000257}
258
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000259static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000260file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000261 PyFileObject *f;
262 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000264 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000265 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000266 off_t offset;
267 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000268
Guido van Rossumd7297e61992-07-06 14:19:26 +0000269 if (f->f_fp == NULL)
270 return err_closed();
271 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000272 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000273 return NULL;
274#if !defined(HAVE_LARGEFILE_SUPPORT)
275 offset = PyInt_AsLong(offobj);
276#else
277 offset = PyLong_Check(offobj) ?
278 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
279#endif
280 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000281 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000282 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000283 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000284#if defined(HAVE_FSEEKO)
285 ret = fseeko(f->f_fp, offset, whence);
286#elif defined(HAVE_FSEEK64)
287 ret = fseek64(f->f_fp, offset, whence);
288#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000289 ret = fseek(f->f_fp, offset, whence);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000290#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000291 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000292 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000293 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000294 clearerr(f->f_fp);
295 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000296 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000297 Py_INCREF(Py_None);
298 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000299}
300
Guido van Rossumd7047b31995-01-02 19:07:15 +0000301#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000302static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000303file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000304 PyFileObject *f;
305 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000306{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000307 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000308 off_t newsize;
309 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000310
311 if (f->f_fp == NULL)
312 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000313 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000314 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000315 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000316 if (newsizeobj != NULL) {
317#if !defined(HAVE_LARGEFILE_SUPPORT)
318 newsize = PyInt_AsLong(newsizeobj);
319#else
320 newsize = PyLong_Check(newsizeobj) ?
321 PyLong_AsLongLong(newsizeobj) :
322 PyInt_AsLong(newsizeobj);
323#endif
324 if (PyErr_Occurred())
325 return NULL;
326 } else {
327 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000329 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000330#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
331 newsize = ftello(f->f_fp);
332#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
333 newsize = ftell64(f->f_fp);
334#else
335 newsize = ftell(f->f_fp);
336#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000337 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000338 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000339 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000340 clearerr(f->f_fp);
341 return NULL;
342 }
343 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000345 errno = 0;
346 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000348 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000350 errno = 0;
351 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000353 }
354 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000356 clearerr(f->f_fp);
357 return NULL;
358 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000359 Py_INCREF(Py_None);
360 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000361}
362#endif /* HAVE_FTRUNCATE */
363
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000364static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000365file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000366 PyFileObject *f;
367 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000368{
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000369 off_t offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000370 if (f->f_fp == NULL)
371 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000372 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000373 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000374 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000375 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000376#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
377 offset = ftello(f->f_fp);
378#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
379 offset = ftell64(f->f_fp);
380#else
Guido van Rossumce5ba841991-03-06 13:06:18 +0000381 offset = ftell(f->f_fp);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000382#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000384 if (offset == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000385 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000386 clearerr(f->f_fp);
387 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000388 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000389#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 return PyInt_FromLong(offset);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000391#else
392 return PyLong_FromLongLong(offset);
393#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000394}
395
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000396static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000397file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000398 PyFileObject *f;
399 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000400{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000401 if (f->f_fp == NULL)
402 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000403 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000404 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000405 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000406}
407
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000408static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000409file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000410 PyFileObject *f;
411 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000412{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000413 int res;
414
Guido van Rossumd7297e61992-07-06 14:19:26 +0000415 if (f->f_fp == NULL)
416 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000417 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000418 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000419 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000420 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000421 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000423 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000424 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000425 clearerr(f->f_fp);
426 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000427 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428 Py_INCREF(Py_None);
429 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000430}
431
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000433file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 PyFileObject *f;
435 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000436{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000437 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000438 if (f->f_fp == NULL)
439 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000440 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000441 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000443 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000444 Py_END_ALLOW_THREADS
445 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000446}
447
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000448/* We expect that fstat exists on most systems.
449 It's confirmed on Unix, Mac and Windows.
450 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
451#ifndef DONT_HAVE_FSTAT
452#define HAVE_FSTAT
453
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000454#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000455#include <sys/types.h>
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000456#endif
457
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000458#ifndef DONT_HAVE_SYS_STAT_H
459#include <sys/stat.h>
460#endif
461
462#endif /* DONT_HAVE_FSTAT */
463
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000464#if BUFSIZ < 8192
465#define SMALLCHUNK 8192
466#else
467#define SMALLCHUNK BUFSIZ
468#endif
469
Guido van Rossum3c259041999-01-14 19:00:14 +0000470#if SIZEOF_INT < 4
471#define BIGCHUNK (512 * 32)
472#else
473#define BIGCHUNK (512 * 1024)
474#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000475
476static size_t
477new_buffersize(f, currentsize)
478 PyFileObject *f;
479 size_t currentsize;
480{
481#ifdef HAVE_FSTAT
482 long pos, end;
483 struct stat st;
484 if (fstat(fileno(f->f_fp), &st) == 0) {
485 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000486 /* The following is not a bug: we really need to call lseek()
487 *and* ftell(). The reason is that some stdio libraries
488 mistakenly flush their buffer when ftell() is called and
489 the lseek() call it makes fails, thereby throwing away
490 data that cannot be recovered in any way. To avoid this,
491 we first test lseek(), and only call ftell() if lseek()
492 works. We can't use the lseek() value either, because we
493 need to take the amount of buffered data into account.
494 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000495 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
496 if (pos >= 0)
497 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000498 if (pos < 0)
499 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000500 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000501 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000502 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000503 }
504#endif
505 if (currentsize > SMALLCHUNK) {
506 /* Keep doubling until we reach BIGCHUNK;
507 then keep adding BIGCHUNK. */
508 if (currentsize <= BIGCHUNK)
509 return currentsize + currentsize;
510 else
511 return currentsize + BIGCHUNK;
512 }
513 return currentsize + SMALLCHUNK;
514}
515
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000516static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000517file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000518 PyFileObject *f;
519 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000520{
Guido van Rossum789a1611997-05-10 22:33:55 +0000521 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000522 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000524
Guido van Rossumd7297e61992-07-06 14:19:26 +0000525 if (f->f_fp == NULL)
526 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000527 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000528 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000529 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000530 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000531 else
532 buffersize = bytesrequested;
533 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000534 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000535 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000536 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000537 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000538 Py_BEGIN_ALLOW_THREADS
539 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000540 chunksize = fread(BUF(v) + bytesread, 1,
541 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000542 Py_END_ALLOW_THREADS
543 if (chunksize == 0) {
544 if (!ferror(f->f_fp))
545 break;
546 PyErr_SetFromErrno(PyExc_IOError);
547 clearerr(f->f_fp);
548 Py_DECREF(v);
549 return NULL;
550 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000551 bytesread += chunksize;
552 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000553 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000554 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000555 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000556 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000557 return NULL;
558 }
559 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000560 if (bytesread != buffersize)
561 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000562 return v;
563}
564
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000565static PyObject *
566file_readinto(f, args)
567 PyFileObject *f;
568 PyObject *args;
569{
570 char *ptr;
571 int ntodo, ndone, nnow;
572
573 if (f->f_fp == NULL)
574 return err_closed();
575 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
576 return NULL;
577 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000578 while (ntodo > 0) {
579 Py_BEGIN_ALLOW_THREADS
580 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000581 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000582 Py_END_ALLOW_THREADS
583 if (nnow == 0) {
584 if (!ferror(f->f_fp))
585 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000586 PyErr_SetFromErrno(PyExc_IOError);
587 clearerr(f->f_fp);
588 return NULL;
589 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000590 ndone += nnow;
591 ntodo -= nnow;
592 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000593 return PyInt_FromLong(ndone);
594}
595
596
Guido van Rossum0bd24411991-04-04 15:21:57 +0000597/* Internal routine to get a line.
598 Size argument interpretation:
599 > 0: max length;
600 = 0: read arbitrary line;
601 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000602*/
603
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000605getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000606 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000607 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000609 register FILE *fp;
610 register int c;
611 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000612 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000613 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000614
Guido van Rossumc10aa771992-07-31 12:42:38 +0000615 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000616 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000617 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000618 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000620 buf = BUF(v);
621 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000622
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000623 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000624 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000625 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000626 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000627 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000628 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000630 return NULL;
631 }
632 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000633 Py_DECREF(v);
634 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000635 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000636 return NULL;
637 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000638 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000639 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000640 }
641 if ((*buf++ = c) == '\n') {
642 if (n < 0)
643 buf--;
644 break;
645 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000646 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000647 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000648 break;
649 n1 = n2;
650 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000651 Py_BLOCK_THREADS
652 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000653 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000655 buf = BUF(v) + n1;
656 end = BUF(v) + n2;
657 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000659 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000660
Guido van Rossumce5ba841991-03-06 13:06:18 +0000661 n1 = buf - BUF(v);
662 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 return v;
665}
666
Guido van Rossum0bd24411991-04-04 15:21:57 +0000667/* External C interface */
668
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669PyObject *
670PyFile_GetLine(f, n)
671 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000672 int n;
673{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000674 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000675 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000676 return NULL;
677 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000678 if (!PyFile_Check(f)) {
679 PyObject *reader;
680 PyObject *args;
681 PyObject *result;
682 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000683 if (reader == NULL)
684 return NULL;
685 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000686 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000687 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000688 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000689 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000690 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000691 return NULL;
692 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000693 result = PyEval_CallObject(reader, args);
694 Py_DECREF(reader);
695 Py_DECREF(args);
696 if (result != NULL && !PyString_Check(result)) {
697 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000698 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000699 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000700 "object.readline() returned non-string");
701 }
702 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000703 char *s = PyString_AsString(result);
704 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000705 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000706 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000707 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000708 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000709 "EOF when reading a line");
710 }
711 else if (s[len-1] == '\n') {
712 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000713 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000714 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000715 PyObject *v;
716 v = PyString_FromStringAndSize(s,
717 len-1);
718 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000719 result = v;
720 }
721 }
722 }
723 return result;
724 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000725 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000726 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000727 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000728}
729
730/* Python method */
731
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000732static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000733file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000734 PyFileObject *f;
735 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000736{
Guido van Rossum789a1611997-05-10 22:33:55 +0000737 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000738
Guido van Rossumd7297e61992-07-06 14:19:26 +0000739 if (f->f_fp == NULL)
740 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000741 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000742 return NULL;
743 if (n == 0)
744 return PyString_FromString("");
745 if (n < 0)
746 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000747 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000748}
749
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000750static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000751file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000752 PyFileObject *f;
753 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000754{
Guido van Rossum789a1611997-05-10 22:33:55 +0000755 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000756 PyObject *list;
757 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000758 char small_buffer[SMALLCHUNK];
759 char *buffer = small_buffer;
760 size_t buffersize = SMALLCHUNK;
761 PyObject *big_buffer = NULL;
762 size_t nfilled = 0;
763 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000764 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000765 char *p, *q, *end;
766 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000767
Guido van Rossumd7297e61992-07-06 14:19:26 +0000768 if (f->f_fp == NULL)
769 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000770 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000771 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000772 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000773 return NULL;
774 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000775 Py_BEGIN_ALLOW_THREADS
776 errno = 0;
777 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
778 Py_END_ALLOW_THREADS
779 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000780 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000781 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000782 break;
783 PyErr_SetFromErrno(PyExc_IOError);
784 clearerr(f->f_fp);
785 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000786 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000787 list = NULL;
788 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000789 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000790 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000791 p = memchr(buffer+nfilled, '\n', nread);
792 if (p == NULL) {
793 /* Need a larger buffer to fit this line */
794 nfilled += nread;
795 buffersize *= 2;
796 if (big_buffer == NULL) {
797 /* Create the big buffer */
798 big_buffer = PyString_FromStringAndSize(
799 NULL, buffersize);
800 if (big_buffer == NULL)
801 goto error;
802 buffer = PyString_AS_STRING(big_buffer);
803 memcpy(buffer, small_buffer, nfilled);
804 }
805 else {
806 /* Grow the big buffer */
807 _PyString_Resize(&big_buffer, buffersize);
808 buffer = PyString_AS_STRING(big_buffer);
809 }
810 continue;
811 }
812 end = buffer+nfilled+nread;
813 q = buffer;
814 do {
815 /* Process complete lines */
816 p++;
817 line = PyString_FromStringAndSize(q, p-q);
818 if (line == NULL)
819 goto error;
820 err = PyList_Append(list, line);
821 Py_DECREF(line);
822 if (err != 0)
823 goto error;
824 q = p;
825 p = memchr(q, '\n', end-q);
826 } while (p != NULL);
827 /* Move the remaining incomplete line to the start */
828 nfilled = end-q;
829 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000830 if (sizehint > 0)
831 if (totalread >= (size_t)sizehint)
832 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000833 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000834 if (nfilled != 0) {
835 /* Partial last line */
836 line = PyString_FromStringAndSize(buffer, nfilled);
837 if (line == NULL)
838 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000839 if (sizehint > 0) {
840 /* Need to complete the last line */
841 PyObject *rest = getline(f, 0);
842 if (rest == NULL) {
843 Py_DECREF(line);
844 goto error;
845 }
846 PyString_Concat(&line, rest);
847 Py_DECREF(rest);
848 if (line == NULL)
849 goto error;
850 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000851 err = PyList_Append(list, line);
852 Py_DECREF(line);
853 if (err != 0)
854 goto error;
855 }
856 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000857 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000858 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000859 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000860 return list;
861}
862
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000863static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000864file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000865 PyFileObject *f;
866 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000867{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000868 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000869 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000870 if (f->f_fp == NULL)
871 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +0000872 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000873 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000874 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000875 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000876 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000877 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000878 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000879 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000880 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000881 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000882 return NULL;
883 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000884 Py_INCREF(Py_None);
885 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000886}
887
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000889file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890 PyFileObject *f;
891 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000892{
Guido van Rossumee70ad12000-03-13 16:27:06 +0000893#define CHUNKSIZE 1000
894 PyObject *list, *line;
895 PyObject *result;
896 int i, j, index, len, nwritten, islist;
897
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000898 if (f->f_fp == NULL)
899 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +0000900 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000901 PyErr_SetString(PyExc_TypeError,
Guido van Rossumee70ad12000-03-13 16:27:06 +0000902 "writelines() requires sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000903 return NULL;
904 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000905 islist = PyList_Check(args);
906
907 /* Strategy: slurp CHUNKSIZE lines into a private list,
908 checking that they are all strings, then write that list
909 without holding the interpreter lock, then come back for more. */
910 index = 0;
911 if (islist)
912 list = NULL;
913 else {
914 list = PyList_New(CHUNKSIZE);
915 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000916 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000917 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000918 result = NULL;
919
920 for (;;) {
921 if (islist) {
922 Py_XDECREF(list);
923 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
924 if (list == NULL)
925 return NULL;
926 j = PyList_GET_SIZE(list);
927 }
928 else {
929 for (j = 0; j < CHUNKSIZE; j++) {
930 line = PySequence_GetItem(args, index+j);
931 if (line == NULL) {
932 if (PyErr_ExceptionMatches(
933 PyExc_IndexError))
934 {
935 PyErr_Clear();
936 break;
937 }
938 /* Some other error occurred.
939 XXX We may lose some output. */
940 goto error;
941 }
942 if (!PyString_Check(line)) {
943 Py_DECREF(line);
944 PyErr_SetString(PyExc_TypeError,
945 "writelines() requires sequences of strings");
946 goto error;
947 }
948 PyList_SetItem(list, j, line);
949 }
950 }
951 if (j == 0)
952 break;
953
954 Py_BEGIN_ALLOW_THREADS
955 f->f_softspace = 0;
956 errno = 0;
957 for (i = 0; i < j; i++) {
958 line = PyList_GET_ITEM(list, i);
959 len = PyString_GET_SIZE(line);
960 nwritten = fwrite(PyString_AS_STRING(line),
961 1, len, f->f_fp);
962 if (nwritten != len) {
963 Py_BLOCK_THREADS
964 PyErr_SetFromErrno(PyExc_IOError);
965 clearerr(f->f_fp);
966 goto error;
967 }
968 }
969 Py_END_ALLOW_THREADS
970
971 if (j < CHUNKSIZE)
972 break;
973 index += CHUNKSIZE;
974 }
975
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000976 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +0000977 result = Py_None;
978 error:
979 Py_XDECREF(list);
980 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000981}
982
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000983static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000984 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000985 {"read", (PyCFunction)file_read, 1},
986 {"write", (PyCFunction)file_write, 0},
987 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +0000988 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000989#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +0000990 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000991#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000992 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000993 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000994 {"readlines", (PyCFunction)file_readlines, 1},
995 {"writelines", (PyCFunction)file_writelines, 0},
996 {"flush", (PyCFunction)file_flush, 0},
997 {"close", (PyCFunction)file_close, 0},
998 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000999 {NULL, NULL} /* sentinel */
1000};
1001
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001002#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001003
1004static struct memberlist file_memberlist[] = {
1005 {"softspace", T_INT, OFF(f_softspace)},
1006 {"mode", T_OBJECT, OFF(f_mode), RO},
1007 {"name", T_OBJECT, OFF(f_name), RO},
1008 /* getattr(f, "closed") is implemented without this table */
1009 {"closed", T_INT, 0, RO},
1010 {NULL} /* Sentinel */
1011};
1012
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +00001014file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001015 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001016 char *name;
1017{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001018 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001019
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001020 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001021 if (res != NULL)
1022 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001023 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001024 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001025 return PyInt_FromLong((long)(f->f_fp == 0));
1026 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001027}
1028
1029static int
1030file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001031 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001032 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001033 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001034{
1035 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001036 PyErr_SetString(PyExc_AttributeError,
1037 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001038 return -1;
1039 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001040 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001041}
1042
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001043PyTypeObject PyFile_Type = {
1044 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001045 0,
1046 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001047 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001048 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001049 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001050 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001051 (getattrfunc)file_getattr, /*tp_getattr*/
1052 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001053 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001054 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001055};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001056
1057/* Interface for the 'soft space' between print items. */
1058
1059int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001060PyFile_SoftSpace(f, newflag)
1061 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001062 int newflag;
1063{
1064 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001065 if (f == NULL) {
1066 /* Do nothing */
1067 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001068 else if (PyFile_Check(f)) {
1069 oldflag = ((PyFileObject *)f)->f_softspace;
1070 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001071 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001072 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001073 PyObject *v;
1074 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001075 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001076 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001077 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001078 if (PyInt_Check(v))
1079 oldflag = PyInt_AsLong(v);
1080 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001081 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001082 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001083 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001084 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001085 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001086 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1087 PyErr_Clear();
1088 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001089 }
1090 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001091 return oldflag;
1092}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001093
1094/* Interfaces to write objects/strings to file-like objects */
1095
1096int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001097PyFile_WriteObject(v, f, flags)
1098 PyObject *v;
1099 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001100 int flags;
1101{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001102 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001103 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001104 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001105 return -1;
1106 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001107 else if (PyFile_Check(f)) {
1108 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001109 if (fp == NULL) {
1110 err_closed();
1111 return -1;
1112 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001113 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001114 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001115 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001116 if (writer == NULL)
1117 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001118 if (flags & Py_PRINT_RAW)
1119 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001120 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001121 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001122 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001123 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001124 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001125 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001126 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001127 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001128 Py_DECREF(value);
1129 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001130 return -1;
1131 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001132 result = PyEval_CallObject(writer, args);
1133 Py_DECREF(args);
1134 Py_DECREF(value);
1135 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001136 if (result == NULL)
1137 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001138 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001139 return 0;
1140}
1141
Guido van Rossum27a60b11997-05-22 22:25:11 +00001142int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001143PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001144 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001145 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001146{
1147 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001148 /* Should be caused by a pre-existing error */
1149 if(!PyErr_Occurred())
1150 PyErr_SetString(PyExc_SystemError,
1151 "null file for PyFile_WriteString");
1152 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001153 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001154 else if (PyFile_Check(f)) {
1155 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001156 if (fp == NULL) {
1157 err_closed();
1158 return -1;
1159 }
1160 fputs(s, fp);
1161 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001162 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001163 else if (!PyErr_Occurred()) {
1164 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001165 int err;
1166 if (v == NULL)
1167 return -1;
1168 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1169 Py_DECREF(v);
1170 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001171 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001172 else
1173 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001174}