blob: 3458f8ebb473bc347128cf0b2dbf087191011305 [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;
Tim Petersdbd9ba62000-07-09 03:09:57 +000072 int (*f_close)(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 *
Fred Drakefd99de62000-07-09 05:02:18 +000079PyFile_AsFile(PyObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000081 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000083 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000084 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085}
86
Guido van Rossumc0b618a1997-05-02 03:12:38 +000087PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000088PyFile_Name(PyObject *f)
Guido van Rossumdb3165e1993-10-18 17:06:59 +000089{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000090 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000091 return NULL;
92 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000093 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000094}
95
Guido van Rossumc0b618a1997-05-02 03:12:38 +000096PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000097PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000099 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100 if (f == NULL)
101 return NULL;
102 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000103 f->f_name = PyString_FromString(name);
104 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000105 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000106 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +0000107 if (strchr(mode,'b') != NULL)
108 f->f_binary = 1;
109 else
110 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000112 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 return NULL;
114 }
115 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000116 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117}
118
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000119PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000120PyFile_FromString(char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121{
Tim Petersdbd9ba62000-07-09 03:09:57 +0000122 extern int fclose(FILE *);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000123 PyFileObject *f;
124 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125 if (f == NULL)
126 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000127#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000128 if (*mode == '*') {
129 FILE *fopenRF();
130 f->f_fp = fopenRF(name, mode+1);
131 }
132 else
133#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000134 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000135 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000136 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000137 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000138 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000139 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000140#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000141 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000142 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000143 PyErr_SetString(PyExc_IOError, "Cannot open file");
144 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000145 return NULL;
146 }
147#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000148 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000149 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150 return NULL;
151 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000152 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153}
154
Guido van Rossumb6775db1994-08-01 11:34:53 +0000155void
Fred Drakefd99de62000-07-09 05:02:18 +0000156PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000157{
158 if (bufsize >= 0) {
159#ifdef HAVE_SETVBUF
160 int type;
161 switch (bufsize) {
162 case 0:
163 type = _IONBF;
164 break;
165 case 1:
166 type = _IOLBF;
167 bufsize = BUFSIZ;
168 break;
169 default:
170 type = _IOFBF;
171 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000172 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
173 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000174#else /* !HAVE_SETVBUF */
175 if (bufsize <= 1)
176 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
177#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178 }
179}
180
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000181static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000182err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000183{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000184 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000185 return NULL;
186}
187
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188/* Methods */
189
190static void
Fred Drakefd99de62000-07-09 05:02:18 +0000191file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000193 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000194 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000195 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000196 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000197 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000198 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000199 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000200 }
201 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000202 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000203 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000204 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205}
206
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000208file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209{
210 char buf[300];
Fred Drakea44d3532000-06-30 15:01:00 +0000211 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000213 PyString_AsString(f->f_name),
214 PyString_AsString(f->f_mode),
Fred Drakea44d3532000-06-30 15:01:00 +0000215 f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000216 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217}
218
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000219static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000220file_close(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000221{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000222 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000223 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000224 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000226 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000227 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000228 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000229 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000231 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232 f->f_fp = NULL;
233 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000234 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000236 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 return PyInt_FromLong((long)sts);
238 Py_INCREF(Py_None);
239 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000240}
241
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000243file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000244{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000245 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000246 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000247 off_t offset;
248 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000249
Guido van Rossumd7297e61992-07-06 14:19:26 +0000250 if (f->f_fp == NULL)
251 return err_closed();
252 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000253 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000254 return NULL;
255#if !defined(HAVE_LARGEFILE_SUPPORT)
256 offset = PyInt_AsLong(offobj);
257#else
258 offset = PyLong_Check(offobj) ?
259 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
260#endif
261 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000262 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000263 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000264 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000265#if defined(HAVE_FSEEKO)
266 ret = fseeko(f->f_fp, offset, whence);
267#elif defined(HAVE_FSEEK64)
268 ret = fseek64(f->f_fp, offset, whence);
269#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000270 ret = fseek(f->f_fp, offset, whence);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000271#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000272 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000273 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000274 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000275 clearerr(f->f_fp);
276 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000277 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000278 Py_INCREF(Py_None);
279 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000280}
281
Guido van Rossumd7047b31995-01-02 19:07:15 +0000282#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000283static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000284file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000285{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000286 int ret;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000287 off_t newsize;
288 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000289
290 if (f->f_fp == NULL)
291 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000292 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000293 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000294 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000295 if (newsizeobj != NULL) {
296#if !defined(HAVE_LARGEFILE_SUPPORT)
297 newsize = PyInt_AsLong(newsizeobj);
298#else
299 newsize = PyLong_Check(newsizeobj) ?
300 PyLong_AsLongLong(newsizeobj) :
301 PyInt_AsLong(newsizeobj);
302#endif
303 if (PyErr_Occurred())
304 return NULL;
305 } else {
306 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000307 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000308 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000309#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
310 newsize = ftello(f->f_fp);
311#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
312 newsize = ftell64(f->f_fp);
313#else
314 newsize = ftell(f->f_fp);
315#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000316 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000317 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000318 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000319 clearerr(f->f_fp);
320 return NULL;
321 }
322 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000324 errno = 0;
325 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000326 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000327 if (ret == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000329 errno = 0;
330 ret = ftruncate(fileno(f->f_fp), newsize);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000331 Py_END_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000332 }
333 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000334 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000335 clearerr(f->f_fp);
336 return NULL;
337 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000338 Py_INCREF(Py_None);
339 return Py_None;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000340}
341#endif /* HAVE_FTRUNCATE */
342
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000343static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000344file_tell(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000345{
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000346 off_t offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000347 if (f->f_fp == NULL)
348 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000350 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000352 errno = 0;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000353#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
354 offset = ftello(f->f_fp);
355#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
356 offset = ftell64(f->f_fp);
357#else
Guido van Rossumce5ba841991-03-06 13:06:18 +0000358 offset = ftell(f->f_fp);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000359#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000360 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000361 if (offset == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000362 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000363 clearerr(f->f_fp);
364 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000365 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000366#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000367 return PyInt_FromLong(offset);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000368#else
369 return PyLong_FromLongLong(offset);
370#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000371}
372
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000374file_fileno(PyFileObject *f, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000375{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000376 if (f->f_fp == NULL)
377 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000378 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000379 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000381}
382
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000384file_flush(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000385{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000386 int res;
387
Guido van Rossumd7297e61992-07-06 14:19:26 +0000388 if (f->f_fp == NULL)
389 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000391 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000393 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000394 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000395 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000396 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000397 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000398 clearerr(f->f_fp);
399 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000400 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401 Py_INCREF(Py_None);
402 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000403}
404
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000405static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000406file_isatty(PyFileObject *f, PyObject *args)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000407{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000408 long res;
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 Rossuma1ab7fa1991-06-04 19:37:39 +0000412 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000413 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000414 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415 Py_END_ALLOW_THREADS
416 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000417}
418
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000419
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000420#if BUFSIZ < 8192
421#define SMALLCHUNK 8192
422#else
423#define SMALLCHUNK BUFSIZ
424#endif
425
Guido van Rossum3c259041999-01-14 19:00:14 +0000426#if SIZEOF_INT < 4
427#define BIGCHUNK (512 * 32)
428#else
429#define BIGCHUNK (512 * 1024)
430#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000431
432static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000433new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000434{
435#ifdef HAVE_FSTAT
436 long pos, end;
437 struct stat st;
438 if (fstat(fileno(f->f_fp), &st) == 0) {
439 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000440 /* The following is not a bug: we really need to call lseek()
441 *and* ftell(). The reason is that some stdio libraries
442 mistakenly flush their buffer when ftell() is called and
443 the lseek() call it makes fails, thereby throwing away
444 data that cannot be recovered in any way. To avoid this,
445 we first test lseek(), and only call ftell() if lseek()
446 works. We can't use the lseek() value either, because we
447 need to take the amount of buffered data into account.
448 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000449 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
450 if (pos >= 0)
451 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000452 if (pos < 0)
453 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000454 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000455 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000456 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000457 }
458#endif
459 if (currentsize > SMALLCHUNK) {
460 /* Keep doubling until we reach BIGCHUNK;
461 then keep adding BIGCHUNK. */
462 if (currentsize <= BIGCHUNK)
463 return currentsize + currentsize;
464 else
465 return currentsize + BIGCHUNK;
466 }
467 return currentsize + SMALLCHUNK;
468}
469
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000470static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000471file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000472{
Guido van Rossum789a1611997-05-10 22:33:55 +0000473 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000474 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000475 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000476
Guido van Rossumd7297e61992-07-06 14:19:26 +0000477 if (f->f_fp == NULL)
478 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000479 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000480 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000481 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000482 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000483 else
484 buffersize = bytesrequested;
485 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000486 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000488 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000489 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000490 Py_BEGIN_ALLOW_THREADS
491 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000492 chunksize = fread(BUF(v) + bytesread, 1,
493 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000494 Py_END_ALLOW_THREADS
495 if (chunksize == 0) {
496 if (!ferror(f->f_fp))
497 break;
498 PyErr_SetFromErrno(PyExc_IOError);
499 clearerr(f->f_fp);
500 Py_DECREF(v);
501 return NULL;
502 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000503 bytesread += chunksize;
504 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000505 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000506 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000507 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000508 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000509 return NULL;
510 }
511 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000512 if (bytesread != buffersize)
513 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514 return v;
515}
516
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000517static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000518file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000519{
520 char *ptr;
521 int ntodo, ndone, nnow;
522
523 if (f->f_fp == NULL)
524 return err_closed();
525 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
526 return NULL;
527 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000528 while (ntodo > 0) {
529 Py_BEGIN_ALLOW_THREADS
530 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000531 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000532 Py_END_ALLOW_THREADS
533 if (nnow == 0) {
534 if (!ferror(f->f_fp))
535 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000536 PyErr_SetFromErrno(PyExc_IOError);
537 clearerr(f->f_fp);
538 return NULL;
539 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000540 ndone += nnow;
541 ntodo -= nnow;
542 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000543 return PyInt_FromLong(ndone);
544}
545
546
Guido van Rossum0bd24411991-04-04 15:21:57 +0000547/* Internal routine to get a line.
548 Size argument interpretation:
549 > 0: max length;
550 = 0: read arbitrary line;
551 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000552*/
553
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000555get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000556{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000557 register FILE *fp;
558 register int c;
559 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000560 int n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000561 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000562
Guido van Rossumc10aa771992-07-31 12:42:38 +0000563 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000564 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000565 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000566 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000567 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000568 buf = BUF(v);
569 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000570
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000571 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000572 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000573 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000574 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000575 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000577 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000578 return NULL;
579 }
580 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000581 Py_DECREF(v);
582 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000583 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000584 return NULL;
585 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000586 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000587 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000588 }
589 if ((*buf++ = c) == '\n') {
590 if (n < 0)
591 buf--;
592 break;
593 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000594 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000595 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000596 break;
597 n1 = n2;
598 n2 += 1000;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000599 Py_BLOCK_THREADS
600 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000601 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000603 buf = BUF(v) + n1;
604 end = BUF(v) + n2;
605 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000606 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000608
Guido van Rossumce5ba841991-03-06 13:06:18 +0000609 n1 = buf - BUF(v);
610 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000611 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612 return v;
613}
614
Guido van Rossum0bd24411991-04-04 15:21:57 +0000615/* External C interface */
616
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000617PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000618PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000619{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000620 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000621 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000622 return NULL;
623 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000624 if (!PyFile_Check(f)) {
625 PyObject *reader;
626 PyObject *args;
627 PyObject *result;
628 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000629 if (reader == NULL)
630 return NULL;
631 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000633 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000634 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000635 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000636 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000637 return NULL;
638 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000639 result = PyEval_CallObject(reader, args);
640 Py_DECREF(reader);
641 Py_DECREF(args);
642 if (result != NULL && !PyString_Check(result)) {
643 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000644 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000645 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000646 "object.readline() returned non-string");
647 }
648 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000649 char *s = PyString_AsString(result);
650 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000651 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000652 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000653 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000655 "EOF when reading a line");
656 }
657 else if (s[len-1] == '\n') {
658 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000659 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000660 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000661 PyObject *v;
662 v = PyString_FromStringAndSize(s,
663 len-1);
664 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000665 result = v;
666 }
667 }
668 }
669 return result;
670 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000671 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000672 return err_closed();
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000673 return get_line((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000674}
675
676/* Python method */
677
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000678static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000679file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000680{
Guido van Rossum789a1611997-05-10 22:33:55 +0000681 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000682
Guido van Rossumd7297e61992-07-06 14:19:26 +0000683 if (f->f_fp == NULL)
684 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000685 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000686 return NULL;
687 if (n == 0)
688 return PyString_FromString("");
689 if (n < 0)
690 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000691 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000692}
693
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000694static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000695file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000696{
Guido van Rossum789a1611997-05-10 22:33:55 +0000697 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000698 PyObject *list;
699 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000700 char small_buffer[SMALLCHUNK];
701 char *buffer = small_buffer;
702 size_t buffersize = SMALLCHUNK;
703 PyObject *big_buffer = NULL;
704 size_t nfilled = 0;
705 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000706 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000707 char *p, *q, *end;
708 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000709
Guido van Rossumd7297e61992-07-06 14:19:26 +0000710 if (f->f_fp == NULL)
711 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000712 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000713 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000714 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000715 return NULL;
716 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000717 Py_BEGIN_ALLOW_THREADS
718 errno = 0;
719 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
720 Py_END_ALLOW_THREADS
721 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000722 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000723 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000724 break;
725 PyErr_SetFromErrno(PyExc_IOError);
726 clearerr(f->f_fp);
727 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000728 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000729 list = NULL;
730 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000731 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000732 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000733 p = memchr(buffer+nfilled, '\n', nread);
734 if (p == NULL) {
735 /* Need a larger buffer to fit this line */
736 nfilled += nread;
737 buffersize *= 2;
738 if (big_buffer == NULL) {
739 /* Create the big buffer */
740 big_buffer = PyString_FromStringAndSize(
741 NULL, buffersize);
742 if (big_buffer == NULL)
743 goto error;
744 buffer = PyString_AS_STRING(big_buffer);
745 memcpy(buffer, small_buffer, nfilled);
746 }
747 else {
748 /* Grow the big buffer */
749 _PyString_Resize(&big_buffer, buffersize);
750 buffer = PyString_AS_STRING(big_buffer);
751 }
752 continue;
753 }
754 end = buffer+nfilled+nread;
755 q = buffer;
756 do {
757 /* Process complete lines */
758 p++;
759 line = PyString_FromStringAndSize(q, p-q);
760 if (line == NULL)
761 goto error;
762 err = PyList_Append(list, line);
763 Py_DECREF(line);
764 if (err != 0)
765 goto error;
766 q = p;
767 p = memchr(q, '\n', end-q);
768 } while (p != NULL);
769 /* Move the remaining incomplete line to the start */
770 nfilled = end-q;
771 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000772 if (sizehint > 0)
773 if (totalread >= (size_t)sizehint)
774 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000775 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000776 if (nfilled != 0) {
777 /* Partial last line */
778 line = PyString_FromStringAndSize(buffer, nfilled);
779 if (line == NULL)
780 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000781 if (sizehint > 0) {
782 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000783 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +0000784 if (rest == NULL) {
785 Py_DECREF(line);
786 goto error;
787 }
788 PyString_Concat(&line, rest);
789 Py_DECREF(rest);
790 if (line == NULL)
791 goto error;
792 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000793 err = PyList_Append(list, line);
794 Py_DECREF(line);
795 if (err != 0)
796 goto error;
797 }
798 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000799 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000800 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000801 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000802 return list;
803}
804
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000805static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000806file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000807{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000808 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000809 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000810 if (f->f_fp == NULL)
811 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +0000812 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000814 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000815 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000816 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000817 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000818 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000819 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000820 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000821 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000822 return NULL;
823 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000824 Py_INCREF(Py_None);
825 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000826}
827
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000828static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000829file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000830{
Guido van Rossumee70ad12000-03-13 16:27:06 +0000831#define CHUNKSIZE 1000
832 PyObject *list, *line;
833 PyObject *result;
834 int i, j, index, len, nwritten, islist;
835
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000836 if (f->f_fp == NULL)
837 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +0000838 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000839 PyErr_SetString(PyExc_TypeError,
Guido van Rossumee70ad12000-03-13 16:27:06 +0000840 "writelines() requires sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000841 return NULL;
842 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000843 islist = PyList_Check(args);
844
845 /* Strategy: slurp CHUNKSIZE lines into a private list,
846 checking that they are all strings, then write that list
847 without holding the interpreter lock, then come back for more. */
848 index = 0;
849 if (islist)
850 list = NULL;
851 else {
852 list = PyList_New(CHUNKSIZE);
853 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000854 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000855 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000856 result = NULL;
857
858 for (;;) {
859 if (islist) {
860 Py_XDECREF(list);
861 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
862 if (list == NULL)
863 return NULL;
864 j = PyList_GET_SIZE(list);
865 }
866 else {
867 for (j = 0; j < CHUNKSIZE; j++) {
868 line = PySequence_GetItem(args, index+j);
869 if (line == NULL) {
870 if (PyErr_ExceptionMatches(
871 PyExc_IndexError))
872 {
873 PyErr_Clear();
874 break;
875 }
876 /* Some other error occurred.
877 XXX We may lose some output. */
878 goto error;
879 }
880 if (!PyString_Check(line)) {
881 Py_DECREF(line);
882 PyErr_SetString(PyExc_TypeError,
883 "writelines() requires sequences of strings");
884 goto error;
885 }
886 PyList_SetItem(list, j, line);
887 }
888 }
889 if (j == 0)
890 break;
891
892 Py_BEGIN_ALLOW_THREADS
893 f->f_softspace = 0;
894 errno = 0;
895 for (i = 0; i < j; i++) {
896 line = PyList_GET_ITEM(list, i);
897 len = PyString_GET_SIZE(line);
898 nwritten = fwrite(PyString_AS_STRING(line),
899 1, len, f->f_fp);
900 if (nwritten != len) {
901 Py_BLOCK_THREADS
902 PyErr_SetFromErrno(PyExc_IOError);
903 clearerr(f->f_fp);
904 goto error;
905 }
906 }
907 Py_END_ALLOW_THREADS
908
909 if (j < CHUNKSIZE)
910 break;
911 index += CHUNKSIZE;
912 }
913
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000914 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +0000915 result = Py_None;
916 error:
917 Py_XDECREF(list);
918 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000919}
920
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000921static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +0000922 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000923 {"read", (PyCFunction)file_read, 1},
924 {"write", (PyCFunction)file_write, 0},
925 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +0000926 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000927#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +0000928 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000929#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000930 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000931 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +0000932 {"readlines", (PyCFunction)file_readlines, 1},
933 {"writelines", (PyCFunction)file_writelines, 0},
934 {"flush", (PyCFunction)file_flush, 0},
935 {"close", (PyCFunction)file_close, 0},
936 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000937 {NULL, NULL} /* sentinel */
938};
939
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000940#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000941
942static struct memberlist file_memberlist[] = {
943 {"softspace", T_INT, OFF(f_softspace)},
944 {"mode", T_OBJECT, OFF(f_mode), RO},
945 {"name", T_OBJECT, OFF(f_name), RO},
946 /* getattr(f, "closed") is implemented without this table */
947 {"closed", T_INT, 0, RO},
948 {NULL} /* Sentinel */
949};
950
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000951static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000952file_getattr(PyFileObject *f, char *name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000953{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000954 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000955
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000956 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000957 if (res != NULL)
958 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000959 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000960 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000961 return PyInt_FromLong((long)(f->f_fp == 0));
962 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000963}
964
965static int
Fred Drakefd99de62000-07-09 05:02:18 +0000966file_setattr(PyFileObject *f, char *name, PyObject *v)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000967{
968 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000969 PyErr_SetString(PyExc_AttributeError,
970 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000971 return -1;
972 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000973 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000974}
975
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000976PyTypeObject PyFile_Type = {
977 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000978 0,
979 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000981 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000982 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000983 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000984 (getattrfunc)file_getattr, /*tp_getattr*/
985 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000986 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000987 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000988};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000989
990/* Interface for the 'soft space' between print items. */
991
992int
Fred Drakefd99de62000-07-09 05:02:18 +0000993PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +0000994{
995 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000996 if (f == NULL) {
997 /* Do nothing */
998 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000999 else if (PyFile_Check(f)) {
1000 oldflag = ((PyFileObject *)f)->f_softspace;
1001 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001002 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001003 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001004 PyObject *v;
1005 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001006 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001007 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001008 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001009 if (PyInt_Check(v))
1010 oldflag = PyInt_AsLong(v);
1011 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001012 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001014 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001015 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001016 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001017 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1018 PyErr_Clear();
1019 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001020 }
1021 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001022 return oldflag;
1023}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001024
1025/* Interfaces to write objects/strings to file-like objects */
1026
1027int
Fred Drakefd99de62000-07-09 05:02:18 +00001028PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001029{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001030 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001031 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001032 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001033 return -1;
1034 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001035 else if (PyFile_Check(f)) {
1036 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001037 if (fp == NULL) {
1038 err_closed();
1039 return -1;
1040 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001041 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001042 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001043 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001044 if (writer == NULL)
1045 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001046 if (flags & Py_PRINT_RAW)
1047 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001048 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001049 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001050 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001051 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001052 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001053 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001054 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001055 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001056 Py_DECREF(value);
1057 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001058 return -1;
1059 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001060 result = PyEval_CallObject(writer, args);
1061 Py_DECREF(args);
1062 Py_DECREF(value);
1063 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001064 if (result == NULL)
1065 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001066 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001067 return 0;
1068}
1069
Guido van Rossum27a60b11997-05-22 22:25:11 +00001070int
Fred Drakefd99de62000-07-09 05:02:18 +00001071PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001072{
1073 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001074 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001075 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001076 PyErr_SetString(PyExc_SystemError,
1077 "null file for PyFile_WriteString");
1078 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001079 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001080 else if (PyFile_Check(f)) {
1081 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001082 if (fp == NULL) {
1083 err_closed();
1084 return -1;
1085 }
1086 fputs(s, fp);
1087 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001088 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001089 else if (!PyErr_Occurred()) {
1090 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001091 int err;
1092 if (v == NULL)
1093 return -1;
1094 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1095 Py_DECREF(v);
1096 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001097 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001098 else
1099 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001100}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001101
1102/* Try to get a file-descriptor from a Python object. If the object
1103 is an integer or long integer, its value is returned. If not, the
1104 object's fileno() method is called if it exists; the method must return
1105 an integer or long integer, which is returned as the file descriptor value.
1106 -1 is returned on failure.
1107*/
1108
1109int PyObject_AsFileDescriptor(PyObject *o)
1110{
1111 int fd;
1112 PyObject *meth;
1113
1114 if (PyInt_Check(o)) {
1115 fd = PyInt_AsLong(o);
1116 }
1117 else if (PyLong_Check(o)) {
1118 fd = PyLong_AsLong(o);
1119 }
1120 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1121 {
1122 PyObject *fno = PyEval_CallObject(meth, NULL);
1123 Py_DECREF(meth);
1124 if (fno == NULL)
1125 return -1;
1126
1127 if (PyInt_Check(fno)) {
1128 fd = PyInt_AsLong(fno);
1129 Py_DECREF(fno);
1130 }
1131 else if (PyLong_Check(fno)) {
1132 fd = PyLong_AsLong(fno);
1133 Py_DECREF(fno);
1134 }
1135 else {
1136 PyErr_SetString(PyExc_TypeError,
1137 "fileno() returned a non-integer");
1138 Py_DECREF(fno);
1139 return -1;
1140 }
1141 }
1142 else {
1143 PyErr_SetString(PyExc_TypeError,
1144 "argument must be an int, or have a fileno() method.");
1145 return -1;
1146 }
1147
1148 if (fd < 0) {
1149 PyErr_Format(PyExc_ValueError,
1150 "file descriptor cannot be a negative integer (%i)",
1151 fd);
1152 return -1;
1153 }
1154 return fd;
1155}
1156
1157
1158