blob: 5b3d6eb217d129ed470f97ccc9a02122764758e8 [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 Rossumc0b618a1997-05-02 03:12:38 +000078} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079
80FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +000081PyFile_AsFile(f)
82 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000084 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000086 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000087 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088}
89
Guido van Rossumc0b618a1997-05-02 03:12:38 +000090PyObject *
91PyFile_Name(f)
92 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000093{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000094 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000095 return NULL;
96 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000097 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000098}
99
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000100PyObject *
101PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102 FILE *fp;
103 char *name;
104 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000105 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108 if (f == NULL)
109 return NULL;
110 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000111 f->f_name = PyString_FromString(name);
112 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000113 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000114 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000116 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117 return NULL;
118 }
119 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000120 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121}
122
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000123PyObject *
124PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125 char *name, *mode;
126{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000127 extern int fclose Py_PROTO((FILE *));
128 PyFileObject *f;
129 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 if (f == NULL)
131 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000132#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000133 if (*mode == '*') {
134 FILE *fopenRF();
135 f->f_fp = fopenRF(name, mode+1);
136 }
137 else
138#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000139 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000140 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000141 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000142 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000143 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000144 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000145#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000146 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000147 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000148 PyErr_SetString(PyExc_IOError, "Cannot open file");
149 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000150 return NULL;
151 }
152#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000153 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000154 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 return NULL;
156 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000157 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158}
159
Guido van Rossumb6775db1994-08-01 11:34:53 +0000160void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000161PyFile_SetBufSize(f, bufsize)
162 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000163 int bufsize;
164{
165 if (bufsize >= 0) {
166#ifdef HAVE_SETVBUF
167 int type;
168 switch (bufsize) {
169 case 0:
170 type = _IONBF;
171 break;
172 case 1:
173 type = _IOLBF;
174 bufsize = BUFSIZ;
175 break;
176 default:
177 type = _IOFBF;
178 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000179 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
180 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000181#else /* !HAVE_SETVBUF */
182 if (bufsize <= 1)
183 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
184#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000185 }
186}
187
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000188static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000189err_closed()
190{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000191 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000192 return NULL;
193}
194
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195/* Methods */
196
197static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000198file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000199 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000201 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000202 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000203 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000205 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000206 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000208 }
209 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000210 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000211 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 free((char *)f);
213}
214
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000215static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000216file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000217 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218{
219 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000220 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000221 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000222 PyString_AsString(f->f_name),
223 PyString_AsString(f->f_mode),
Guido van Rossume35399e1993-01-10 18:33:56 +0000224 (long)f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000225 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226}
227
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000229file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230 PyFileObject *f;
231 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000233 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000237 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000238 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000239 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000240 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000241 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000242 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243 f->f_fp = NULL;
244 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000245 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000246 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000247 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248 return PyInt_FromLong((long)sts);
249 Py_INCREF(Py_None);
250 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251}
252
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000253static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000254file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000255 PyFileObject *f;
256 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000257{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000258 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000259 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000260 off_t offset;
261 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000262
Guido van Rossumd7297e61992-07-06 14:19:26 +0000263 if (f->f_fp == NULL)
264 return err_closed();
265 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000266 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000267 return NULL;
268#if !defined(HAVE_LARGEFILE_SUPPORT)
269 offset = PyInt_AsLong(offobj);
270#else
271 offset = PyLong_Check(offobj) ?
272 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
273#endif
274 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000275 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000276 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000277 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000278#if defined(HAVE_FSEEKO)
279 ret = fseeko(f->f_fp, offset, whence);
280#elif defined(HAVE_FSEEK64)
281 ret = fseek64(f->f_fp, offset, whence);
282#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000283 ret = fseek(f->f_fp, offset, whence);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000284#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000285 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000286 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000287 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000288 clearerr(f->f_fp);
289 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000290 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000291 Py_INCREF(Py_None);
292 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000293}
294
Guido van Rossumd7047b31995-01-02 19:07:15 +0000295#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000296static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000297file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000298 PyFileObject *f;
299 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000300{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000301 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000302 off_t newsize;
303 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000304
305 if (f->f_fp == NULL)
306 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000307 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000308 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000309 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000310 if (newsizeobj != NULL) {
311#if !defined(HAVE_LARGEFILE_SUPPORT)
312 newsize = PyInt_AsLong(newsizeobj);
313#else
314 newsize = PyLong_Check(newsizeobj) ?
315 PyLong_AsLongLong(newsizeobj) :
316 PyInt_AsLong(newsizeobj);
317#endif
318 if (PyErr_Occurred())
319 return NULL;
320 } else {
321 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000322 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000323 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000324#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
325 newsize = ftello(f->f_fp);
326#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
327 newsize = ftell64(f->f_fp);
328#else
329 newsize = ftell(f->f_fp);
330#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000331 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000332 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000333 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000334 clearerr(f->f_fp);
335 return NULL;
336 }
337 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000338 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000339 errno = 0;
340 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000341 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000342 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000343 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000344 errno = 0;
345 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000347 }
348 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000350 clearerr(f->f_fp);
351 return NULL;
352 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353 Py_INCREF(Py_None);
354 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000355}
356#endif /* HAVE_FTRUNCATE */
357
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000359file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000360 PyFileObject *f;
361 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000362{
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000363 off_t offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000364 if (f->f_fp == NULL)
365 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000366 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000367 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000368 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000369 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000370#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
371 offset = ftello(f->f_fp);
372#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
373 offset = ftell64(f->f_fp);
374#else
Guido van Rossumce5ba841991-03-06 13:06:18 +0000375 offset = ftell(f->f_fp);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000376#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000377 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000378 if (offset == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000379 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000380 clearerr(f->f_fp);
381 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000382 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000383#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000384 return PyInt_FromLong(offset);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000385#else
386 return PyLong_FromLongLong(offset);
387#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000388}
389
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000391file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 PyFileObject *f;
393 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000394{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000395 if (f->f_fp == NULL)
396 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000397 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000398 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000399 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000400}
401
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000402static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000403file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000404 PyFileObject *f;
405 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000406{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000407 int res;
408
Guido van Rossumd7297e61992-07-06 14:19:26 +0000409 if (f->f_fp == NULL)
410 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000411 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000412 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000413 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000414 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000415 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000416 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000417 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000418 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000419 clearerr(f->f_fp);
420 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000421 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 Py_INCREF(Py_None);
423 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000424}
425
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000426static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000427file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428 PyFileObject *f;
429 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000430{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000431 long res;
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 Rossuma1ab7fa1991-06-04 19:37:39 +0000435 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000436 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000437 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000438 Py_END_ALLOW_THREADS
439 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000440}
441
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000442/* We expect that fstat exists on most systems.
443 It's confirmed on Unix, Mac and Windows.
444 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
445#ifndef DONT_HAVE_FSTAT
446#define HAVE_FSTAT
447
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000448#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000449#include <sys/types.h>
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000450#endif
451
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000452#ifndef DONT_HAVE_SYS_STAT_H
453#include <sys/stat.h>
454#endif
455
456#endif /* DONT_HAVE_FSTAT */
457
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000458#if BUFSIZ < 8192
459#define SMALLCHUNK 8192
460#else
461#define SMALLCHUNK BUFSIZ
462#endif
463
Guido van Rossum3c259041999-01-14 19:00:14 +0000464#if SIZEOF_INT < 4
465#define BIGCHUNK (512 * 32)
466#else
467#define BIGCHUNK (512 * 1024)
468#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000469
470static size_t
471new_buffersize(f, currentsize)
472 PyFileObject *f;
473 size_t currentsize;
474{
475#ifdef HAVE_FSTAT
476 long pos, end;
477 struct stat st;
478 if (fstat(fileno(f->f_fp), &st) == 0) {
479 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000480 /* The following is not a bug: we really need to call lseek()
481 *and* ftell(). The reason is that some stdio libraries
482 mistakenly flush their buffer when ftell() is called and
483 the lseek() call it makes fails, thereby throwing away
484 data that cannot be recovered in any way. To avoid this,
485 we first test lseek(), and only call ftell() if lseek()
486 works. We can't use the lseek() value either, because we
487 need to take the amount of buffered data into account.
488 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000489 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
490 if (pos >= 0)
491 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000492 if (pos < 0)
493 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000494 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000495 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000496 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000497 }
498#endif
499 if (currentsize > SMALLCHUNK) {
500 /* Keep doubling until we reach BIGCHUNK;
501 then keep adding BIGCHUNK. */
502 if (currentsize <= BIGCHUNK)
503 return currentsize + currentsize;
504 else
505 return currentsize + BIGCHUNK;
506 }
507 return currentsize + SMALLCHUNK;
508}
509
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000510static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000511file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000512 PyFileObject *f;
513 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000514{
Guido van Rossum789a1611997-05-10 22:33:55 +0000515 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000516 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000517 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000518
Guido van Rossumd7297e61992-07-06 14:19:26 +0000519 if (f->f_fp == NULL)
520 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000521 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000522 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000523 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000524 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000525 else
526 buffersize = bytesrequested;
527 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000528 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000530 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000531 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000532 Py_BEGIN_ALLOW_THREADS
533 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000534 chunksize = fread(BUF(v) + bytesread, 1,
535 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000536 Py_END_ALLOW_THREADS
537 if (chunksize == 0) {
538 if (!ferror(f->f_fp))
539 break;
540 PyErr_SetFromErrno(PyExc_IOError);
541 clearerr(f->f_fp);
542 Py_DECREF(v);
543 return NULL;
544 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000545 bytesread += chunksize;
546 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000547 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000548 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000549 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000550 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000551 return NULL;
552 }
553 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000554 if (bytesread != buffersize)
555 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000556 return v;
557}
558
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000559static PyObject *
560file_readinto(f, args)
561 PyFileObject *f;
562 PyObject *args;
563{
564 char *ptr;
565 int ntodo, ndone, nnow;
566
567 if (f->f_fp == NULL)
568 return err_closed();
569 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
570 return NULL;
571 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000572 while (ntodo > 0) {
573 Py_BEGIN_ALLOW_THREADS
574 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000575 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000576 Py_END_ALLOW_THREADS
577 if (nnow == 0) {
578 if (!ferror(f->f_fp))
579 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000580 PyErr_SetFromErrno(PyExc_IOError);
581 clearerr(f->f_fp);
582 return NULL;
583 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000584 ndone += nnow;
585 ntodo -= nnow;
586 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000587 return PyInt_FromLong(ndone);
588}
589
590
Guido van Rossum0bd24411991-04-04 15:21:57 +0000591/* Internal routine to get a line.
592 Size argument interpretation:
593 > 0: max length;
594 = 0: read arbitrary line;
595 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000596*/
597
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000598static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000599getline(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000601 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000602{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000603 register FILE *fp;
604 register int c;
605 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000606 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000608
Guido van Rossumc10aa771992-07-31 12:42:38 +0000609 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000610 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000611 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000612 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000613 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000614 buf = BUF(v);
615 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000616
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000617 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000618 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000619 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000620 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000621 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000622 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000623 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000624 return NULL;
625 }
626 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000627 Py_DECREF(v);
628 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000629 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000630 return NULL;
631 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000632 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000633 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000634 }
635 if ((*buf++ = c) == '\n') {
636 if (n < 0)
637 buf--;
638 break;
639 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000640 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000641 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000642 break;
643 n1 = n2;
644 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000645 Py_BLOCK_THREADS
646 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000647 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000648 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000649 buf = BUF(v) + n1;
650 end = BUF(v) + n2;
651 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000652 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000653 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000654
Guido van Rossumce5ba841991-03-06 13:06:18 +0000655 n1 = buf - BUF(v);
656 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000657 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658 return v;
659}
660
Guido van Rossum0bd24411991-04-04 15:21:57 +0000661/* External C interface */
662
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663PyObject *
664PyFile_GetLine(f, n)
665 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000666 int n;
667{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000668 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000670 return NULL;
671 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000672 if (!PyFile_Check(f)) {
673 PyObject *reader;
674 PyObject *args;
675 PyObject *result;
676 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000677 if (reader == NULL)
678 return NULL;
679 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000680 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000681 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000682 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000683 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000684 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000685 return NULL;
686 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000687 result = PyEval_CallObject(reader, args);
688 Py_DECREF(reader);
689 Py_DECREF(args);
690 if (result != NULL && !PyString_Check(result)) {
691 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000692 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000693 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000694 "object.readline() returned non-string");
695 }
696 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000697 char *s = PyString_AsString(result);
698 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000699 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000700 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000701 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000702 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000703 "EOF when reading a line");
704 }
705 else if (s[len-1] == '\n') {
706 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000707 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000708 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000709 PyObject *v;
710 v = PyString_FromStringAndSize(s,
711 len-1);
712 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000713 result = v;
714 }
715 }
716 }
717 return result;
718 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000719 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000720 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000721 return getline((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000722}
723
724/* Python method */
725
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000726static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000727file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000728 PyFileObject *f;
729 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000730{
Guido van Rossum789a1611997-05-10 22:33:55 +0000731 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000732
Guido van Rossumd7297e61992-07-06 14:19:26 +0000733 if (f->f_fp == NULL)
734 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000735 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000736 return NULL;
737 if (n == 0)
738 return PyString_FromString("");
739 if (n < 0)
740 n = 0;
Guido van Rossum51415a71992-03-27 17:23:38 +0000741 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000742}
743
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000744static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000745file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000746 PyFileObject *f;
747 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000748{
Guido van Rossum789a1611997-05-10 22:33:55 +0000749 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000750 PyObject *list;
751 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000752 char small_buffer[SMALLCHUNK];
753 char *buffer = small_buffer;
754 size_t buffersize = SMALLCHUNK;
755 PyObject *big_buffer = NULL;
756 size_t nfilled = 0;
757 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000758 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000759 char *p, *q, *end;
760 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000761
Guido van Rossumd7297e61992-07-06 14:19:26 +0000762 if (f->f_fp == NULL)
763 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000764 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000765 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000766 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000767 return NULL;
768 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000769 Py_BEGIN_ALLOW_THREADS
770 errno = 0;
771 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
772 Py_END_ALLOW_THREADS
773 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000774 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000775 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000776 break;
777 PyErr_SetFromErrno(PyExc_IOError);
778 clearerr(f->f_fp);
779 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000780 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000781 list = NULL;
782 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000783 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000784 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000785 p = memchr(buffer+nfilled, '\n', nread);
786 if (p == NULL) {
787 /* Need a larger buffer to fit this line */
788 nfilled += nread;
789 buffersize *= 2;
790 if (big_buffer == NULL) {
791 /* Create the big buffer */
792 big_buffer = PyString_FromStringAndSize(
793 NULL, buffersize);
794 if (big_buffer == NULL)
795 goto error;
796 buffer = PyString_AS_STRING(big_buffer);
797 memcpy(buffer, small_buffer, nfilled);
798 }
799 else {
800 /* Grow the big buffer */
801 _PyString_Resize(&big_buffer, buffersize);
802 buffer = PyString_AS_STRING(big_buffer);
803 }
804 continue;
805 }
806 end = buffer+nfilled+nread;
807 q = buffer;
808 do {
809 /* Process complete lines */
810 p++;
811 line = PyString_FromStringAndSize(q, p-q);
812 if (line == NULL)
813 goto error;
814 err = PyList_Append(list, line);
815 Py_DECREF(line);
816 if (err != 0)
817 goto error;
818 q = p;
819 p = memchr(q, '\n', end-q);
820 } while (p != NULL);
821 /* Move the remaining incomplete line to the start */
822 nfilled = end-q;
823 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000824 if (sizehint > 0)
825 if (totalread >= (size_t)sizehint)
826 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000827 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000828 if (nfilled != 0) {
829 /* Partial last line */
830 line = PyString_FromStringAndSize(buffer, nfilled);
831 if (line == NULL)
832 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000833 if (sizehint > 0) {
834 /* Need to complete the last line */
835 PyObject *rest = getline(f, 0);
836 if (rest == NULL) {
837 Py_DECREF(line);
838 goto error;
839 }
840 PyString_Concat(&line, rest);
841 Py_DECREF(rest);
842 if (line == NULL)
843 goto error;
844 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000845 err = PyList_Append(list, line);
846 Py_DECREF(line);
847 if (err != 0)
848 goto error;
849 }
850 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000851 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000852 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000853 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000854 return list;
855}
856
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000857static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000858file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000859 PyFileObject *f;
860 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000862 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000863 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000864 if (f->f_fp == NULL)
865 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000866 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000867 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000868 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000869 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000870 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000871 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000872 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000873 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000874 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000875 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000876 return NULL;
877 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000878 Py_INCREF(Py_None);
879 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000880}
881
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000882static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000883file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000884 PyFileObject *f;
885 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000886{
887 int i, n;
888 if (f->f_fp == NULL)
889 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890 if (args == NULL || !PyList_Check(args)) {
891 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000892 "writelines() requires list of strings");
893 return NULL;
894 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000895 n = PyList_Size(args);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000896 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000897 Py_BEGIN_ALLOW_THREADS
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000898 errno = 0;
899 for (i = 0; i < n; i++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000900 PyObject *line = PyList_GetItem(args, i);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000901 int len;
902 int nwritten;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 if (!PyString_Check(line)) {
904 Py_BLOCK_THREADS
905 PyErr_SetString(PyExc_TypeError,
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000906 "writelines() requires list of strings");
907 return NULL;
908 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000909 len = PyString_Size(line);
910 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000911 if (nwritten != len) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000912 Py_BLOCK_THREADS
913 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000914 clearerr(f->f_fp);
915 return NULL;
916 }
917 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000918 Py_END_ALLOW_THREADS
919 Py_INCREF(Py_None);
920 return Py_None;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000921}
922
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000923static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000924 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000925 {"read", (PyCFunction)file_read, 1},
926 {"write", (PyCFunction)file_write, 0},
927 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +0000928 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000929#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +0000930 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000931#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000932 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000933 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000934 {"readlines", (PyCFunction)file_readlines, 1},
935 {"writelines", (PyCFunction)file_writelines, 0},
936 {"flush", (PyCFunction)file_flush, 0},
937 {"close", (PyCFunction)file_close, 0},
938 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000939 {NULL, NULL} /* sentinel */
940};
941
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000942#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000943
944static struct memberlist file_memberlist[] = {
945 {"softspace", T_INT, OFF(f_softspace)},
946 {"mode", T_OBJECT, OFF(f_mode), RO},
947 {"name", T_OBJECT, OFF(f_name), RO},
948 /* getattr(f, "closed") is implemented without this table */
949 {"closed", T_INT, 0, RO},
950 {NULL} /* Sentinel */
951};
952
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000953static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000954file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000955 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956 char *name;
957{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000958 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000959
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000960 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000961 if (res != NULL)
962 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000963 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000964 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000965 return PyInt_FromLong((long)(f->f_fp == 0));
966 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000967}
968
969static int
970file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000971 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000972 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000973 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000974{
975 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000976 PyErr_SetString(PyExc_AttributeError,
977 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000978 return -1;
979 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000981}
982
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000983PyTypeObject PyFile_Type = {
984 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985 0,
986 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000987 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000988 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000989 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000990 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000991 (getattrfunc)file_getattr, /*tp_getattr*/
992 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000993 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000994 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000995};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000996
997/* Interface for the 'soft space' between print items. */
998
999int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001000PyFile_SoftSpace(f, newflag)
1001 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001002 int newflag;
1003{
1004 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001005 if (f == NULL) {
1006 /* Do nothing */
1007 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001008 else if (PyFile_Check(f)) {
1009 oldflag = ((PyFileObject *)f)->f_softspace;
1010 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001011 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001012 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013 PyObject *v;
1014 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001015 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001016 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001017 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001018 if (PyInt_Check(v))
1019 oldflag = PyInt_AsLong(v);
1020 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001021 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001022 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001023 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001024 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001025 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001026 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1027 PyErr_Clear();
1028 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001029 }
1030 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001031 return oldflag;
1032}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001033
1034/* Interfaces to write objects/strings to file-like objects */
1035
1036int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001037PyFile_WriteObject(v, f, flags)
1038 PyObject *v;
1039 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001040 int flags;
1041{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001042 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001043 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001044 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001045 return -1;
1046 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001047 else if (PyFile_Check(f)) {
1048 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001049 if (fp == NULL) {
1050 err_closed();
1051 return -1;
1052 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001053 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001054 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001055 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001056 if (writer == NULL)
1057 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001058 if (flags & Py_PRINT_RAW)
1059 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001060 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001061 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001062 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001063 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001064 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001065 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001066 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001067 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001068 Py_DECREF(value);
1069 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001070 return -1;
1071 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001072 result = PyEval_CallObject(writer, args);
1073 Py_DECREF(args);
1074 Py_DECREF(value);
1075 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001076 if (result == NULL)
1077 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001078 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001079 return 0;
1080}
1081
Guido van Rossum27a60b11997-05-22 22:25:11 +00001082int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001083PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001084 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001085 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001086{
1087 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001088 /* Should be caused by a pre-existing error */
1089 if(!PyErr_Occurred())
1090 PyErr_SetString(PyExc_SystemError,
1091 "null file for PyFile_WriteString");
1092 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001093 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001094 else if (PyFile_Check(f)) {
1095 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001096 if (fp == NULL) {
1097 err_closed();
1098 return -1;
1099 }
1100 fputs(s, fp);
1101 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001102 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001103 else if (!PyErr_Occurred()) {
1104 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001105 int err;
1106 if (v == NULL)
1107 return -1;
1108 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1109 Py_DECREF(v);
1110 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001111 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001112 else
1113 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001114}