blob: 7247ff8461043b1dd5b1c4650116dafe9dcf978b [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* File object implementation */
12
Guido van Rossumc0b618a1997-05-02 03:12:38 +000013#include "Python.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000014#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000015
Guido van Rossumff7e83d1999-08-27 20:39:37 +000016#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum41498431999-01-07 22:09:51 +000017#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000018#endif /* DONT_HAVE_SYS_TYPES_H */
Guido van Rossum41498431999-01-07 22:09:51 +000019
Guido van Rossumeceebb82000-06-28 20:57:07 +000020/* We expect that fstat exists on most systems.
21 It's confirmed on Unix, Mac and Windows.
22 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
23#ifndef DONT_HAVE_FSTAT
24#define HAVE_FSTAT
25
26#ifndef DONT_HAVE_SYS_TYPES_H
27#include <sys/types.h>
28#endif
29
30#ifndef DONT_HAVE_SYS_STAT_H
31#include <sys/stat.h>
32#else
33#ifdef HAVE_STAT_H
34#include <stat.h>
35#endif
36#endif
37
38#endif /* DONT_HAVE_FSTAT */
39
Guido van Rossum685a38e1996-12-05 21:54:17 +000040#ifdef HAVE_UNISTD_H
41#include <unistd.h>
42#endif
43
Guido van Rossumb8199141997-05-06 15:23:24 +000044#ifdef MS_WIN32
45#define ftruncate _chsize
46#define fileno _fileno
47#define HAVE_FTRUNCATE
48#endif
49
Guido van Rossumf2044e11998-04-28 16:05:59 +000050#ifdef macintosh
51#ifdef USE_GUSI
52#define HAVE_FTRUNCATE
53#endif
54#endif
55
Jack Jansene08dea191995-04-23 22:12:47 +000056#ifdef __MWERKS__
57/* Mwerks fopen() doesn't always set errno */
58#define NO_FOPEN_ERRNO
59#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000060
Guido van Rossumc0b618a1997-05-02 03:12:38 +000061#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000062
Guido van Rossumff7e83d1999-08-27 20:39:37 +000063#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000064#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000065#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
67typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000068 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000070 PyObject *f_name;
71 PyObject *f_mode;
72 int (*f_close) Py_PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000073 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000074 int f_binary; /* Flag which indicates whether the file is open
75 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000076} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077
78FILE *
Guido van Rossumc0b618a1997-05-02 03:12:38 +000079PyFile_AsFile(f)
80 PyObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000084 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000085 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086}
87
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088PyObject *
89PyFile_Name(f)
90 PyObject *f;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000091{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000092 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000093 return NULL;
94 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000095 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000096}
97
Guido van Rossumc0b618a1997-05-02 03:12:38 +000098PyObject *
99PyFile_FromFile(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100 FILE *fp;
101 char *name;
102 char *mode;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000103 int (*close) Py_FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000105 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106 if (f == NULL)
107 return NULL;
108 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 f->f_name = PyString_FromString(name);
110 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000111 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000112 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +0000113 if (strchr(mode,'b') != NULL)
114 f->f_binary = 1;
115 else
116 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000118 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119 return NULL;
120 }
121 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000122 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123}
124
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000125PyObject *
126PyFile_FromString(name, mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 char *name, *mode;
128{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000129 extern int fclose Py_PROTO((FILE *));
130 PyFileObject *f;
131 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000132 if (f == NULL)
133 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000134#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000135 if (*mode == '*') {
136 FILE *fopenRF();
137 f->f_fp = fopenRF(name, mode+1);
138 }
139 else
140#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000141 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000142 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000143 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000144 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000145 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000146 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000147#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000148 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000149 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000150 PyErr_SetString(PyExc_IOError, "Cannot open file");
151 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000152 return NULL;
153 }
154#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000155 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000156 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157 return NULL;
158 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000159 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160}
161
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000163PyFile_SetBufSize(f, bufsize)
164 PyObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165 int bufsize;
166{
167 if (bufsize >= 0) {
168#ifdef HAVE_SETVBUF
169 int type;
170 switch (bufsize) {
171 case 0:
172 type = _IONBF;
173 break;
174 case 1:
175 type = _IOLBF;
176 bufsize = BUFSIZ;
177 break;
178 default:
179 type = _IOFBF;
180 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000181 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
182 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000183#else /* !HAVE_SETVBUF */
184 if (bufsize <= 1)
185 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
186#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187 }
188}
189
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000190static PyObject *
Guido van Rossumd7297e61992-07-06 14:19:26 +0000191err_closed()
192{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000193 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000194 return NULL;
195}
196
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197/* Methods */
198
199static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000200file_dealloc(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000201 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000203 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000205 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000206 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000207 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000208 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000210 }
211 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000212 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000213 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000214 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215}
216
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000217static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000218file_repr(f)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000219 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220{
221 char buf[300];
Fred Drakea44d3532000-06-30 15:01:00 +0000222 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224 PyString_AsString(f->f_name),
225 PyString_AsString(f->f_mode),
Fred Drakea44d3532000-06-30 15:01:00 +0000226 f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000227 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228}
229
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000231file_close(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000232 PyFileObject *f;
233 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000235 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000236 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000239 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000241 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000242 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000243 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000244 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245 f->f_fp = NULL;
246 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000247 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000249 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000250 return PyInt_FromLong((long)sts);
251 Py_INCREF(Py_None);
252 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000253}
254
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000255static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000256file_seek(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000257 PyFileObject *f;
258 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000260 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000261 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000262 off_t offset;
263 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000264
Guido van Rossumd7297e61992-07-06 14:19:26 +0000265 if (f->f_fp == NULL)
266 return err_closed();
267 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000268 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000269 return NULL;
270#if !defined(HAVE_LARGEFILE_SUPPORT)
271 offset = PyInt_AsLong(offobj);
272#else
273 offset = PyLong_Check(offobj) ?
274 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
275#endif
276 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000277 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000278 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000279 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000280#if defined(HAVE_FSEEKO)
281 ret = fseeko(f->f_fp, offset, whence);
282#elif defined(HAVE_FSEEK64)
283 ret = fseek64(f->f_fp, offset, whence);
284#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000285 ret = fseek(f->f_fp, offset, whence);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000286#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000287 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000288 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000289 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000290 clearerr(f->f_fp);
291 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000292 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000293 Py_INCREF(Py_None);
294 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000295}
296
Guido van Rossumd7047b31995-01-02 19:07:15 +0000297#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000298static PyObject *
Guido van Rossumd7047b31995-01-02 19:07:15 +0000299file_truncate(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000300 PyFileObject *f;
301 PyObject *args;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000302{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000303 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000304 off_t newsize;
305 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000306
307 if (f->f_fp == NULL)
308 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000309 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000310 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000311 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000312 if (newsizeobj != NULL) {
313#if !defined(HAVE_LARGEFILE_SUPPORT)
314 newsize = PyInt_AsLong(newsizeobj);
315#else
316 newsize = PyLong_Check(newsizeobj) ?
317 PyLong_AsLongLong(newsizeobj) :
318 PyInt_AsLong(newsizeobj);
319#endif
320 if (PyErr_Occurred())
321 return NULL;
322 } else {
323 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000324 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000325 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000326#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
327 newsize = ftello(f->f_fp);
328#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
329 newsize = ftell64(f->f_fp);
330#else
331 newsize = ftell(f->f_fp);
332#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000333 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000334 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000335 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000336 clearerr(f->f_fp);
337 return NULL;
338 }
339 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000341 errno = 0;
342 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000343 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000344 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000345 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000346 errno = 0;
347 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000348 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000349 }
350 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000352 clearerr(f->f_fp);
353 return NULL;
354 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 Py_INCREF(Py_None);
356 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000357}
358#endif /* HAVE_FTRUNCATE */
359
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000360static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000361file_tell(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000362 PyFileObject *f;
363 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000364{
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000365 off_t offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000366 if (f->f_fp == NULL)
367 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000368 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000370 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000371 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000372#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
373 offset = ftello(f->f_fp);
374#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
375 offset = ftell64(f->f_fp);
376#else
Guido van Rossumce5ba841991-03-06 13:06:18 +0000377 offset = ftell(f->f_fp);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000378#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000379 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000380 if (offset == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000382 clearerr(f->f_fp);
383 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000384 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000385#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000386 return PyInt_FromLong(offset);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000387#else
388 return PyLong_FromLongLong(offset);
389#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000390}
391
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392static PyObject *
Guido van Rossumed233a51992-06-23 09:07:03 +0000393file_fileno(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000394 PyFileObject *f;
395 PyObject *args;
Guido van Rossumed233a51992-06-23 09:07:03 +0000396{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000397 if (f->f_fp == NULL)
398 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000399 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000400 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000402}
403
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000404static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000405file_flush(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000406 PyFileObject *f;
407 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000408{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000409 int res;
410
Guido van Rossumd7297e61992-07-06 14:19:26 +0000411 if (f->f_fp == NULL)
412 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000413 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000414 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000416 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000417 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000418 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000419 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000420 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000421 clearerr(f->f_fp);
422 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000423 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000424 Py_INCREF(Py_None);
425 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000426}
427
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428static PyObject *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000429file_isatty(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430 PyFileObject *f;
431 PyObject *args;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000432{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000433 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000434 if (f->f_fp == NULL)
435 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000436 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000437 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000438 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000439 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000440 Py_END_ALLOW_THREADS
441 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000442}
443
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000444
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000445#if BUFSIZ < 8192
446#define SMALLCHUNK 8192
447#else
448#define SMALLCHUNK BUFSIZ
449#endif
450
Guido van Rossum3c259041999-01-14 19:00:14 +0000451#if SIZEOF_INT < 4
452#define BIGCHUNK (512 * 32)
453#else
454#define BIGCHUNK (512 * 1024)
455#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000456
457static size_t
458new_buffersize(f, currentsize)
459 PyFileObject *f;
460 size_t currentsize;
461{
462#ifdef HAVE_FSTAT
463 long pos, end;
464 struct stat st;
465 if (fstat(fileno(f->f_fp), &st) == 0) {
466 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000467 /* The following is not a bug: we really need to call lseek()
468 *and* ftell(). The reason is that some stdio libraries
469 mistakenly flush their buffer when ftell() is called and
470 the lseek() call it makes fails, thereby throwing away
471 data that cannot be recovered in any way. To avoid this,
472 we first test lseek(), and only call ftell() if lseek()
473 works. We can't use the lseek() value either, because we
474 need to take the amount of buffered data into account.
475 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000476 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
477 if (pos >= 0)
478 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000479 if (pos < 0)
480 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000481 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000482 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000483 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000484 }
485#endif
486 if (currentsize > SMALLCHUNK) {
487 /* Keep doubling until we reach BIGCHUNK;
488 then keep adding BIGCHUNK. */
489 if (currentsize <= BIGCHUNK)
490 return currentsize + currentsize;
491 else
492 return currentsize + BIGCHUNK;
493 }
494 return currentsize + SMALLCHUNK;
495}
496
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000497static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000498file_read(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000499 PyFileObject *f;
500 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000501{
Guido van Rossum789a1611997-05-10 22:33:55 +0000502 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000503 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000504 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000505
Guido van Rossumd7297e61992-07-06 14:19:26 +0000506 if (f->f_fp == NULL)
507 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000508 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000509 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000510 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000511 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000512 else
513 buffersize = bytesrequested;
514 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000515 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000516 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000517 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000518 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000519 Py_BEGIN_ALLOW_THREADS
520 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000521 chunksize = fread(BUF(v) + bytesread, 1,
522 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000523 Py_END_ALLOW_THREADS
524 if (chunksize == 0) {
525 if (!ferror(f->f_fp))
526 break;
527 PyErr_SetFromErrno(PyExc_IOError);
528 clearerr(f->f_fp);
529 Py_DECREF(v);
530 return NULL;
531 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000532 bytesread += chunksize;
533 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000534 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000535 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000536 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000537 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000538 return NULL;
539 }
540 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000541 if (bytesread != buffersize)
542 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000543 return v;
544}
545
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000546static PyObject *
547file_readinto(f, args)
548 PyFileObject *f;
549 PyObject *args;
550{
551 char *ptr;
552 int ntodo, ndone, nnow;
553
554 if (f->f_fp == NULL)
555 return err_closed();
556 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
557 return NULL;
558 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000559 while (ntodo > 0) {
560 Py_BEGIN_ALLOW_THREADS
561 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000562 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000563 Py_END_ALLOW_THREADS
564 if (nnow == 0) {
565 if (!ferror(f->f_fp))
566 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000567 PyErr_SetFromErrno(PyExc_IOError);
568 clearerr(f->f_fp);
569 return NULL;
570 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000571 ndone += nnow;
572 ntodo -= nnow;
573 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000574 return PyInt_FromLong(ndone);
575}
576
577
Guido van Rossum0bd24411991-04-04 15:21:57 +0000578/* Internal routine to get a line.
579 Size argument interpretation:
580 > 0: max length;
581 = 0: read arbitrary line;
582 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000583*/
584
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000585static PyObject *
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000586get_line(f, n)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000587 PyFileObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000588 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000589{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000590 register FILE *fp;
591 register int c;
592 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000593 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000594 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000595
Guido van Rossumc10aa771992-07-31 12:42:38 +0000596 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000597 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000598 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000599 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000600 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000601 buf = BUF(v);
602 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000603
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000605 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000606 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000607 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000608 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000609 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000610 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000611 return NULL;
612 }
613 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000614 Py_DECREF(v);
615 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000616 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000617 return NULL;
618 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000619 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000620 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000621 }
622 if ((*buf++ = c) == '\n') {
623 if (n < 0)
624 buf--;
625 break;
626 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000627 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000628 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000629 break;
630 n1 = n2;
631 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 Py_BLOCK_THREADS
633 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000634 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000635 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000636 buf = BUF(v) + n1;
637 end = BUF(v) + n2;
638 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000640 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000641
Guido van Rossumce5ba841991-03-06 13:06:18 +0000642 n1 = buf - BUF(v);
643 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000644 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000645 return v;
646}
647
Guido van Rossum0bd24411991-04-04 15:21:57 +0000648/* External C interface */
649
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000650PyObject *
651PyFile_GetLine(f, n)
652 PyObject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000653 int n;
654{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000655 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000656 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000657 return NULL;
658 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000659 if (!PyFile_Check(f)) {
660 PyObject *reader;
661 PyObject *args;
662 PyObject *result;
663 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000664 if (reader == NULL)
665 return NULL;
666 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000667 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000668 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000670 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000672 return NULL;
673 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000674 result = PyEval_CallObject(reader, args);
675 Py_DECREF(reader);
676 Py_DECREF(args);
677 if (result != NULL && !PyString_Check(result)) {
678 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000679 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000680 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000681 "object.readline() returned non-string");
682 }
683 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000684 char *s = PyString_AsString(result);
685 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000686 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000687 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000688 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000689 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000690 "EOF when reading a line");
691 }
692 else if (s[len-1] == '\n') {
693 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000694 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000695 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000696 PyObject *v;
697 v = PyString_FromStringAndSize(s,
698 len-1);
699 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000700 result = v;
701 }
702 }
703 }
704 return result;
705 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000706 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000707 return err_closed();
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000708 return get_line((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000709}
710
711/* Python method */
712
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000713static PyObject *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000714file_readline(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000715 PyFileObject *f;
716 PyObject *args;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000717{
Guido van Rossum789a1611997-05-10 22:33:55 +0000718 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000719
Guido van Rossumd7297e61992-07-06 14:19:26 +0000720 if (f->f_fp == NULL)
721 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000722 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000723 return NULL;
724 if (n == 0)
725 return PyString_FromString("");
726 if (n < 0)
727 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000728 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000729}
730
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000731static PyObject *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000732file_readlines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000733 PyFileObject *f;
734 PyObject *args;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000735{
Guido van Rossum789a1611997-05-10 22:33:55 +0000736 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000737 PyObject *list;
738 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000739 char small_buffer[SMALLCHUNK];
740 char *buffer = small_buffer;
741 size_t buffersize = SMALLCHUNK;
742 PyObject *big_buffer = NULL;
743 size_t nfilled = 0;
744 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000745 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000746 char *p, *q, *end;
747 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000748
Guido van Rossumd7297e61992-07-06 14:19:26 +0000749 if (f->f_fp == NULL)
750 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000751 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000752 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000753 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000754 return NULL;
755 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000756 Py_BEGIN_ALLOW_THREADS
757 errno = 0;
758 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
759 Py_END_ALLOW_THREADS
760 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000761 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000762 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000763 break;
764 PyErr_SetFromErrno(PyExc_IOError);
765 clearerr(f->f_fp);
766 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000767 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000768 list = NULL;
769 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000770 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000771 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000772 p = memchr(buffer+nfilled, '\n', nread);
773 if (p == NULL) {
774 /* Need a larger buffer to fit this line */
775 nfilled += nread;
776 buffersize *= 2;
777 if (big_buffer == NULL) {
778 /* Create the big buffer */
779 big_buffer = PyString_FromStringAndSize(
780 NULL, buffersize);
781 if (big_buffer == NULL)
782 goto error;
783 buffer = PyString_AS_STRING(big_buffer);
784 memcpy(buffer, small_buffer, nfilled);
785 }
786 else {
787 /* Grow the big buffer */
788 _PyString_Resize(&big_buffer, buffersize);
789 buffer = PyString_AS_STRING(big_buffer);
790 }
791 continue;
792 }
793 end = buffer+nfilled+nread;
794 q = buffer;
795 do {
796 /* Process complete lines */
797 p++;
798 line = PyString_FromStringAndSize(q, p-q);
799 if (line == NULL)
800 goto error;
801 err = PyList_Append(list, line);
802 Py_DECREF(line);
803 if (err != 0)
804 goto error;
805 q = p;
806 p = memchr(q, '\n', end-q);
807 } while (p != NULL);
808 /* Move the remaining incomplete line to the start */
809 nfilled = end-q;
810 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000811 if (sizehint > 0)
812 if (totalread >= (size_t)sizehint)
813 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000814 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000815 if (nfilled != 0) {
816 /* Partial last line */
817 line = PyString_FromStringAndSize(buffer, nfilled);
818 if (line == NULL)
819 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000820 if (sizehint > 0) {
821 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000822 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +0000823 if (rest == NULL) {
824 Py_DECREF(line);
825 goto error;
826 }
827 PyString_Concat(&line, rest);
828 Py_DECREF(rest);
829 if (line == NULL)
830 goto error;
831 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000832 err = PyList_Append(list, line);
833 Py_DECREF(line);
834 if (err != 0)
835 goto error;
836 }
837 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000838 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000839 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000840 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000841 return list;
842}
843
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000844static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000845file_write(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000846 PyFileObject *f;
847 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000848{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000849 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000850 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000851 if (f->f_fp == NULL)
852 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +0000853 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000854 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000855 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000856 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000857 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000858 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000859 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000860 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000861 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000862 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000863 return NULL;
864 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000865 Py_INCREF(Py_None);
866 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000867}
868
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000869static PyObject *
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000870file_writelines(f, args)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000871 PyFileObject *f;
872 PyObject *args;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000873{
Guido van Rossumee70ad12000-03-13 16:27:06 +0000874#define CHUNKSIZE 1000
875 PyObject *list, *line;
876 PyObject *result;
877 int i, j, index, len, nwritten, islist;
878
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000879 if (f->f_fp == NULL)
880 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +0000881 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000882 PyErr_SetString(PyExc_TypeError,
Guido van Rossumee70ad12000-03-13 16:27:06 +0000883 "writelines() requires sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000884 return NULL;
885 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000886 islist = PyList_Check(args);
887
888 /* Strategy: slurp CHUNKSIZE lines into a private list,
889 checking that they are all strings, then write that list
890 without holding the interpreter lock, then come back for more. */
891 index = 0;
892 if (islist)
893 list = NULL;
894 else {
895 list = PyList_New(CHUNKSIZE);
896 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000897 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000898 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000899 result = NULL;
900
901 for (;;) {
902 if (islist) {
903 Py_XDECREF(list);
904 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
905 if (list == NULL)
906 return NULL;
907 j = PyList_GET_SIZE(list);
908 }
909 else {
910 for (j = 0; j < CHUNKSIZE; j++) {
911 line = PySequence_GetItem(args, index+j);
912 if (line == NULL) {
913 if (PyErr_ExceptionMatches(
914 PyExc_IndexError))
915 {
916 PyErr_Clear();
917 break;
918 }
919 /* Some other error occurred.
920 XXX We may lose some output. */
921 goto error;
922 }
923 if (!PyString_Check(line)) {
924 Py_DECREF(line);
925 PyErr_SetString(PyExc_TypeError,
926 "writelines() requires sequences of strings");
927 goto error;
928 }
929 PyList_SetItem(list, j, line);
930 }
931 }
932 if (j == 0)
933 break;
934
935 Py_BEGIN_ALLOW_THREADS
936 f->f_softspace = 0;
937 errno = 0;
938 for (i = 0; i < j; i++) {
939 line = PyList_GET_ITEM(list, i);
940 len = PyString_GET_SIZE(line);
941 nwritten = fwrite(PyString_AS_STRING(line),
942 1, len, f->f_fp);
943 if (nwritten != len) {
944 Py_BLOCK_THREADS
945 PyErr_SetFromErrno(PyExc_IOError);
946 clearerr(f->f_fp);
947 goto error;
948 }
949 }
950 Py_END_ALLOW_THREADS
951
952 if (j < CHUNKSIZE)
953 break;
954 index += CHUNKSIZE;
955 }
956
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000957 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +0000958 result = Py_None;
959 error:
960 Py_XDECREF(list);
961 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000962}
963
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000964static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000965 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000966 {"read", (PyCFunction)file_read, 1},
967 {"write", (PyCFunction)file_write, 0},
968 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +0000969 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000970#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +0000971 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000972#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000973 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000974 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000975 {"readlines", (PyCFunction)file_readlines, 1},
976 {"writelines", (PyCFunction)file_writelines, 0},
977 {"flush", (PyCFunction)file_flush, 0},
978 {"close", (PyCFunction)file_close, 0},
979 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000980 {NULL, NULL} /* sentinel */
981};
982
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000983#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000984
985static struct memberlist file_memberlist[] = {
986 {"softspace", T_INT, OFF(f_softspace)},
987 {"mode", T_OBJECT, OFF(f_mode), RO},
988 {"name", T_OBJECT, OFF(f_name), RO},
989 /* getattr(f, "closed") is implemented without this table */
990 {"closed", T_INT, 0, RO},
991 {NULL} /* Sentinel */
992};
993
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000994static PyObject *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000995file_getattr(f, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000996 PyFileObject *f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000997 char *name;
998{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000999 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001000
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001001 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001002 if (res != NULL)
1003 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001004 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001005 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001006 return PyInt_FromLong((long)(f->f_fp == 0));
1007 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001008}
1009
1010static int
1011file_setattr(f, name, v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001012 PyFileObject *f;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001013 char *name;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001014 PyObject *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001015{
1016 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001017 PyErr_SetString(PyExc_AttributeError,
1018 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001019 return -1;
1020 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001021 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001022}
1023
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001024PyTypeObject PyFile_Type = {
1025 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001026 0,
1027 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001028 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001029 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001030 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001031 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001032 (getattrfunc)file_getattr, /*tp_getattr*/
1033 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001034 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001035 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001036};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001037
1038/* Interface for the 'soft space' between print items. */
1039
1040int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001041PyFile_SoftSpace(f, newflag)
1042 PyObject *f;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001043 int newflag;
1044{
1045 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001046 if (f == NULL) {
1047 /* Do nothing */
1048 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001049 else if (PyFile_Check(f)) {
1050 oldflag = ((PyFileObject *)f)->f_softspace;
1051 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001052 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001053 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001054 PyObject *v;
1055 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001056 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001057 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001058 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001059 if (PyInt_Check(v))
1060 oldflag = PyInt_AsLong(v);
1061 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001062 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001063 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001064 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001065 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001066 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001067 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1068 PyErr_Clear();
1069 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001070 }
1071 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001072 return oldflag;
1073}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001074
1075/* Interfaces to write objects/strings to file-like objects */
1076
1077int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001078PyFile_WriteObject(v, f, flags)
1079 PyObject *v;
1080 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001081 int flags;
1082{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001083 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001084 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001085 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001086 return -1;
1087 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001088 else if (PyFile_Check(f)) {
1089 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001090 if (fp == NULL) {
1091 err_closed();
1092 return -1;
1093 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001094 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001095 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001096 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001097 if (writer == NULL)
1098 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001099 if (flags & Py_PRINT_RAW)
1100 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001101 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001102 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001103 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001104 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001105 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001106 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001107 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001108 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001109 Py_DECREF(value);
1110 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001111 return -1;
1112 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001113 result = PyEval_CallObject(writer, args);
1114 Py_DECREF(args);
1115 Py_DECREF(value);
1116 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001117 if (result == NULL)
1118 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001119 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001120 return 0;
1121}
1122
Guido van Rossum27a60b11997-05-22 22:25:11 +00001123int
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001124PyFile_WriteString(s, f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001125 char *s;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001126 PyObject *f;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001127{
1128 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001129 /* Should be caused by a pre-existing error */
1130 if(!PyErr_Occurred())
1131 PyErr_SetString(PyExc_SystemError,
1132 "null file for PyFile_WriteString");
1133 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001134 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001135 else if (PyFile_Check(f)) {
1136 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001137 if (fp == NULL) {
1138 err_closed();
1139 return -1;
1140 }
1141 fputs(s, fp);
1142 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001143 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001144 else if (!PyErr_Occurred()) {
1145 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001146 int err;
1147 if (v == NULL)
1148 return -1;
1149 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1150 Py_DECREF(v);
1151 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001152 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001153 else
1154 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001155}