blob: 99c0dd5e2bcd8146dd52a9913209dd383b29876a [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 Rossumeceebb82000-06-28 20:57:07 +000041/* We expect that fstat exists on most systems.
42 It's confirmed on Unix, Mac and Windows.
43 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
44#ifndef DONT_HAVE_FSTAT
45#define HAVE_FSTAT
46
47#ifndef DONT_HAVE_SYS_TYPES_H
48#include <sys/types.h>
49#endif
50
51#ifndef DONT_HAVE_SYS_STAT_H
52#include <sys/stat.h>
53#else
54#ifdef HAVE_STAT_H
55#include <stat.h>
56#endif
57#endif
58
59#endif /* DONT_HAVE_FSTAT */
60
Guido van Rossum685a38e1996-12-05 21:54:17 +000061#ifdef HAVE_UNISTD_H
62#include <unistd.h>
63#endif
64
Guido van Rossumb8199141997-05-06 15:23:24 +000065#ifdef MS_WIN32
66#define ftruncate _chsize
67#define fileno _fileno
68#define HAVE_FTRUNCATE
69#endif
70
Guido van Rossumf2044e11998-04-28 16:05:59 +000071#ifdef macintosh
72#ifdef USE_GUSI
73#define HAVE_FTRUNCATE
74#endif
75#endif
76
Jack Jansene08dea191995-04-23 22:12:47 +000077#ifdef __MWERKS__
78/* Mwerks fopen() doesn't always set errno */
79#define NO_FOPEN_ERRNO
80#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000081
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000083
Guido van Rossumff7e83d1999-08-27 20:39:37 +000084#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000085#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000086#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087
88typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000089 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091 PyObject *f_name;
92 PyObject *f_mode;
93 int (*f_close) Py_PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000094 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000095 int f_binary; /* Flag which indicates whether the file is open
96 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000097} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098
99FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000100PyFile_AsFile(f)
101 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000103 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000105 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000106 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107}
108
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109PyObject *
110PyFile_Name(f)
111 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +0000112{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +0000114 return NULL;
115 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000116 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +0000117}
118
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000119PyObject *
120PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 FILE *fp;
122 char *name;
123 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000124 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000126 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 if (f == NULL)
128 return NULL;
129 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000130 f->f_name = PyString_FromString(name);
131 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000132 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000133 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +0000134 if (strchr(mode,'b') != NULL)
135 f->f_binary = 1;
136 else
137 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000138 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000139 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000140 return NULL;
141 }
142 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000143 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144}
145
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000146PyObject *
147PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148 char *name, *mode;
149{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000150 extern int fclose Py_PROTO((FILE *));
151 PyFileObject *f;
152 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 if (f == NULL)
154 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000155#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000156 if (*mode == '*') {
157 FILE *fopenRF();
158 f->f_fp = fopenRF(name, mode+1);
159 }
160 else
161#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000162 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000163 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000164 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000165 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000166 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000167 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000168#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000169 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000170 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000171 PyErr_SetString(PyExc_IOError, "Cannot open file");
172 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000173 return NULL;
174 }
175#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000176 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000177 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 return NULL;
179 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000180 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181}
182
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000184PyFile_SetBufSize(f, bufsize)
185 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186 int bufsize;
187{
188 if (bufsize >= 0) {
189#ifdef HAVE_SETVBUF
190 int type;
191 switch (bufsize) {
192 case 0:
193 type = _IONBF;
194 break;
195 case 1:
196 type = _IOLBF;
197 bufsize = BUFSIZ;
198 break;
199 default:
200 type = _IOFBF;
201 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000202 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
203 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000204#else /* !HAVE_SETVBUF */
205 if (bufsize <= 1)
206 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
207#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208 }
209}
210
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000211static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000212err_closed()
213{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000214 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000215 return NULL;
216}
217
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218/* Methods */
219
220static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000221file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000222 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000224 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000225 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000226 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000227 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000228 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000229 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000231 }
232 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000234 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000235 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236}
237
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000238static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000239file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241{
242 char buf[300];
Fred Drakea44d3532000-06-30 15:01:00 +0000243 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000244 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000245 PyString_AsString(f->f_name),
246 PyString_AsString(f->f_mode),
Fred Drakea44d3532000-06-30 15:01:00 +0000247 f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249}
250
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000251static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000252file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000253 PyFileObject *f;
254 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000255{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000256 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000257 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000258 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000260 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000261 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000262 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000263 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000264 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000265 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000266 f->f_fp = NULL;
267 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000268 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000269 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000270 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000271 return PyInt_FromLong((long)sts);
272 Py_INCREF(Py_None);
273 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274}
275
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000276static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000277file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000278 PyFileObject *f;
279 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000281 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000282 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000283 off_t offset;
284 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000285
Guido van Rossumd7297e61992-07-06 14:19:26 +0000286 if (f->f_fp == NULL)
287 return err_closed();
288 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000289 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000290 return NULL;
291#if !defined(HAVE_LARGEFILE_SUPPORT)
292 offset = PyInt_AsLong(offobj);
293#else
294 offset = PyLong_Check(offobj) ?
295 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
296#endif
297 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000298 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000299 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000300 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000301#if defined(HAVE_FSEEKO)
302 ret = fseeko(f->f_fp, offset, whence);
303#elif defined(HAVE_FSEEK64)
304 ret = fseek64(f->f_fp, offset, whence);
305#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000306 ret = fseek(f->f_fp, offset, whence);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000307#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000308 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000309 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000311 clearerr(f->f_fp);
312 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000313 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314 Py_INCREF(Py_None);
315 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000316}
317
Guido van Rossumd7047b31995-01-02 19:07:15 +0000318#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000319static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000320file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000321 PyFileObject *f;
322 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000323{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000324 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000325 off_t newsize;
326 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000327
328 if (f->f_fp == NULL)
329 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000330 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000331 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000332 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000333 if (newsizeobj != NULL) {
334#if !defined(HAVE_LARGEFILE_SUPPORT)
335 newsize = PyInt_AsLong(newsizeobj);
336#else
337 newsize = PyLong_Check(newsizeobj) ?
338 PyLong_AsLongLong(newsizeobj) :
339 PyInt_AsLong(newsizeobj);
340#endif
341 if (PyErr_Occurred())
342 return NULL;
343 } else {
344 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000345 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000346 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000347#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
348 newsize = ftello(f->f_fp);
349#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
350 newsize = ftell64(f->f_fp);
351#else
352 newsize = ftell(f->f_fp);
353#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000355 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000357 clearerr(f->f_fp);
358 return NULL;
359 }
360 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000361 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000362 errno = 0;
363 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000364 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000365 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000366 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000367 errno = 0;
368 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000369 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000370 }
371 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000372 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000373 clearerr(f->f_fp);
374 return NULL;
375 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000376 Py_INCREF(Py_None);
377 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000378}
379#endif /* HAVE_FTRUNCATE */
380
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000382file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383 PyFileObject *f;
384 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000385{
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000386 off_t offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000387 if (f->f_fp == NULL)
388 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000390 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000391 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000392 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000393#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
394 offset = ftello(f->f_fp);
395#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
396 offset = ftell64(f->f_fp);
397#else
Guido van Rossumce5ba841991-03-06 13:06:18 +0000398 offset = ftell(f->f_fp);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000399#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000400 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000401 if (offset == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000402 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000403 clearerr(f->f_fp);
404 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000405 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000406#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000407 return PyInt_FromLong(offset);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000408#else
409 return PyLong_FromLongLong(offset);
410#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000411}
412
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000413static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000414file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415 PyFileObject *f;
416 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000417{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000418 if (f->f_fp == NULL)
419 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000420 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000421 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000423}
424
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000425static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000426file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000427 PyFileObject *f;
428 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000429{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000430 int res;
431
Guido van Rossumd7297e61992-07-06 14:19:26 +0000432 if (f->f_fp == NULL)
433 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000435 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000436 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000437 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000438 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000439 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000440 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000441 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000442 clearerr(f->f_fp);
443 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000444 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000445 Py_INCREF(Py_None);
446 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000447}
448
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000449static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000450file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000451 PyFileObject *f;
452 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000453{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000454 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000455 if (f->f_fp == NULL)
456 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000458 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000459 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000460 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000461 Py_END_ALLOW_THREADS
462 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000463}
464
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000465
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000466#if BUFSIZ < 8192
467#define SMALLCHUNK 8192
468#else
469#define SMALLCHUNK BUFSIZ
470#endif
471
Guido van Rossum3c259041999-01-14 19:00:14 +0000472#if SIZEOF_INT < 4
473#define BIGCHUNK (512 * 32)
474#else
475#define BIGCHUNK (512 * 1024)
476#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000477
478static size_t
479new_buffersize(f, currentsize)
480 PyFileObject *f;
481 size_t currentsize;
482{
483#ifdef HAVE_FSTAT
484 long pos, end;
485 struct stat st;
486 if (fstat(fileno(f->f_fp), &st) == 0) {
487 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000488 /* The following is not a bug: we really need to call lseek()
489 *and* ftell(). The reason is that some stdio libraries
490 mistakenly flush their buffer when ftell() is called and
491 the lseek() call it makes fails, thereby throwing away
492 data that cannot be recovered in any way. To avoid this,
493 we first test lseek(), and only call ftell() if lseek()
494 works. We can't use the lseek() value either, because we
495 need to take the amount of buffered data into account.
496 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000497 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
498 if (pos >= 0)
499 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000500 if (pos < 0)
501 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000502 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000503 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000504 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000505 }
506#endif
507 if (currentsize > SMALLCHUNK) {
508 /* Keep doubling until we reach BIGCHUNK;
509 then keep adding BIGCHUNK. */
510 if (currentsize <= BIGCHUNK)
511 return currentsize + currentsize;
512 else
513 return currentsize + BIGCHUNK;
514 }
515 return currentsize + SMALLCHUNK;
516}
517
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000518static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000519file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000520 PyFileObject *f;
521 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000522{
Guido van Rossum789a1611997-05-10 22:33:55 +0000523 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000524 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000525 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000526
Guido van Rossumd7297e61992-07-06 14:19:26 +0000527 if (f->f_fp == NULL)
528 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000529 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000530 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000531 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000532 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000533 else
534 buffersize = bytesrequested;
535 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000536 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000537 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000538 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000539 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000540 Py_BEGIN_ALLOW_THREADS
541 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000542 chunksize = fread(BUF(v) + bytesread, 1,
543 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000544 Py_END_ALLOW_THREADS
545 if (chunksize == 0) {
546 if (!ferror(f->f_fp))
547 break;
548 PyErr_SetFromErrno(PyExc_IOError);
549 clearerr(f->f_fp);
550 Py_DECREF(v);
551 return NULL;
552 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000553 bytesread += chunksize;
554 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000555 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000556 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000557 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000558 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000559 return NULL;
560 }
561 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000562 if (bytesread != buffersize)
563 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000564 return v;
565}
566
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000567static PyObject *
568file_readinto(f, args)
569 PyFileObject *f;
570 PyObject *args;
571{
572 char *ptr;
573 int ntodo, ndone, nnow;
574
575 if (f->f_fp == NULL)
576 return err_closed();
577 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
578 return NULL;
579 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000580 while (ntodo > 0) {
581 Py_BEGIN_ALLOW_THREADS
582 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000583 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000584 Py_END_ALLOW_THREADS
585 if (nnow == 0) {
586 if (!ferror(f->f_fp))
587 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000588 PyErr_SetFromErrno(PyExc_IOError);
589 clearerr(f->f_fp);
590 return NULL;
591 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000592 ndone += nnow;
593 ntodo -= nnow;
594 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000595 return PyInt_FromLong(ndone);
596}
597
598
Guido van Rossum0bd24411991-04-04 15:21:57 +0000599/* Internal routine to get a line.
600 Size argument interpretation:
601 > 0: max length;
602 = 0: read arbitrary line;
603 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000604*/
605
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000606static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000607getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000609 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000610{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000611 register FILE *fp;
612 register int c;
613 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000614 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000615 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000616
Guido van Rossumc10aa771992-07-31 12:42:38 +0000617 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000618 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000619 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000620 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000621 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000622 buf = BUF(v);
623 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000624
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000625 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000626 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000627 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000628 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000629 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000630 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000631 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000632 return NULL;
633 }
634 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000635 Py_DECREF(v);
636 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000637 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000638 return NULL;
639 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000640 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000641 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000642 }
643 if ((*buf++ = c) == '\n') {
644 if (n < 0)
645 buf--;
646 break;
647 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000648 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000649 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000650 break;
651 n1 = n2;
652 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000653 Py_BLOCK_THREADS
654 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000655 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000656 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000657 buf = BUF(v) + n1;
658 end = BUF(v) + n2;
659 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000660 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000661 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000662
Guido van Rossumce5ba841991-03-06 13:06:18 +0000663 n1 = buf - BUF(v);
664 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000665 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666 return v;
667}
668
Guido van Rossum0bd24411991-04-04 15:21:57 +0000669/* External C interface */
670
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671PyObject *
672PyFile_GetLine(f, n)
673 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000674 int n;
675{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000676 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000677 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000678 return NULL;
679 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000680 if (!PyFile_Check(f)) {
681 PyObject *reader;
682 PyObject *args;
683 PyObject *result;
684 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000685 if (reader == NULL)
686 return NULL;
687 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000688 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000689 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000690 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000691 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000692 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000693 return NULL;
694 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000695 result = PyEval_CallObject(reader, args);
696 Py_DECREF(reader);
697 Py_DECREF(args);
698 if (result != NULL && !PyString_Check(result)) {
699 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000700 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000701 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000702 "object.readline() returned non-string");
703 }
704 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000705 char *s = PyString_AsString(result);
706 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000707 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000708 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000709 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000710 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000711 "EOF when reading a line");
712 }
713 else if (s[len-1] == '\n') {
714 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000715 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000716 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000717 PyObject *v;
718 v = PyString_FromStringAndSize(s,
719 len-1);
720 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000721 result = v;
722 }
723 }
724 }
725 return result;
726 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000727 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000728 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000729 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000730}
731
732/* Python method */
733
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000734static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000735file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000736 PyFileObject *f;
737 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000738{
Guido van Rossum789a1611997-05-10 22:33:55 +0000739 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000740
Guido van Rossumd7297e61992-07-06 14:19:26 +0000741 if (f->f_fp == NULL)
742 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000743 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000744 return NULL;
745 if (n == 0)
746 return PyString_FromString("");
747 if (n < 0)
748 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000749 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000750}
751
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000752static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000753file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000754 PyFileObject *f;
755 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000756{
Guido van Rossum789a1611997-05-10 22:33:55 +0000757 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000758 PyObject *list;
759 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000760 char small_buffer[SMALLCHUNK];
761 char *buffer = small_buffer;
762 size_t buffersize = SMALLCHUNK;
763 PyObject *big_buffer = NULL;
764 size_t nfilled = 0;
765 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000766 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000767 char *p, *q, *end;
768 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000769
Guido van Rossumd7297e61992-07-06 14:19:26 +0000770 if (f->f_fp == NULL)
771 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000772 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000773 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000774 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000775 return NULL;
776 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000777 Py_BEGIN_ALLOW_THREADS
778 errno = 0;
779 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
780 Py_END_ALLOW_THREADS
781 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000782 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000783 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000784 break;
785 PyErr_SetFromErrno(PyExc_IOError);
786 clearerr(f->f_fp);
787 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000788 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000789 list = NULL;
790 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000791 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000792 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000793 p = memchr(buffer+nfilled, '\n', nread);
794 if (p == NULL) {
795 /* Need a larger buffer to fit this line */
796 nfilled += nread;
797 buffersize *= 2;
798 if (big_buffer == NULL) {
799 /* Create the big buffer */
800 big_buffer = PyString_FromStringAndSize(
801 NULL, buffersize);
802 if (big_buffer == NULL)
803 goto error;
804 buffer = PyString_AS_STRING(big_buffer);
805 memcpy(buffer, small_buffer, nfilled);
806 }
807 else {
808 /* Grow the big buffer */
809 _PyString_Resize(&big_buffer, buffersize);
810 buffer = PyString_AS_STRING(big_buffer);
811 }
812 continue;
813 }
814 end = buffer+nfilled+nread;
815 q = buffer;
816 do {
817 /* Process complete lines */
818 p++;
819 line = PyString_FromStringAndSize(q, p-q);
820 if (line == NULL)
821 goto error;
822 err = PyList_Append(list, line);
823 Py_DECREF(line);
824 if (err != 0)
825 goto error;
826 q = p;
827 p = memchr(q, '\n', end-q);
828 } while (p != NULL);
829 /* Move the remaining incomplete line to the start */
830 nfilled = end-q;
831 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000832 if (sizehint > 0)
833 if (totalread >= (size_t)sizehint)
834 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000835 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000836 if (nfilled != 0) {
837 /* Partial last line */
838 line = PyString_FromStringAndSize(buffer, nfilled);
839 if (line == NULL)
840 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000841 if (sizehint > 0) {
842 /* Need to complete the last line */
843 PyObject *rest = getline(f, 0);
844 if (rest == NULL) {
845 Py_DECREF(line);
846 goto error;
847 }
848 PyString_Concat(&line, rest);
849 Py_DECREF(rest);
850 if (line == NULL)
851 goto error;
852 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000853 err = PyList_Append(list, line);
854 Py_DECREF(line);
855 if (err != 0)
856 goto error;
857 }
858 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000859 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000860 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000861 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000862 return list;
863}
864
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000865static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000866file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000867 PyFileObject *f;
868 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000869{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000870 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000871 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000872 if (f->f_fp == NULL)
873 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +0000874 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000875 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000876 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000877 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000878 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000879 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000880 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000881 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000882 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000883 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000884 return NULL;
885 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000886 Py_INCREF(Py_None);
887 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000888}
889
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000891file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000892 PyFileObject *f;
893 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000894{
Guido van Rossumee70ad12000-03-13 16:27:06 +0000895#define CHUNKSIZE 1000
896 PyObject *list, *line;
897 PyObject *result;
898 int i, j, index, len, nwritten, islist;
899
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000900 if (f->f_fp == NULL)
901 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +0000902 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 PyErr_SetString(PyExc_TypeError,
Guido van Rossumee70ad12000-03-13 16:27:06 +0000904 "writelines() requires sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000905 return NULL;
906 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000907 islist = PyList_Check(args);
908
909 /* Strategy: slurp CHUNKSIZE lines into a private list,
910 checking that they are all strings, then write that list
911 without holding the interpreter lock, then come back for more. */
912 index = 0;
913 if (islist)
914 list = NULL;
915 else {
916 list = PyList_New(CHUNKSIZE);
917 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000918 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000919 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000920 result = NULL;
921
922 for (;;) {
923 if (islist) {
924 Py_XDECREF(list);
925 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
926 if (list == NULL)
927 return NULL;
928 j = PyList_GET_SIZE(list);
929 }
930 else {
931 for (j = 0; j < CHUNKSIZE; j++) {
932 line = PySequence_GetItem(args, index+j);
933 if (line == NULL) {
934 if (PyErr_ExceptionMatches(
935 PyExc_IndexError))
936 {
937 PyErr_Clear();
938 break;
939 }
940 /* Some other error occurred.
941 XXX We may lose some output. */
942 goto error;
943 }
944 if (!PyString_Check(line)) {
945 Py_DECREF(line);
946 PyErr_SetString(PyExc_TypeError,
947 "writelines() requires sequences of strings");
948 goto error;
949 }
950 PyList_SetItem(list, j, line);
951 }
952 }
953 if (j == 0)
954 break;
955
956 Py_BEGIN_ALLOW_THREADS
957 f->f_softspace = 0;
958 errno = 0;
959 for (i = 0; i < j; i++) {
960 line = PyList_GET_ITEM(list, i);
961 len = PyString_GET_SIZE(line);
962 nwritten = fwrite(PyString_AS_STRING(line),
963 1, len, f->f_fp);
964 if (nwritten != len) {
965 Py_BLOCK_THREADS
966 PyErr_SetFromErrno(PyExc_IOError);
967 clearerr(f->f_fp);
968 goto error;
969 }
970 }
971 Py_END_ALLOW_THREADS
972
973 if (j < CHUNKSIZE)
974 break;
975 index += CHUNKSIZE;
976 }
977
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000978 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +0000979 result = Py_None;
980 error:
981 Py_XDECREF(list);
982 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000983}
984
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000985static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000986 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000987 {"read", (PyCFunction)file_read, 1},
988 {"write", (PyCFunction)file_write, 0},
989 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +0000990 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000991#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +0000992 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000993#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000994 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000995 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000996 {"readlines", (PyCFunction)file_readlines, 1},
997 {"writelines", (PyCFunction)file_writelines, 0},
998 {"flush", (PyCFunction)file_flush, 0},
999 {"close", (PyCFunction)file_close, 0},
1000 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001001 {NULL, NULL} /* sentinel */
1002};
1003
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001004#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001005
1006static struct memberlist file_memberlist[] = {
1007 {"softspace", T_INT, OFF(f_softspace)},
1008 {"mode", T_OBJECT, OFF(f_mode), RO},
1009 {"name", T_OBJECT, OFF(f_name), RO},
1010 /* getattr(f, "closed") is implemented without this table */
1011 {"closed", T_INT, 0, RO},
1012 {NULL} /* Sentinel */
1013};
1014
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001015static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +00001016file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001017 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001018 char *name;
1019{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001020 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001021
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001022 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001023 if (res != NULL)
1024 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001025 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001026 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001027 return PyInt_FromLong((long)(f->f_fp == 0));
1028 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001029}
1030
1031static int
1032file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001033 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001034 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001035 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001036{
1037 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001038 PyErr_SetString(PyExc_AttributeError,
1039 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001040 return -1;
1041 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001042 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001043}
1044
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001045PyTypeObject PyFile_Type = {
1046 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001047 0,
1048 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001049 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001050 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001051 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001052 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001053 (getattrfunc)file_getattr, /*tp_getattr*/
1054 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001055 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001056 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001057};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001058
1059/* Interface for the 'soft space' between print items. */
1060
1061int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001062PyFile_SoftSpace(f, newflag)
1063 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001064 int newflag;
1065{
1066 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001067 if (f == NULL) {
1068 /* Do nothing */
1069 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001070 else if (PyFile_Check(f)) {
1071 oldflag = ((PyFileObject *)f)->f_softspace;
1072 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001073 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001074 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001075 PyObject *v;
1076 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001077 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001078 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001079 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001080 if (PyInt_Check(v))
1081 oldflag = PyInt_AsLong(v);
1082 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001083 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001084 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001085 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001086 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001087 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001088 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1089 PyErr_Clear();
1090 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001091 }
1092 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001093 return oldflag;
1094}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001095
1096/* Interfaces to write objects/strings to file-like objects */
1097
1098int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001099PyFile_WriteObject(v, f, flags)
1100 PyObject *v;
1101 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001102 int flags;
1103{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001104 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001105 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001106 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001107 return -1;
1108 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001109 else if (PyFile_Check(f)) {
1110 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001111 if (fp == NULL) {
1112 err_closed();
1113 return -1;
1114 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001115 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001116 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001117 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001118 if (writer == NULL)
1119 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001120 if (flags & Py_PRINT_RAW)
1121 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001122 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001123 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001124 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001125 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001126 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001127 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001128 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001129 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001130 Py_DECREF(value);
1131 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001132 return -1;
1133 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001134 result = PyEval_CallObject(writer, args);
1135 Py_DECREF(args);
1136 Py_DECREF(value);
1137 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001138 if (result == NULL)
1139 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001140 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001141 return 0;
1142}
1143
Guido van Rossum27a60b11997-05-22 22:25:11 +00001144int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001145PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001146 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001147 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001148{
1149 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001150 /* Should be caused by a pre-existing error */
1151 if(!PyErr_Occurred())
1152 PyErr_SetString(PyExc_SystemError,
1153 "null file for PyFile_WriteString");
1154 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001155 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001156 else if (PyFile_Check(f)) {
1157 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001158 if (fp == NULL) {
1159 err_closed();
1160 return -1;
1161 }
1162 fputs(s, fp);
1163 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001164 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001165 else if (!PyErr_Occurred()) {
1166 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001167 int err;
1168 if (v == NULL)
1169 return -1;
1170 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1171 Py_DECREF(v);
1172 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001173 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001174 else
1175 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001176}