blob: 5909e99f47f75afdef1e46bce884f832c56cbbb3 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* File object implementation */
3
Guido van Rossumc0b618a1997-05-02 03:12:38 +00004#include "Python.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +00005#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006
Guido van Rossumff7e83d1999-08-27 20:39:37 +00007#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum41498431999-01-07 22:09:51 +00008#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +00009#endif /* DONT_HAVE_SYS_TYPES_H */
Guido van Rossum41498431999-01-07 22:09:51 +000010
Guido van Rossum685a38e1996-12-05 21:54:17 +000011#ifdef HAVE_UNISTD_H
12#include <unistd.h>
13#endif
14
Guido van Rossumb8199141997-05-06 15:23:24 +000015#ifdef MS_WIN32
Guido van Rossumb8199141997-05-06 15:23:24 +000016#define fileno _fileno
Trent Mickf29f47b2000-08-11 19:02:59 +000017/* can (almost fully) duplicate with _chsize, see file_truncate */
Guido van Rossumb8199141997-05-06 15:23:24 +000018#define HAVE_FTRUNCATE
19#endif
20
Guido van Rossumf2044e11998-04-28 16:05:59 +000021#ifdef macintosh
22#ifdef USE_GUSI
23#define HAVE_FTRUNCATE
24#endif
25#endif
26
Jack Jansene08dea191995-04-23 22:12:47 +000027#ifdef __MWERKS__
28/* Mwerks fopen() doesn't always set errno */
29#define NO_FOPEN_ERRNO
30#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000031
Guido van Rossumc0b618a1997-05-02 03:12:38 +000032#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000033
Guido van Rossumff7e83d1999-08-27 20:39:37 +000034#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000035#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000036#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000037
Trent Mickf29f47b2000-08-11 19:02:59 +000038
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000040 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000042 PyObject *f_name;
43 PyObject *f_mode;
Tim Petersdbd9ba62000-07-09 03:09:57 +000044 int (*f_close)(FILE *);
Guido van Rossumeb183da1991-04-04 10:44:06 +000045 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000046 int f_binary; /* Flag which indicates whether the file is open
47 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000048} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000049
50FILE *
Fred Drakefd99de62000-07-09 05:02:18 +000051PyFile_AsFile(PyObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000053 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000055 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000056 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057}
58
Guido van Rossumc0b618a1997-05-02 03:12:38 +000059PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000060PyFile_Name(PyObject *f)
Guido van Rossumdb3165e1993-10-18 17:06:59 +000061{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000062 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000063 return NULL;
64 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000065 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000066}
67
Guido van Rossumc0b618a1997-05-02 03:12:38 +000068PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000069PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000071 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000072 if (f == NULL)
73 return NULL;
74 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000075 f->f_name = PyString_FromString(name);
76 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000077 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000078 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +000079 if (strchr(mode,'b') != NULL)
80 f->f_binary = 1;
81 else
82 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000084 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085 return NULL;
86 }
87 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089}
90
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000092PyFile_FromString(char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000093{
Tim Petersdbd9ba62000-07-09 03:09:57 +000094 extern int fclose(FILE *);
Guido van Rossumc0b618a1997-05-02 03:12:38 +000095 PyFileObject *f;
96 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 if (f == NULL)
98 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +000099#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000100 if (*mode == '*') {
101 FILE *fopenRF();
102 f->f_fp = fopenRF(name, mode+1);
103 }
104 else
105#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000106 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000108 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000110 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000111 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000112#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000113 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000114 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115 PyErr_SetString(PyExc_IOError, "Cannot open file");
116 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000117 return NULL;
118 }
119#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000120 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000121 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122 return NULL;
123 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000124 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125}
126
Guido van Rossumb6775db1994-08-01 11:34:53 +0000127void
Fred Drakefd99de62000-07-09 05:02:18 +0000128PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000129{
130 if (bufsize >= 0) {
131#ifdef HAVE_SETVBUF
132 int type;
133 switch (bufsize) {
134 case 0:
135 type = _IONBF;
136 break;
137 case 1:
138 type = _IOLBF;
139 bufsize = BUFSIZ;
140 break;
141 default:
142 type = _IOFBF;
143 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000144 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
145 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000146#else /* !HAVE_SETVBUF */
147 if (bufsize <= 1)
148 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
149#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000150 }
151}
152
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000153static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000154err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000155{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000156 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000157 return NULL;
158}
159
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160/* Methods */
161
162static void
Fred Drakefd99de62000-07-09 05:02:18 +0000163file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000165 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000166 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000167 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000168 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000169 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000170 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000171 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000172 }
173 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000174 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000175 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000176 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177}
178
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000179static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000180file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181{
Barry Warsaw7ce36942001-08-24 18:34:26 +0000182 return PyString_FromFormat("<%s file '%s', mode '%s' at %p>",
183 f->f_fp == NULL ? "closed" : "open",
184 PyString_AsString(f->f_name),
185 PyString_AsString(f->f_mode),
186 f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187}
188
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000189static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000190file_close(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000192 int sts = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000194 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000195 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000196 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000197 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000198 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000199 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 f->f_fp = NULL;
201 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000202 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000203 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000204 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205 return PyInt_FromLong((long)sts);
206 Py_INCREF(Py_None);
207 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208}
209
Trent Mickf29f47b2000-08-11 19:02:59 +0000210
Guido van Rossumb8552162001-09-05 14:58:11 +0000211/* Our very own off_t-like type, 64-bit if possible */
212#if !defined(HAVE_LARGEFILE_SUPPORT)
213typedef off_t Py_off_t;
214#elif SIZEOF_OFF_T >= 8
215typedef off_t Py_off_t;
216#elif SIZEOF_FPOS_T >= 8
Guido van Rossum4f53da02001-03-01 18:26:53 +0000217typedef fpos_t Py_off_t;
218#else
Guido van Rossumb8552162001-09-05 14:58:11 +0000219#error "Large file support, but neither off_t nor fpos_t is large enough."
Guido van Rossum4f53da02001-03-01 18:26:53 +0000220#endif
221
222
Trent Mickf29f47b2000-08-11 19:02:59 +0000223/* a portable fseek() function
224 return 0 on success, non-zero on failure (with errno set) */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000225static int
Guido van Rossum4f53da02001-03-01 18:26:53 +0000226_portable_fseek(FILE *fp, Py_off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000227{
Guido van Rossumb8552162001-09-05 14:58:11 +0000228#if !defined(HAVE_LARGEFILE_SUPPORT)
229 return fseek(fp, offset, whence);
230#elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000231 return fseeko(fp, offset, whence);
232#elif defined(HAVE_FSEEK64)
233 return fseek64(fp, offset, whence);
Fred Drakedb810ac2000-10-06 20:42:33 +0000234#elif defined(__BEOS__)
235 return _fseek(fp, offset, whence);
Guido van Rossumb8552162001-09-05 14:58:11 +0000236#elif SIZEOF_FPOS_T >= 8
Guido van Rossume54e0be2001-01-16 20:53:31 +0000237 /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
238 and fgetpos() to implement fseek()*/
Trent Mickf29f47b2000-08-11 19:02:59 +0000239 fpos_t pos;
240 switch (whence) {
Guido van Rossume54e0be2001-01-16 20:53:31 +0000241 case SEEK_END:
242 if (fseek(fp, 0, SEEK_END) != 0)
243 return -1;
244 /* fall through */
245 case SEEK_CUR:
246 if (fgetpos(fp, &pos) != 0)
247 return -1;
248 offset += pos;
249 break;
250 /* case SEEK_SET: break; */
Trent Mickf29f47b2000-08-11 19:02:59 +0000251 }
252 return fsetpos(fp, &offset);
253#else
Guido van Rossumb8552162001-09-05 14:58:11 +0000254#error "Large file support, but no way to fseek."
Trent Mickf29f47b2000-08-11 19:02:59 +0000255#endif
256}
257
258
259/* a portable ftell() function
260 Return -1 on failure with errno set appropriately, current file
261 position on success */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000262static Py_off_t
Fred Drake8ce159a2000-08-31 05:18:54 +0000263_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000264{
Guido van Rossumb8552162001-09-05 14:58:11 +0000265#if !defined(HAVE_LARGEFILE_SUPPORT)
266 return ftell(fp);
267#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8
268 return ftello(fp);
269#elif defined(HAVE_FTELL64)
270 return ftell64(fp);
271#elif SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000272 fpos_t pos;
273 if (fgetpos(fp, &pos) != 0)
274 return -1;
275 return pos;
276#else
Guido van Rossumb8552162001-09-05 14:58:11 +0000277#error "Large file support, but no way to ftell."
Trent Mickf29f47b2000-08-11 19:02:59 +0000278#endif
279}
280
281
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000282static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000283file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000285 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000286 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000287 Py_off_t offset;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000288 PyObject *offobj;
Tim Peters86821b22001-01-07 21:19:34 +0000289
Guido van Rossumd7297e61992-07-06 14:19:26 +0000290 if (f->f_fp == NULL)
291 return err_closed();
292 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000293 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000294 return NULL;
295#if !defined(HAVE_LARGEFILE_SUPPORT)
296 offset = PyInt_AsLong(offobj);
297#else
298 offset = PyLong_Check(offobj) ?
299 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
300#endif
301 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000302 return NULL;
Tim Peters86821b22001-01-07 21:19:34 +0000303
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000304 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000305 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000306 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000307 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000308
Guido van Rossumff4949e1992-08-05 19:58:53 +0000309 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000311 clearerr(f->f_fp);
312 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000313 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314 Py_INCREF(Py_None);
315 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000316}
317
Trent Mickf29f47b2000-08-11 19:02:59 +0000318
Guido van Rossumd7047b31995-01-02 19:07:15 +0000319#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000320static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000321file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000322{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000323 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000324 Py_off_t newsize;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000325 PyObject *newsizeobj;
Tim Peters86821b22001-01-07 21:19:34 +0000326
Guido van Rossumd7047b31995-01-02 19:07:15 +0000327 if (f->f_fp == NULL)
328 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000329 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000330 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000331 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000332 if (newsizeobj != NULL) {
333#if !defined(HAVE_LARGEFILE_SUPPORT)
334 newsize = PyInt_AsLong(newsizeobj);
335#else
336 newsize = PyLong_Check(newsizeobj) ?
337 PyLong_AsLongLong(newsizeobj) :
338 PyInt_AsLong(newsizeobj);
339#endif
340 if (PyErr_Occurred())
341 return NULL;
342 } else {
343 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000345 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000346 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000348 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000350 clearerr(f->f_fp);
351 return NULL;
352 }
353 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000355 errno = 0;
356 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000357 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000358 if (ret != 0) goto onioerror;
359
360#ifdef MS_WIN32
361 /* can use _chsize; if, however, the newsize overflows 32-bits then
362 _chsize is *not* adequate; in this case, an OverflowError is raised */
363 if (newsize > LONG_MAX) {
364 PyErr_SetString(PyExc_OverflowError,
365 "the new size is too long for _chsize (it is limited to 32-bit values)");
Guido van Rossumd7047b31995-01-02 19:07:15 +0000366 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000367 } else {
368 Py_BEGIN_ALLOW_THREADS
369 errno = 0;
Tim Peters6e13a562001-09-06 00:32:15 +0000370 ret = _chsize(fileno(f->f_fp), (long)newsize);
Trent Mickf29f47b2000-08-11 19:02:59 +0000371 Py_END_ALLOW_THREADS
372 if (ret != 0) goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000373 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000374#else
375 Py_BEGIN_ALLOW_THREADS
376 errno = 0;
377 ret = ftruncate(fileno(f->f_fp), newsize);
378 Py_END_ALLOW_THREADS
379 if (ret != 0) goto onioerror;
380#endif /* !MS_WIN32 */
Tim Peters86821b22001-01-07 21:19:34 +0000381
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000382 Py_INCREF(Py_None);
383 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000384
385onioerror:
386 PyErr_SetFromErrno(PyExc_IOError);
387 clearerr(f->f_fp);
388 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000389}
390#endif /* HAVE_FTRUNCATE */
391
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000393file_tell(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000394{
Guido van Rossum4f53da02001-03-01 18:26:53 +0000395 Py_off_t pos;
Trent Mickf29f47b2000-08-11 19:02:59 +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 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000400 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000401 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000402 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000403 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000404 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000405 clearerr(f->f_fp);
406 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000407 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000408#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000409 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000410#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000411 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000412#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000413}
414
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000416file_fileno(PyFileObject *f)
Guido van Rossumed233a51992-06-23 09:07:03 +0000417{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000418 if (f->f_fp == NULL)
419 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000420 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000421}
422
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000423static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000424file_flush(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000425{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000426 int res;
Tim Peters86821b22001-01-07 21:19:34 +0000427
Guido van Rossumd7297e61992-07-06 14:19:26 +0000428 if (f->f_fp == NULL)
429 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000431 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000432 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000433 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000434 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000435 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000436 clearerr(f->f_fp);
437 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000438 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000439 Py_INCREF(Py_None);
440 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000441}
442
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000443static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000444file_isatty(PyFileObject *f)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000445{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000446 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000447 if (f->f_fp == NULL)
448 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000449 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000450 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000451 Py_END_ALLOW_THREADS
452 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000453}
454
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000455
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000456#if BUFSIZ < 8192
457#define SMALLCHUNK 8192
458#else
459#define SMALLCHUNK BUFSIZ
460#endif
461
Guido van Rossum3c259041999-01-14 19:00:14 +0000462#if SIZEOF_INT < 4
463#define BIGCHUNK (512 * 32)
464#else
465#define BIGCHUNK (512 * 1024)
466#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000467
468static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000469new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000470{
471#ifdef HAVE_FSTAT
Fred Drake1bc8fab2001-07-19 21:49:38 +0000472 off_t pos, end;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000473 struct stat st;
474 if (fstat(fileno(f->f_fp), &st) == 0) {
475 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000476 /* The following is not a bug: we really need to call lseek()
477 *and* ftell(). The reason is that some stdio libraries
478 mistakenly flush their buffer when ftell() is called and
479 the lseek() call it makes fails, thereby throwing away
480 data that cannot be recovered in any way. To avoid this,
481 we first test lseek(), and only call ftell() if lseek()
482 works. We can't use the lseek() value either, because we
483 need to take the amount of buffered data into account.
484 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000485 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
486 if (pos >= 0)
487 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000488 if (pos < 0)
489 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000490 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000491 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000492 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000493 }
494#endif
495 if (currentsize > SMALLCHUNK) {
496 /* Keep doubling until we reach BIGCHUNK;
497 then keep adding BIGCHUNK. */
498 if (currentsize <= BIGCHUNK)
499 return currentsize + currentsize;
500 else
501 return currentsize + BIGCHUNK;
502 }
503 return currentsize + SMALLCHUNK;
504}
505
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000506static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000507file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000508{
Guido van Rossum789a1611997-05-10 22:33:55 +0000509 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000510 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000511 PyObject *v;
Tim Peters86821b22001-01-07 21:19:34 +0000512
Guido van Rossumd7297e61992-07-06 14:19:26 +0000513 if (f->f_fp == NULL)
514 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000515 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000516 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000517 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000518 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000519 else
520 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000521 if (buffersize > INT_MAX) {
522 PyErr_SetString(PyExc_OverflowError,
523 "requested number of bytes is more than a Python string can hold");
524 return NULL;
525 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000526 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000527 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000528 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000529 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000530 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000531 Py_BEGIN_ALLOW_THREADS
532 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000533 chunksize = fread(BUF(v) + bytesread, 1,
534 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000535 Py_END_ALLOW_THREADS
536 if (chunksize == 0) {
537 if (!ferror(f->f_fp))
538 break;
539 PyErr_SetFromErrno(PyExc_IOError);
540 clearerr(f->f_fp);
541 Py_DECREF(v);
542 return NULL;
543 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000544 bytesread += chunksize;
545 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000546 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000547 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000548 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000549 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000550 return NULL;
551 }
552 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000553 if (bytesread != buffersize)
554 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000555 return v;
556}
557
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000558static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000559file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000560{
561 char *ptr;
Trent Mickf29f47b2000-08-11 19:02:59 +0000562 size_t ntodo, ndone, nnow;
Tim Peters86821b22001-01-07 21:19:34 +0000563
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000564 if (f->f_fp == NULL)
565 return err_closed();
566 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
567 return NULL;
568 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000569 while (ntodo > 0) {
570 Py_BEGIN_ALLOW_THREADS
571 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000572 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000573 Py_END_ALLOW_THREADS
574 if (nnow == 0) {
575 if (!ferror(f->f_fp))
576 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000577 PyErr_SetFromErrno(PyExc_IOError);
578 clearerr(f->f_fp);
579 return NULL;
580 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000581 ndone += nnow;
582 ntodo -= nnow;
583 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000584 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000585}
586
Tim Peters86821b22001-01-07 21:19:34 +0000587/**************************************************************************
Tim Petersf29b64d2001-01-15 06:33:19 +0000588Routine to get next line using platform fgets().
Tim Peters86821b22001-01-07 21:19:34 +0000589
590Under MSVC 6:
591
Tim Peters1c733232001-01-08 04:02:07 +0000592+ MS threadsafe getc is very slow (multiple layers of function calls before+
593 after each character, to lock+unlock the stream).
594+ The stream-locking functions are MS-internal -- can't access them from user
595 code.
596+ There's nothing Tim could find in the MS C or platform SDK libraries that
597 can worm around this.
Tim Peters86821b22001-01-07 21:19:34 +0000598+ MS fgets locks/unlocks only once per line; it's the only hook we have.
599
600So we use fgets for speed(!), despite that it's painful.
601
602MS realloc is also slow.
603
Tim Petersf29b64d2001-01-15 06:33:19 +0000604Reports from other platforms on this method vs getc_unlocked (which MS doesn't
605have):
606 Linux a wash
607 Solaris a wash
608 Tru64 Unix getline_via_fgets significantly faster
Tim Peters86821b22001-01-07 21:19:34 +0000609
Tim Petersf29b64d2001-01-15 06:33:19 +0000610CAUTION: The C std isn't clear about this: in those cases where fgets
611writes something into the buffer, can it write into any position beyond the
612required trailing null byte? MSVC 6 fgets does not, and no platform is (yet)
613known on which it does; and it would be a strange way to code fgets. Still,
614getline_via_fgets may not work correctly if it does. The std test
615test_bufio.py should fail if platform fgets() routinely writes beyond the
616trailing null byte. #define DONT_USE_FGETS_IN_GETLINE to disable this code.
Tim Peters86821b22001-01-07 21:19:34 +0000617**************************************************************************/
618
Tim Petersf29b64d2001-01-15 06:33:19 +0000619/* Use this routine if told to, or by default on non-get_unlocked()
620 * platforms unless told not to. Yikes! Let's spell that out:
621 * On a platform with getc_unlocked():
622 * By default, use getc_unlocked().
623 * If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
624 * On a platform without getc_unlocked():
625 * By default, use fgets().
626 * If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
627 */
628#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
629#define USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000630#endif
631
Tim Petersf29b64d2001-01-15 06:33:19 +0000632#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
633#undef USE_FGETS_IN_GETLINE
634#endif
635
636#ifdef USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000637static PyObject*
Tim Petersf29b64d2001-01-15 06:33:19 +0000638getline_via_fgets(FILE *fp)
Tim Peters86821b22001-01-07 21:19:34 +0000639{
Tim Peters15b83852001-01-08 00:53:12 +0000640/* INITBUFSIZE is the maximum line length that lets us get away with the fast
Tim Peters142297a2001-01-15 10:36:56 +0000641 * no-realloc, one-fgets()-call path. Boosting it isn't free, because we have
642 * to fill this much of the buffer with a known value in order to figure out
643 * how much of the buffer fgets() overwrites. So if INITBUFSIZE is larger
644 * than "most" lines, we waste time filling unused buffer slots. 100 is
645 * surely adequate for most peoples' email archives, chewing over source code,
646 * etc -- "regular old text files".
647 * MAXBUFSIZE is the maximum line length that lets us get away with the less
648 * fast (but still zippy) no-realloc, two-fgets()-call path. See above for
649 * cautions about boosting that. 300 was chosen because the worst real-life
650 * text-crunching job reported on Python-Dev was a mail-log crawler where over
651 * half the lines were 254 chars.
652 * INCBUFSIZE is the amount by which we grow the buffer, if MAXBUFSIZE isn't
653 * enough. It doesn't much matter what this is set to: we only get here for
654 * absurdly long lines anyway.
Tim Peters15b83852001-01-08 00:53:12 +0000655 */
Tim Peters142297a2001-01-15 10:36:56 +0000656#define INITBUFSIZE 100
657#define MAXBUFSIZE 300
Tim Peters86821b22001-01-07 21:19:34 +0000658#define INCBUFSIZE 1000
Tim Peters142297a2001-01-15 10:36:56 +0000659 char* p; /* temp */
660 char buf[MAXBUFSIZE];
Tim Peters86821b22001-01-07 21:19:34 +0000661 PyObject* v; /* the string object result */
Tim Peters86821b22001-01-07 21:19:34 +0000662 char* pvfree; /* address of next free slot */
663 char* pvend; /* address one beyond last free slot */
Tim Peters142297a2001-01-15 10:36:56 +0000664 size_t nfree; /* # of free buffer slots; pvend-pvfree */
665 size_t total_v_size; /* total # of slots in buffer */
Tim Peters86821b22001-01-07 21:19:34 +0000666
Tim Peters15b83852001-01-08 00:53:12 +0000667 /* Optimize for normal case: avoid _PyString_Resize if at all
Tim Peters142297a2001-01-15 10:36:56 +0000668 * possible via first reading into stack buffer "buf".
Tim Peters15b83852001-01-08 00:53:12 +0000669 */
Tim Peters142297a2001-01-15 10:36:56 +0000670 total_v_size = INITBUFSIZE; /* start small and pray */
671 pvfree = buf;
672 for (;;) {
673 Py_BEGIN_ALLOW_THREADS
674 pvend = buf + total_v_size;
675 nfree = pvend - pvfree;
676 memset(pvfree, '\n', nfree);
677 p = fgets(pvfree, nfree, fp);
678 Py_END_ALLOW_THREADS
Tim Peters15b83852001-01-08 00:53:12 +0000679
Tim Peters142297a2001-01-15 10:36:56 +0000680 if (p == NULL) {
681 clearerr(fp);
682 if (PyErr_CheckSignals())
683 return NULL;
684 v = PyString_FromStringAndSize(buf, pvfree - buf);
Tim Peters86821b22001-01-07 21:19:34 +0000685 return v;
686 }
Tim Peters142297a2001-01-15 10:36:56 +0000687 /* fgets read *something* */
688 p = memchr(pvfree, '\n', nfree);
689 if (p != NULL) {
690 /* Did the \n come from fgets or from us?
691 * Since fgets stops at the first \n, and then writes
692 * \0, if it's from fgets a \0 must be next. But if
693 * that's so, it could not have come from us, since
694 * the \n's we filled the buffer with have only more
695 * \n's to the right.
696 */
697 if (p+1 < pvend && *(p+1) == '\0') {
698 /* It's from fgets: we win! In particular,
699 * we haven't done any mallocs yet, and can
700 * build the final result on the first try.
701 */
702 ++p; /* include \n from fgets */
703 }
704 else {
705 /* Must be from us: fgets didn't fill the
706 * buffer and didn't find a newline, so it
707 * must be the last and newline-free line of
708 * the file.
709 */
710 assert(p > pvfree && *(p-1) == '\0');
711 --p; /* don't include \0 from fgets */
712 }
713 v = PyString_FromStringAndSize(buf, p - buf);
714 return v;
715 }
716 /* yuck: fgets overwrote all the newlines, i.e. the entire
717 * buffer. So this line isn't over yet, or maybe it is but
718 * we're exactly at EOF. If we haven't already, try using the
719 * rest of the stack buffer.
Tim Peters86821b22001-01-07 21:19:34 +0000720 */
Tim Peters142297a2001-01-15 10:36:56 +0000721 assert(*(pvend-1) == '\0');
722 if (pvfree == buf) {
723 pvfree = pvend - 1; /* overwrite trailing null */
724 total_v_size = MAXBUFSIZE;
725 }
726 else
727 break;
Tim Peters86821b22001-01-07 21:19:34 +0000728 }
Tim Peters142297a2001-01-15 10:36:56 +0000729
730 /* The stack buffer isn't big enough; malloc a string object and read
731 * into its buffer.
Tim Peters15b83852001-01-08 00:53:12 +0000732 */
Tim Peters142297a2001-01-15 10:36:56 +0000733 total_v_size = MAXBUFSIZE + INCBUFSIZE;
Tim Peters1c733232001-01-08 04:02:07 +0000734 v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
Tim Peters15b83852001-01-08 00:53:12 +0000735 if (v == NULL)
736 return v;
737 /* copy over everything except the last null byte */
Tim Peters142297a2001-01-15 10:36:56 +0000738 memcpy(BUF(v), buf, MAXBUFSIZE-1);
739 pvfree = BUF(v) + MAXBUFSIZE - 1;
Tim Peters86821b22001-01-07 21:19:34 +0000740
741 /* Keep reading stuff into v; if it ever ends successfully, break
Tim Peters15b83852001-01-08 00:53:12 +0000742 * after setting p one beyond the end of the line. The code here is
743 * very much like the code above, except reads into v's buffer; see
744 * the code above for detailed comments about the logic.
Tim Peters86821b22001-01-07 21:19:34 +0000745 */
746 for (;;) {
Tim Peters86821b22001-01-07 21:19:34 +0000747 Py_BEGIN_ALLOW_THREADS
748 pvend = BUF(v) + total_v_size;
749 nfree = pvend - pvfree;
750 memset(pvfree, '\n', nfree);
751 p = fgets(pvfree, nfree, fp);
752 Py_END_ALLOW_THREADS
753
754 if (p == NULL) {
755 clearerr(fp);
756 if (PyErr_CheckSignals()) {
757 Py_DECREF(v);
758 return NULL;
759 }
760 p = pvfree;
761 break;
762 }
Tim Peters86821b22001-01-07 21:19:34 +0000763 p = memchr(pvfree, '\n', nfree);
764 if (p != NULL) {
765 if (p+1 < pvend && *(p+1) == '\0') {
766 /* \n came from fgets */
767 ++p;
768 break;
769 }
770 /* \n came from us; last line of file, no newline */
771 assert(p > pvfree && *(p-1) == '\0');
772 --p;
773 break;
774 }
775 /* expand buffer and try again */
776 assert(*(pvend-1) == '\0');
777 total_v_size += INCBUFSIZE;
778 if (total_v_size > INT_MAX) {
779 PyErr_SetString(PyExc_OverflowError,
780 "line is longer than a Python string can hold");
781 Py_DECREF(v);
782 return NULL;
783 }
784 if (_PyString_Resize(&v, (int)total_v_size) < 0)
785 return NULL;
786 /* overwrite the trailing null byte */
787 pvfree = BUF(v) + (total_v_size - INCBUFSIZE - 1);
788 }
789 if (BUF(v) + total_v_size != p)
790 _PyString_Resize(&v, p - BUF(v));
791 return v;
792#undef INITBUFSIZE
Tim Peters142297a2001-01-15 10:36:56 +0000793#undef MAXBUFSIZE
Tim Peters86821b22001-01-07 21:19:34 +0000794#undef INCBUFSIZE
795}
Tim Petersf29b64d2001-01-15 06:33:19 +0000796#endif /* ifdef USE_FGETS_IN_GETLINE */
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000797
Guido van Rossum0bd24411991-04-04 15:21:57 +0000798/* Internal routine to get a line.
799 Size argument interpretation:
800 > 0: max length;
Guido van Rossum86282062001-01-08 01:26:47 +0000801 <= 0: read arbitrary line
Guido van Rossumce5ba841991-03-06 13:06:18 +0000802*/
803
Guido van Rossum1187aa42001-01-05 14:43:05 +0000804#ifdef HAVE_GETC_UNLOCKED
805#define GETC(f) getc_unlocked(f)
806#define FLOCKFILE(f) flockfile(f)
807#define FUNLOCKFILE(f) funlockfile(f)
808#else
809#define GETC(f) getc(f)
810#define FLOCKFILE(f)
811#define FUNLOCKFILE(f)
812#endif
813
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000814static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000815get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000816{
Guido van Rossum1187aa42001-01-05 14:43:05 +0000817 FILE *fp = f->f_fp;
818 int c;
Andrew M. Kuchling4b2b4452000-11-29 02:53:22 +0000819 char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000820 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000821 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000822
Tim Petersf29b64d2001-01-15 06:33:19 +0000823#ifdef USE_FGETS_IN_GETLINE
Guido van Rossum86282062001-01-08 01:26:47 +0000824 if (n <= 0)
Tim Petersf29b64d2001-01-15 06:33:19 +0000825 return getline_via_fgets(fp);
Tim Peters86821b22001-01-07 21:19:34 +0000826#endif
Guido van Rossum0bd24411991-04-04 15:21:57 +0000827 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000828 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000829 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000830 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000831 buf = BUF(v);
832 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000833
Guido van Rossumce5ba841991-03-06 13:06:18 +0000834 for (;;) {
Guido van Rossum1187aa42001-01-05 14:43:05 +0000835 Py_BEGIN_ALLOW_THREADS
836 FLOCKFILE(fp);
837 while ((c = GETC(fp)) != EOF &&
838 (*buf++ = c) != '\n' &&
839 buf != end)
840 ;
841 FUNLOCKFILE(fp);
842 Py_END_ALLOW_THREADS
843 if (c == '\n')
844 break;
845 if (c == EOF) {
Guido van Rossum29206bc2001-08-09 18:14:59 +0000846 if (ferror(fp)) {
847 PyErr_SetFromErrno(PyExc_IOError);
848 clearerr(fp);
849 Py_DECREF(v);
850 return NULL;
851 }
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000852 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000853 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000854 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000855 return NULL;
856 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000857 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000858 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000859 /* Must be because buf == end */
860 if (n > 0)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000861 break;
Guido van Rossum1187aa42001-01-05 14:43:05 +0000862 n1 = n2;
863 n2 += 1000;
864 if (n2 > INT_MAX) {
865 PyErr_SetString(PyExc_OverflowError,
866 "line is longer than a Python string can hold");
Tim Peters86821b22001-01-07 21:19:34 +0000867 Py_DECREF(v);
Guido van Rossum1187aa42001-01-05 14:43:05 +0000868 return NULL;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000869 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000870 if (_PyString_Resize(&v, n2) < 0)
871 return NULL;
872 buf = BUF(v) + n1;
873 end = BUF(v) + n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000874 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000875
Guido van Rossumce5ba841991-03-06 13:06:18 +0000876 n1 = buf - BUF(v);
877 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000878 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000879 return v;
880}
881
Guido van Rossum0bd24411991-04-04 15:21:57 +0000882/* External C interface */
883
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000884PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000885PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000886{
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000887 PyObject *result;
888
Guido van Rossum3165fe61992-09-25 21:59:05 +0000889 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000890 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000891 return NULL;
892 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000893
894 if (PyFile_Check(f)) {
895 if (((PyFileObject*)f)->f_fp == NULL)
896 return err_closed();
897 result = get_line((PyFileObject *)f, n);
898 }
899 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000900 PyObject *reader;
901 PyObject *args;
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000902
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000904 if (reader == NULL)
905 return NULL;
906 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000907 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000908 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000909 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000910 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000911 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000912 return NULL;
913 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000914 result = PyEval_CallObject(reader, args);
915 Py_DECREF(reader);
916 Py_DECREF(args);
917 if (result != NULL && !PyString_Check(result)) {
918 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000919 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000920 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000921 "object.readline() returned non-string");
922 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000923 }
924
925 if (n < 0 && result != NULL && PyString_Check(result)) {
926 char *s = PyString_AS_STRING(result);
927 int len = PyString_GET_SIZE(result);
928 if (len == 0) {
929 Py_DECREF(result);
930 result = NULL;
931 PyErr_SetString(PyExc_EOFError,
932 "EOF when reading a line");
933 }
934 else if (s[len-1] == '\n') {
935 if (result->ob_refcnt == 1)
936 _PyString_Resize(&result, len-1);
937 else {
938 PyObject *v;
939 v = PyString_FromStringAndSize(s, len-1);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000940 Py_DECREF(result);
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000941 result = v;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000942 }
943 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000944 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000945 return result;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000946}
947
948/* Python method */
949
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000950static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000951file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000952{
Guido van Rossum789a1611997-05-10 22:33:55 +0000953 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000954
Guido van Rossumd7297e61992-07-06 14:19:26 +0000955 if (f->f_fp == NULL)
956 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000957 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000958 return NULL;
959 if (n == 0)
960 return PyString_FromString("");
961 if (n < 0)
962 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000963 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000964}
965
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000966static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000967file_xreadlines(PyFileObject *f)
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000968{
969 static PyObject* xreadlines_function = NULL;
Tim Petersf29b64d2001-01-15 06:33:19 +0000970
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000971 if (!xreadlines_function) {
972 PyObject *xreadlines_module =
973 PyImport_ImportModule("xreadlines");
974 if(!xreadlines_module)
975 return NULL;
976
977 xreadlines_function = PyObject_GetAttrString(xreadlines_module,
978 "xreadlines");
979 Py_DECREF(xreadlines_module);
980 if(!xreadlines_function)
981 return NULL;
982 }
983 return PyObject_CallFunction(xreadlines_function, "(O)", f);
984}
985
986static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000987file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000988{
Guido van Rossum789a1611997-05-10 22:33:55 +0000989 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000990 PyObject *list;
991 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000992 char small_buffer[SMALLCHUNK];
993 char *buffer = small_buffer;
994 size_t buffersize = SMALLCHUNK;
995 PyObject *big_buffer = NULL;
996 size_t nfilled = 0;
997 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000998 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000999 char *p, *q, *end;
1000 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +00001001
Guido van Rossumd7297e61992-07-06 14:19:26 +00001002 if (f->f_fp == NULL)
1003 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +00001004 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +00001005 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001006 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001007 return NULL;
1008 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001009 Py_BEGIN_ALLOW_THREADS
1010 errno = 0;
1011 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
1012 Py_END_ALLOW_THREADS
1013 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +00001014 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +00001015 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +00001016 break;
1017 PyErr_SetFromErrno(PyExc_IOError);
1018 clearerr(f->f_fp);
1019 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001020 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +00001021 list = NULL;
1022 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001023 }
Guido van Rossum789a1611997-05-10 22:33:55 +00001024 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +00001025 p = memchr(buffer+nfilled, '\n', nread);
1026 if (p == NULL) {
1027 /* Need a larger buffer to fit this line */
1028 nfilled += nread;
1029 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +00001030 if (buffersize > INT_MAX) {
1031 PyErr_SetString(PyExc_OverflowError,
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001032 "line is longer than a Python string can hold");
Trent Mickf29f47b2000-08-11 19:02:59 +00001033 goto error;
1034 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001035 if (big_buffer == NULL) {
1036 /* Create the big buffer */
1037 big_buffer = PyString_FromStringAndSize(
1038 NULL, buffersize);
1039 if (big_buffer == NULL)
1040 goto error;
1041 buffer = PyString_AS_STRING(big_buffer);
1042 memcpy(buffer, small_buffer, nfilled);
1043 }
1044 else {
1045 /* Grow the big buffer */
1046 _PyString_Resize(&big_buffer, buffersize);
1047 buffer = PyString_AS_STRING(big_buffer);
1048 }
1049 continue;
1050 }
1051 end = buffer+nfilled+nread;
1052 q = buffer;
1053 do {
1054 /* Process complete lines */
1055 p++;
1056 line = PyString_FromStringAndSize(q, p-q);
1057 if (line == NULL)
1058 goto error;
1059 err = PyList_Append(list, line);
1060 Py_DECREF(line);
1061 if (err != 0)
1062 goto error;
1063 q = p;
1064 p = memchr(q, '\n', end-q);
1065 } while (p != NULL);
1066 /* Move the remaining incomplete line to the start */
1067 nfilled = end-q;
1068 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +00001069 if (sizehint > 0)
1070 if (totalread >= (size_t)sizehint)
1071 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001072 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001073 if (nfilled != 0) {
1074 /* Partial last line */
1075 line = PyString_FromStringAndSize(buffer, nfilled);
1076 if (line == NULL)
1077 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +00001078 if (sizehint > 0) {
1079 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +00001080 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +00001081 if (rest == NULL) {
1082 Py_DECREF(line);
1083 goto error;
1084 }
1085 PyString_Concat(&line, rest);
1086 Py_DECREF(rest);
1087 if (line == NULL)
1088 goto error;
1089 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001090 err = PyList_Append(list, line);
1091 Py_DECREF(line);
1092 if (err != 0)
1093 goto error;
1094 }
1095 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001096 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001097 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001098 }
Guido van Rossumce5ba841991-03-06 13:06:18 +00001099 return list;
1100}
1101
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001102static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001103file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001104{
Guido van Rossumd7297e61992-07-06 14:19:26 +00001105 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001106 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001107 if (f->f_fp == NULL)
1108 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +00001109 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001110 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001111 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001112 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001113 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001114 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001115 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001116 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001117 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +00001118 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119 return NULL;
1120 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001121 Py_INCREF(Py_None);
1122 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001123}
1124
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001125static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001126file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001127{
Guido van Rossumee70ad12000-03-13 16:27:06 +00001128#define CHUNKSIZE 1000
1129 PyObject *list, *line;
1130 PyObject *result;
1131 int i, j, index, len, nwritten, islist;
1132
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001133 if (f->f_fp == NULL)
1134 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +00001135 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001136 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001137 "writelines() argument must be a sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001138 return NULL;
1139 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001140 islist = PyList_Check(args);
1141
1142 /* Strategy: slurp CHUNKSIZE lines into a private list,
1143 checking that they are all strings, then write that list
1144 without holding the interpreter lock, then come back for more. */
1145 index = 0;
1146 if (islist)
1147 list = NULL;
1148 else {
1149 list = PyList_New(CHUNKSIZE);
1150 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001151 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001152 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001153 result = NULL;
1154
1155 for (;;) {
1156 if (islist) {
1157 Py_XDECREF(list);
1158 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
1159 if (list == NULL)
1160 return NULL;
1161 j = PyList_GET_SIZE(list);
1162 }
1163 else {
1164 for (j = 0; j < CHUNKSIZE; j++) {
1165 line = PySequence_GetItem(args, index+j);
1166 if (line == NULL) {
1167 if (PyErr_ExceptionMatches(
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001168 PyExc_IndexError)) {
Guido van Rossumee70ad12000-03-13 16:27:06 +00001169 PyErr_Clear();
1170 break;
1171 }
1172 /* Some other error occurred.
1173 XXX We may lose some output. */
1174 goto error;
1175 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001176 PyList_SetItem(list, j, line);
1177 }
1178 }
1179 if (j == 0)
1180 break;
1181
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001182 /* Check that all entries are indeed strings. If not,
1183 apply the same rules as for file.write() and
1184 convert the results to strings. This is slow, but
1185 seems to be the only way since all conversion APIs
1186 could potentially execute Python code. */
1187 for (i = 0; i < j; i++) {
1188 PyObject *v = PyList_GET_ITEM(list, i);
1189 if (!PyString_Check(v)) {
1190 const char *buffer;
1191 int len;
Tim Peters86821b22001-01-07 21:19:34 +00001192 if (((f->f_binary &&
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001193 PyObject_AsReadBuffer(v,
1194 (const void**)&buffer,
1195 &len)) ||
1196 PyObject_AsCharBuffer(v,
1197 &buffer,
1198 &len))) {
1199 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001200 "writelines() argument must be a sequence of strings");
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001201 goto error;
1202 }
1203 line = PyString_FromStringAndSize(buffer,
1204 len);
1205 if (line == NULL)
1206 goto error;
1207 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001208 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001209 }
1210 }
1211
1212 /* Since we are releasing the global lock, the
1213 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001214 Py_BEGIN_ALLOW_THREADS
1215 f->f_softspace = 0;
1216 errno = 0;
1217 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001218 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001219 len = PyString_GET_SIZE(line);
1220 nwritten = fwrite(PyString_AS_STRING(line),
1221 1, len, f->f_fp);
1222 if (nwritten != len) {
1223 Py_BLOCK_THREADS
1224 PyErr_SetFromErrno(PyExc_IOError);
1225 clearerr(f->f_fp);
1226 goto error;
1227 }
1228 }
1229 Py_END_ALLOW_THREADS
1230
1231 if (j < CHUNKSIZE)
1232 break;
1233 index += CHUNKSIZE;
1234 }
1235
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001236 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001237 result = Py_None;
1238 error:
1239 Py_XDECREF(list);
1240 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001241}
1242
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001243static PyMethodDef file_methods[] = {
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001244 {"readline", (PyCFunction)file_readline, METH_VARARGS},
1245 {"read", (PyCFunction)file_read, METH_VARARGS},
1246 {"write", (PyCFunction)file_write, METH_OLDARGS},
1247 {"fileno", (PyCFunction)file_fileno, METH_NOARGS},
1248 {"seek", (PyCFunction)file_seek, METH_VARARGS},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001249#ifdef HAVE_FTRUNCATE
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001250 {"truncate", (PyCFunction)file_truncate, METH_VARARGS},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001251#endif
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001252 {"tell", (PyCFunction)file_tell, METH_NOARGS},
1253 {"readinto", (PyCFunction)file_readinto, METH_OLDARGS},
1254 {"readlines", (PyCFunction)file_readlines, METH_VARARGS},
1255 {"xreadlines", (PyCFunction)file_xreadlines, METH_NOARGS},
1256 {"writelines", (PyCFunction)file_writelines, METH_O},
1257 {"flush", (PyCFunction)file_flush, METH_NOARGS},
1258 {"close", (PyCFunction)file_close, METH_NOARGS},
1259 {"isatty", (PyCFunction)file_isatty, METH_NOARGS},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001260 {NULL, NULL} /* sentinel */
1261};
1262
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001263#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001264
1265static struct memberlist file_memberlist[] = {
1266 {"softspace", T_INT, OFF(f_softspace)},
1267 {"mode", T_OBJECT, OFF(f_mode), RO},
1268 {"name", T_OBJECT, OFF(f_name), RO},
1269 /* getattr(f, "closed") is implemented without this table */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001270 {NULL} /* Sentinel */
1271};
1272
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001273static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00001274get_closed(PyFileObject *f, void *closure)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275{
Tim Peters6d6c1a32001-08-02 04:15:00 +00001276 return PyInt_FromLong((long)(f->f_fp == 0));
Guido van Rossumb6775db1994-08-01 11:34:53 +00001277}
1278
Tim Peters6d6c1a32001-08-02 04:15:00 +00001279static struct getsetlist file_getsetlist[] = {
1280 {"closed", (getter)get_closed, NULL, NULL},
1281 {0},
1282};
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001283
Guido van Rossum65967252001-04-21 13:20:18 +00001284static PyObject *
Guido van Rossum5b021842001-05-22 16:48:37 +00001285file_getiter(PyObject *f)
Guido van Rossum65967252001-04-21 13:20:18 +00001286{
Guido van Rossum5b021842001-05-22 16:48:37 +00001287 return PyObject_CallMethod(f, "xreadlines", "");
Guido van Rossum65967252001-04-21 13:20:18 +00001288}
1289
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001290PyTypeObject PyFile_Type = {
1291 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292 0,
1293 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001294 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001295 0,
Guido van Rossum65967252001-04-21 13:20:18 +00001296 (destructor)file_dealloc, /* tp_dealloc */
1297 0, /* tp_print */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001298 0, /* tp_getattr */
1299 0, /* tp_setattr */
Guido van Rossum65967252001-04-21 13:20:18 +00001300 0, /* tp_compare */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001301 (reprfunc)file_repr, /* tp_repr */
Guido van Rossum65967252001-04-21 13:20:18 +00001302 0, /* tp_as_number */
1303 0, /* tp_as_sequence */
1304 0, /* tp_as_mapping */
1305 0, /* tp_hash */
1306 0, /* tp_call */
1307 0, /* tp_str */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001308 PyObject_GenericGetAttr, /* tp_getattro */
Guido van Rossum65967252001-04-21 13:20:18 +00001309 0, /* tp_setattro */
1310 0, /* tp_as_buffer */
1311 Py_TPFLAGS_DEFAULT, /* tp_flags */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001312 0, /* tp_doc */
1313 0, /* tp_traverse */
1314 0, /* tp_clear */
Guido van Rossum65967252001-04-21 13:20:18 +00001315 0, /* tp_richcompare */
1316 0, /* tp_weaklistoffset */
Guido van Rossum5b021842001-05-22 16:48:37 +00001317 file_getiter, /* tp_iter */
Guido van Rossum213c7a62001-04-23 14:08:49 +00001318 0, /* tp_iternext */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001319 file_methods, /* tp_methods */
1320 file_memberlist, /* tp_members */
1321 file_getsetlist, /* tp_getset */
1322 0, /* tp_base */
1323 0, /* tp_dict */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001324};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001325
1326/* Interface for the 'soft space' between print items. */
1327
1328int
Fred Drakefd99de62000-07-09 05:02:18 +00001329PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001330{
1331 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001332 if (f == NULL) {
1333 /* Do nothing */
1334 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001335 else if (PyFile_Check(f)) {
1336 oldflag = ((PyFileObject *)f)->f_softspace;
1337 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001338 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001339 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001340 PyObject *v;
1341 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001342 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001343 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001344 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001345 if (PyInt_Check(v))
1346 oldflag = PyInt_AsLong(v);
1347 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001348 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001349 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001350 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001351 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001352 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001353 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1354 PyErr_Clear();
1355 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001356 }
1357 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001358 return oldflag;
1359}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001360
1361/* Interfaces to write objects/strings to file-like objects */
1362
1363int
Fred Drakefd99de62000-07-09 05:02:18 +00001364PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001365{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001366 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001367 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001368 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001369 return -1;
1370 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001371 else if (PyFile_Check(f)) {
1372 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001373 if (fp == NULL) {
1374 err_closed();
1375 return -1;
1376 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001377 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001378 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001379 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001380 if (writer == NULL)
1381 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001382 if (flags & Py_PRINT_RAW)
1383 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001384 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001385 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001386 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001387 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001388 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001389 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001390 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001391 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001392 Py_DECREF(value);
1393 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001394 return -1;
1395 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001396 result = PyEval_CallObject(writer, args);
1397 Py_DECREF(args);
1398 Py_DECREF(value);
1399 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001400 if (result == NULL)
1401 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001402 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001403 return 0;
1404}
1405
Guido van Rossum27a60b11997-05-22 22:25:11 +00001406int
Fred Drakefd99de62000-07-09 05:02:18 +00001407PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001408{
1409 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001410 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001411 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001412 PyErr_SetString(PyExc_SystemError,
1413 "null file for PyFile_WriteString");
1414 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001415 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001416 else if (PyFile_Check(f)) {
1417 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001418 if (fp == NULL) {
1419 err_closed();
1420 return -1;
1421 }
1422 fputs(s, fp);
1423 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001424 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001425 else if (!PyErr_Occurred()) {
1426 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001427 int err;
1428 if (v == NULL)
1429 return -1;
1430 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1431 Py_DECREF(v);
1432 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001433 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001434 else
1435 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001436}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001437
1438/* Try to get a file-descriptor from a Python object. If the object
1439 is an integer or long integer, its value is returned. If not, the
1440 object's fileno() method is called if it exists; the method must return
1441 an integer or long integer, which is returned as the file descriptor value.
1442 -1 is returned on failure.
1443*/
1444
1445int PyObject_AsFileDescriptor(PyObject *o)
1446{
1447 int fd;
1448 PyObject *meth;
1449
1450 if (PyInt_Check(o)) {
1451 fd = PyInt_AsLong(o);
1452 }
1453 else if (PyLong_Check(o)) {
1454 fd = PyLong_AsLong(o);
1455 }
1456 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1457 {
1458 PyObject *fno = PyEval_CallObject(meth, NULL);
1459 Py_DECREF(meth);
1460 if (fno == NULL)
1461 return -1;
Tim Peters86821b22001-01-07 21:19:34 +00001462
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001463 if (PyInt_Check(fno)) {
1464 fd = PyInt_AsLong(fno);
1465 Py_DECREF(fno);
1466 }
1467 else if (PyLong_Check(fno)) {
1468 fd = PyLong_AsLong(fno);
1469 Py_DECREF(fno);
1470 }
1471 else {
1472 PyErr_SetString(PyExc_TypeError,
1473 "fileno() returned a non-integer");
1474 Py_DECREF(fno);
1475 return -1;
1476 }
1477 }
1478 else {
1479 PyErr_SetString(PyExc_TypeError,
1480 "argument must be an int, or have a fileno() method.");
1481 return -1;
1482 }
1483
1484 if (fd < 0) {
1485 PyErr_Format(PyExc_ValueError,
1486 "file descriptor cannot be a negative integer (%i)",
1487 fd);
1488 return -1;
1489 }
1490 return fd;
1491}