blob: 7d3287928abb6bb829f520126d5bfe6d4ea9d90f [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{
182 char buf[300];
Fred Drakea44d3532000-06-30 15:01:00 +0000183 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000185 PyString_AsString(f->f_name),
186 PyString_AsString(f->f_mode),
Fred Drakea44d3532000-06-30 15:01:00 +0000187 f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000188 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189}
190
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000191static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000192file_close(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000194 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000195 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000198 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000199 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000200 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000201 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000202 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000203 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204 f->f_fp = NULL;
205 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000206 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000208 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209 return PyInt_FromLong((long)sts);
210 Py_INCREF(Py_None);
211 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212}
213
Trent Mickf29f47b2000-08-11 19:02:59 +0000214
215/* a portable fseek() function
216 return 0 on success, non-zero on failure (with errno set) */
217int
Tim Peters86821b22001-01-07 21:19:34 +0000218#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Fred Drake8ce159a2000-08-31 05:18:54 +0000219_portable_fseek(FILE *fp, fpos_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000220#else
Fred Drake8ce159a2000-08-31 05:18:54 +0000221_portable_fseek(FILE *fp, off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000222#endif
Trent Mickf29f47b2000-08-11 19:02:59 +0000223{
224#if defined(HAVE_FSEEKO)
225 return fseeko(fp, offset, whence);
226#elif defined(HAVE_FSEEK64)
227 return fseek64(fp, offset, whence);
Fred Drakedb810ac2000-10-06 20:42:33 +0000228#elif defined(__BEOS__)
229 return _fseek(fp, offset, whence);
Tim Peters86821b22001-01-07 21:19:34 +0000230#elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
Guido van Rossume54e0be2001-01-16 20:53:31 +0000231 /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
232 and fgetpos() to implement fseek()*/
Trent Mickf29f47b2000-08-11 19:02:59 +0000233 fpos_t pos;
234 switch (whence) {
Guido van Rossume54e0be2001-01-16 20:53:31 +0000235 case SEEK_END:
236 if (fseek(fp, 0, SEEK_END) != 0)
237 return -1;
238 /* fall through */
239 case SEEK_CUR:
240 if (fgetpos(fp, &pos) != 0)
241 return -1;
242 offset += pos;
243 break;
244 /* case SEEK_SET: break; */
Trent Mickf29f47b2000-08-11 19:02:59 +0000245 }
246 return fsetpos(fp, &offset);
247#else
248 return fseek(fp, offset, whence);
249#endif
250}
251
252
253/* a portable ftell() function
254 Return -1 on failure with errno set appropriately, current file
255 position on success */
Tim Peters86821b22001-01-07 21:19:34 +0000256#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000257fpos_t
258#else
259off_t
260#endif
Fred Drake8ce159a2000-08-31 05:18:54 +0000261_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000262{
263#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
264 return ftello(fp);
265#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
266 return ftell64(fp);
267#elif SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT)
268 fpos_t pos;
269 if (fgetpos(fp, &pos) != 0)
270 return -1;
271 return pos;
272#else
273 return ftell(fp);
274#endif
275}
276
277
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000278static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000279file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000281 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000282 int ret;
Tim Peters86821b22001-01-07 21:19:34 +0000283#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000284 fpos_t offset, pos;
285#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000286 off_t offset;
Trent Mickf29f47b2000-08-11 19:02:59 +0000287#endif /* !MS_WIN64 */
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;
Tim Peters86821b22001-01-07 21:19:34 +0000324#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000325 fpos_t newsize;
326#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000327 off_t newsize;
Trent Mickf29f47b2000-08-11 19:02:59 +0000328#endif
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000329 PyObject *newsizeobj;
Tim Peters86821b22001-01-07 21:19:34 +0000330
Guido van Rossumd7047b31995-01-02 19:07:15 +0000331 if (f->f_fp == NULL)
332 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000333 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000334 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000335 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000336 if (newsizeobj != NULL) {
337#if !defined(HAVE_LARGEFILE_SUPPORT)
338 newsize = PyInt_AsLong(newsizeobj);
339#else
340 newsize = PyLong_Check(newsizeobj) ?
341 PyLong_AsLongLong(newsizeobj) :
342 PyInt_AsLong(newsizeobj);
343#endif
344 if (PyErr_Occurred())
345 return NULL;
346 } else {
347 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000348 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000349 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000350 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000352 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000354 clearerr(f->f_fp);
355 return NULL;
356 }
357 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000359 errno = 0;
360 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000361 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000362 if (ret != 0) goto onioerror;
363
364#ifdef MS_WIN32
365 /* can use _chsize; if, however, the newsize overflows 32-bits then
366 _chsize is *not* adequate; in this case, an OverflowError is raised */
367 if (newsize > LONG_MAX) {
368 PyErr_SetString(PyExc_OverflowError,
369 "the new size is too long for _chsize (it is limited to 32-bit values)");
Guido van Rossumd7047b31995-01-02 19:07:15 +0000370 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000371 } else {
372 Py_BEGIN_ALLOW_THREADS
373 errno = 0;
374 ret = _chsize(fileno(f->f_fp), newsize);
375 Py_END_ALLOW_THREADS
376 if (ret != 0) goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000377 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000378#else
379 Py_BEGIN_ALLOW_THREADS
380 errno = 0;
381 ret = ftruncate(fileno(f->f_fp), newsize);
382 Py_END_ALLOW_THREADS
383 if (ret != 0) goto onioerror;
384#endif /* !MS_WIN32 */
Tim Peters86821b22001-01-07 21:19:34 +0000385
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000386 Py_INCREF(Py_None);
387 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000388
389onioerror:
390 PyErr_SetFromErrno(PyExc_IOError);
391 clearerr(f->f_fp);
392 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000393}
394#endif /* HAVE_FTRUNCATE */
395
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000396static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000397file_tell(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000398{
Tim Peters86821b22001-01-07 21:19:34 +0000399#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000400 fpos_t pos;
401#else
402 off_t pos;
403#endif
404
Guido van Rossumd7297e61992-07-06 14:19:26 +0000405 if (f->f_fp == NULL)
406 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000407 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000408 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000409 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000410 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000411 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000412 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000413 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000414 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000415 clearerr(f->f_fp);
416 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000417 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000418#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000419 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000420#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000421 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000422#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000423}
424
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000425static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000426file_fileno(PyFileObject *f, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +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 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000431 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000433}
434
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000435static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000436file_flush(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000437{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000438 int res;
Tim Peters86821b22001-01-07 21:19:34 +0000439
Guido van Rossumd7297e61992-07-06 14:19:26 +0000440 if (f->f_fp == NULL)
441 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000442 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000443 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000444 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000445 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000446 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000447 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000448 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000449 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000450 clearerr(f->f_fp);
451 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000452 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000453 Py_INCREF(Py_None);
454 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000455}
456
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000458file_isatty(PyFileObject *f, PyObject *args)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000459{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000460 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000461 if (f->f_fp == NULL)
462 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000463 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000464 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000465 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000466 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000467 Py_END_ALLOW_THREADS
468 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000469}
470
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000471
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000472#if BUFSIZ < 8192
473#define SMALLCHUNK 8192
474#else
475#define SMALLCHUNK BUFSIZ
476#endif
477
Guido van Rossum3c259041999-01-14 19:00:14 +0000478#if SIZEOF_INT < 4
479#define BIGCHUNK (512 * 32)
480#else
481#define BIGCHUNK (512 * 1024)
482#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000483
484static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000485new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000486{
487#ifdef HAVE_FSTAT
488 long pos, end;
489 struct stat st;
490 if (fstat(fileno(f->f_fp), &st) == 0) {
491 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000492 /* The following is not a bug: we really need to call lseek()
493 *and* ftell(). The reason is that some stdio libraries
494 mistakenly flush their buffer when ftell() is called and
495 the lseek() call it makes fails, thereby throwing away
496 data that cannot be recovered in any way. To avoid this,
497 we first test lseek(), and only call ftell() if lseek()
498 works. We can't use the lseek() value either, because we
499 need to take the amount of buffered data into account.
500 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000501 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
502 if (pos >= 0)
503 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000504 if (pos < 0)
505 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000506 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000507 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000508 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000509 }
510#endif
511 if (currentsize > SMALLCHUNK) {
512 /* Keep doubling until we reach BIGCHUNK;
513 then keep adding BIGCHUNK. */
514 if (currentsize <= BIGCHUNK)
515 return currentsize + currentsize;
516 else
517 return currentsize + BIGCHUNK;
518 }
519 return currentsize + SMALLCHUNK;
520}
521
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000522static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000523file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000524{
Guido van Rossum789a1611997-05-10 22:33:55 +0000525 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000526 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000527 PyObject *v;
Tim Peters86821b22001-01-07 21:19:34 +0000528
Guido van Rossumd7297e61992-07-06 14:19:26 +0000529 if (f->f_fp == NULL)
530 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000531 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000532 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000533 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000534 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000535 else
536 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000537 if (buffersize > INT_MAX) {
538 PyErr_SetString(PyExc_OverflowError,
539 "requested number of bytes is more than a Python string can hold");
540 return NULL;
541 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000542 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000543 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000544 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000545 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000546 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000547 Py_BEGIN_ALLOW_THREADS
548 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000549 chunksize = fread(BUF(v) + bytesread, 1,
550 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000551 Py_END_ALLOW_THREADS
552 if (chunksize == 0) {
553 if (!ferror(f->f_fp))
554 break;
555 PyErr_SetFromErrno(PyExc_IOError);
556 clearerr(f->f_fp);
557 Py_DECREF(v);
558 return NULL;
559 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000560 bytesread += chunksize;
561 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000562 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000563 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000564 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000565 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000566 return NULL;
567 }
568 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000569 if (bytesread != buffersize)
570 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000571 return v;
572}
573
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000574static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000575file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000576{
577 char *ptr;
Trent Mickf29f47b2000-08-11 19:02:59 +0000578 size_t ntodo, ndone, nnow;
Tim Peters86821b22001-01-07 21:19:34 +0000579
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000580 if (f->f_fp == NULL)
581 return err_closed();
582 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
583 return NULL;
584 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000585 while (ntodo > 0) {
586 Py_BEGIN_ALLOW_THREADS
587 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000588 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000589 Py_END_ALLOW_THREADS
590 if (nnow == 0) {
591 if (!ferror(f->f_fp))
592 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000593 PyErr_SetFromErrno(PyExc_IOError);
594 clearerr(f->f_fp);
595 return NULL;
596 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000597 ndone += nnow;
598 ntodo -= nnow;
599 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000600 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000601}
602
Tim Peters86821b22001-01-07 21:19:34 +0000603/**************************************************************************
Tim Petersf29b64d2001-01-15 06:33:19 +0000604Routine to get next line using platform fgets().
Tim Peters86821b22001-01-07 21:19:34 +0000605
606Under MSVC 6:
607
Tim Peters1c733232001-01-08 04:02:07 +0000608+ MS threadsafe getc is very slow (multiple layers of function calls before+
609 after each character, to lock+unlock the stream).
610+ The stream-locking functions are MS-internal -- can't access them from user
611 code.
612+ There's nothing Tim could find in the MS C or platform SDK libraries that
613 can worm around this.
Tim Peters86821b22001-01-07 21:19:34 +0000614+ MS fgets locks/unlocks only once per line; it's the only hook we have.
615
616So we use fgets for speed(!), despite that it's painful.
617
618MS realloc is also slow.
619
Tim Petersf29b64d2001-01-15 06:33:19 +0000620Reports from other platforms on this method vs getc_unlocked (which MS doesn't
621have):
622 Linux a wash
623 Solaris a wash
624 Tru64 Unix getline_via_fgets significantly faster
Tim Peters86821b22001-01-07 21:19:34 +0000625
Tim Petersf29b64d2001-01-15 06:33:19 +0000626CAUTION: The C std isn't clear about this: in those cases where fgets
627writes something into the buffer, can it write into any position beyond the
628required trailing null byte? MSVC 6 fgets does not, and no platform is (yet)
629known on which it does; and it would be a strange way to code fgets. Still,
630getline_via_fgets may not work correctly if it does. The std test
631test_bufio.py should fail if platform fgets() routinely writes beyond the
632trailing null byte. #define DONT_USE_FGETS_IN_GETLINE to disable this code.
Tim Peters86821b22001-01-07 21:19:34 +0000633**************************************************************************/
634
Tim Petersf29b64d2001-01-15 06:33:19 +0000635/* Use this routine if told to, or by default on non-get_unlocked()
636 * platforms unless told not to. Yikes! Let's spell that out:
637 * On a platform with getc_unlocked():
638 * By default, use getc_unlocked().
639 * If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
640 * On a platform without getc_unlocked():
641 * By default, use fgets().
642 * If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
643 */
644#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
645#define USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000646#endif
647
Tim Petersf29b64d2001-01-15 06:33:19 +0000648#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
649#undef USE_FGETS_IN_GETLINE
650#endif
651
652#ifdef USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000653static PyObject*
Tim Petersf29b64d2001-01-15 06:33:19 +0000654getline_via_fgets(FILE *fp)
Tim Peters86821b22001-01-07 21:19:34 +0000655{
Tim Peters15b83852001-01-08 00:53:12 +0000656/* INITBUFSIZE is the maximum line length that lets us get away with the fast
Tim Peters142297a2001-01-15 10:36:56 +0000657 * no-realloc, one-fgets()-call path. Boosting it isn't free, because we have
658 * to fill this much of the buffer with a known value in order to figure out
659 * how much of the buffer fgets() overwrites. So if INITBUFSIZE is larger
660 * than "most" lines, we waste time filling unused buffer slots. 100 is
661 * surely adequate for most peoples' email archives, chewing over source code,
662 * etc -- "regular old text files".
663 * MAXBUFSIZE is the maximum line length that lets us get away with the less
664 * fast (but still zippy) no-realloc, two-fgets()-call path. See above for
665 * cautions about boosting that. 300 was chosen because the worst real-life
666 * text-crunching job reported on Python-Dev was a mail-log crawler where over
667 * half the lines were 254 chars.
668 * INCBUFSIZE is the amount by which we grow the buffer, if MAXBUFSIZE isn't
669 * enough. It doesn't much matter what this is set to: we only get here for
670 * absurdly long lines anyway.
Tim Peters15b83852001-01-08 00:53:12 +0000671 */
Tim Peters142297a2001-01-15 10:36:56 +0000672#define INITBUFSIZE 100
673#define MAXBUFSIZE 300
Tim Peters86821b22001-01-07 21:19:34 +0000674#define INCBUFSIZE 1000
Tim Peters142297a2001-01-15 10:36:56 +0000675 char* p; /* temp */
676 char buf[MAXBUFSIZE];
Tim Peters86821b22001-01-07 21:19:34 +0000677 PyObject* v; /* the string object result */
Tim Peters86821b22001-01-07 21:19:34 +0000678 char* pvfree; /* address of next free slot */
679 char* pvend; /* address one beyond last free slot */
Tim Peters142297a2001-01-15 10:36:56 +0000680 size_t nfree; /* # of free buffer slots; pvend-pvfree */
681 size_t total_v_size; /* total # of slots in buffer */
Tim Peters86821b22001-01-07 21:19:34 +0000682
Tim Peters15b83852001-01-08 00:53:12 +0000683 /* Optimize for normal case: avoid _PyString_Resize if at all
Tim Peters142297a2001-01-15 10:36:56 +0000684 * possible via first reading into stack buffer "buf".
Tim Peters15b83852001-01-08 00:53:12 +0000685 */
Tim Peters142297a2001-01-15 10:36:56 +0000686 total_v_size = INITBUFSIZE; /* start small and pray */
687 pvfree = buf;
688 for (;;) {
689 Py_BEGIN_ALLOW_THREADS
690 pvend = buf + total_v_size;
691 nfree = pvend - pvfree;
692 memset(pvfree, '\n', nfree);
693 p = fgets(pvfree, nfree, fp);
694 Py_END_ALLOW_THREADS
Tim Peters15b83852001-01-08 00:53:12 +0000695
Tim Peters142297a2001-01-15 10:36:56 +0000696 if (p == NULL) {
697 clearerr(fp);
698 if (PyErr_CheckSignals())
699 return NULL;
700 v = PyString_FromStringAndSize(buf, pvfree - buf);
Tim Peters86821b22001-01-07 21:19:34 +0000701 return v;
702 }
Tim Peters142297a2001-01-15 10:36:56 +0000703 /* fgets read *something* */
704 p = memchr(pvfree, '\n', nfree);
705 if (p != NULL) {
706 /* Did the \n come from fgets or from us?
707 * Since fgets stops at the first \n, and then writes
708 * \0, if it's from fgets a \0 must be next. But if
709 * that's so, it could not have come from us, since
710 * the \n's we filled the buffer with have only more
711 * \n's to the right.
712 */
713 if (p+1 < pvend && *(p+1) == '\0') {
714 /* It's from fgets: we win! In particular,
715 * we haven't done any mallocs yet, and can
716 * build the final result on the first try.
717 */
718 ++p; /* include \n from fgets */
719 }
720 else {
721 /* Must be from us: fgets didn't fill the
722 * buffer and didn't find a newline, so it
723 * must be the last and newline-free line of
724 * the file.
725 */
726 assert(p > pvfree && *(p-1) == '\0');
727 --p; /* don't include \0 from fgets */
728 }
729 v = PyString_FromStringAndSize(buf, p - buf);
730 return v;
731 }
732 /* yuck: fgets overwrote all the newlines, i.e. the entire
733 * buffer. So this line isn't over yet, or maybe it is but
734 * we're exactly at EOF. If we haven't already, try using the
735 * rest of the stack buffer.
Tim Peters86821b22001-01-07 21:19:34 +0000736 */
Tim Peters142297a2001-01-15 10:36:56 +0000737 assert(*(pvend-1) == '\0');
738 if (pvfree == buf) {
739 pvfree = pvend - 1; /* overwrite trailing null */
740 total_v_size = MAXBUFSIZE;
741 }
742 else
743 break;
Tim Peters86821b22001-01-07 21:19:34 +0000744 }
Tim Peters142297a2001-01-15 10:36:56 +0000745
746 /* The stack buffer isn't big enough; malloc a string object and read
747 * into its buffer.
Tim Peters15b83852001-01-08 00:53:12 +0000748 */
Tim Peters142297a2001-01-15 10:36:56 +0000749 total_v_size = MAXBUFSIZE + INCBUFSIZE;
Tim Peters1c733232001-01-08 04:02:07 +0000750 v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
Tim Peters15b83852001-01-08 00:53:12 +0000751 if (v == NULL)
752 return v;
753 /* copy over everything except the last null byte */
Tim Peters142297a2001-01-15 10:36:56 +0000754 memcpy(BUF(v), buf, MAXBUFSIZE-1);
755 pvfree = BUF(v) + MAXBUFSIZE - 1;
Tim Peters86821b22001-01-07 21:19:34 +0000756
757 /* Keep reading stuff into v; if it ever ends successfully, break
Tim Peters15b83852001-01-08 00:53:12 +0000758 * after setting p one beyond the end of the line. The code here is
759 * very much like the code above, except reads into v's buffer; see
760 * the code above for detailed comments about the logic.
Tim Peters86821b22001-01-07 21:19:34 +0000761 */
762 for (;;) {
Tim Peters86821b22001-01-07 21:19:34 +0000763 Py_BEGIN_ALLOW_THREADS
764 pvend = BUF(v) + total_v_size;
765 nfree = pvend - pvfree;
766 memset(pvfree, '\n', nfree);
767 p = fgets(pvfree, nfree, fp);
768 Py_END_ALLOW_THREADS
769
770 if (p == NULL) {
771 clearerr(fp);
772 if (PyErr_CheckSignals()) {
773 Py_DECREF(v);
774 return NULL;
775 }
776 p = pvfree;
777 break;
778 }
Tim Peters86821b22001-01-07 21:19:34 +0000779 p = memchr(pvfree, '\n', nfree);
780 if (p != NULL) {
781 if (p+1 < pvend && *(p+1) == '\0') {
782 /* \n came from fgets */
783 ++p;
784 break;
785 }
786 /* \n came from us; last line of file, no newline */
787 assert(p > pvfree && *(p-1) == '\0');
788 --p;
789 break;
790 }
791 /* expand buffer and try again */
792 assert(*(pvend-1) == '\0');
793 total_v_size += INCBUFSIZE;
794 if (total_v_size > INT_MAX) {
795 PyErr_SetString(PyExc_OverflowError,
796 "line is longer than a Python string can hold");
797 Py_DECREF(v);
798 return NULL;
799 }
800 if (_PyString_Resize(&v, (int)total_v_size) < 0)
801 return NULL;
802 /* overwrite the trailing null byte */
803 pvfree = BUF(v) + (total_v_size - INCBUFSIZE - 1);
804 }
805 if (BUF(v) + total_v_size != p)
806 _PyString_Resize(&v, p - BUF(v));
807 return v;
808#undef INITBUFSIZE
Tim Peters142297a2001-01-15 10:36:56 +0000809#undef MAXBUFSIZE
Tim Peters86821b22001-01-07 21:19:34 +0000810#undef INCBUFSIZE
811}
Tim Petersf29b64d2001-01-15 06:33:19 +0000812#endif /* ifdef USE_FGETS_IN_GETLINE */
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000813
Guido van Rossum0bd24411991-04-04 15:21:57 +0000814/* Internal routine to get a line.
815 Size argument interpretation:
816 > 0: max length;
Guido van Rossum86282062001-01-08 01:26:47 +0000817 <= 0: read arbitrary line
Guido van Rossumce5ba841991-03-06 13:06:18 +0000818*/
819
Guido van Rossum1187aa42001-01-05 14:43:05 +0000820#ifdef HAVE_GETC_UNLOCKED
821#define GETC(f) getc_unlocked(f)
822#define FLOCKFILE(f) flockfile(f)
823#define FUNLOCKFILE(f) funlockfile(f)
824#else
825#define GETC(f) getc(f)
826#define FLOCKFILE(f)
827#define FUNLOCKFILE(f)
828#endif
829
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000830static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000831get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000832{
Guido van Rossum1187aa42001-01-05 14:43:05 +0000833 FILE *fp = f->f_fp;
834 int c;
Andrew M. Kuchling4b2b4452000-11-29 02:53:22 +0000835 char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000836 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000837 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000838
Tim Petersf29b64d2001-01-15 06:33:19 +0000839#ifdef USE_FGETS_IN_GETLINE
Guido van Rossum86282062001-01-08 01:26:47 +0000840 if (n <= 0)
Tim Petersf29b64d2001-01-15 06:33:19 +0000841 return getline_via_fgets(fp);
Tim Peters86821b22001-01-07 21:19:34 +0000842#endif
Guido van Rossum0bd24411991-04-04 15:21:57 +0000843 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000844 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000845 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000847 buf = BUF(v);
848 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000849
Guido van Rossumce5ba841991-03-06 13:06:18 +0000850 for (;;) {
Guido van Rossum1187aa42001-01-05 14:43:05 +0000851 Py_BEGIN_ALLOW_THREADS
852 FLOCKFILE(fp);
853 while ((c = GETC(fp)) != EOF &&
854 (*buf++ = c) != '\n' &&
855 buf != end)
856 ;
857 FUNLOCKFILE(fp);
858 Py_END_ALLOW_THREADS
859 if (c == '\n')
860 break;
861 if (c == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000862 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000863 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000864 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000865 return NULL;
866 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000867 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000868 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000869 /* Must be because buf == end */
870 if (n > 0)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000871 break;
Guido van Rossum1187aa42001-01-05 14:43:05 +0000872 n1 = n2;
873 n2 += 1000;
874 if (n2 > INT_MAX) {
875 PyErr_SetString(PyExc_OverflowError,
876 "line is longer than a Python string can hold");
Tim Peters86821b22001-01-07 21:19:34 +0000877 Py_DECREF(v);
Guido van Rossum1187aa42001-01-05 14:43:05 +0000878 return NULL;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000879 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000880 if (_PyString_Resize(&v, n2) < 0)
881 return NULL;
882 buf = BUF(v) + n1;
883 end = BUF(v) + n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000884 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000885
Guido van Rossumce5ba841991-03-06 13:06:18 +0000886 n1 = buf - BUF(v);
887 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000888 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000889 return v;
890}
891
Guido van Rossum0bd24411991-04-04 15:21:57 +0000892/* External C interface */
893
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000894PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000895PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000896{
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000897 PyObject *result;
898
Guido van Rossum3165fe61992-09-25 21:59:05 +0000899 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000900 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000901 return NULL;
902 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000903
904 if (PyFile_Check(f)) {
905 if (((PyFileObject*)f)->f_fp == NULL)
906 return err_closed();
907 result = get_line((PyFileObject *)f, n);
908 }
909 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000910 PyObject *reader;
911 PyObject *args;
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000912
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000913 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000914 if (reader == NULL)
915 return NULL;
916 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000917 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000918 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000919 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000920 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000921 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000922 return NULL;
923 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000924 result = PyEval_CallObject(reader, args);
925 Py_DECREF(reader);
926 Py_DECREF(args);
927 if (result != NULL && !PyString_Check(result)) {
928 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000929 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000930 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000931 "object.readline() returned non-string");
932 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000933 }
934
935 if (n < 0 && result != NULL && PyString_Check(result)) {
936 char *s = PyString_AS_STRING(result);
937 int len = PyString_GET_SIZE(result);
938 if (len == 0) {
939 Py_DECREF(result);
940 result = NULL;
941 PyErr_SetString(PyExc_EOFError,
942 "EOF when reading a line");
943 }
944 else if (s[len-1] == '\n') {
945 if (result->ob_refcnt == 1)
946 _PyString_Resize(&result, len-1);
947 else {
948 PyObject *v;
949 v = PyString_FromStringAndSize(s, len-1);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000950 Py_DECREF(result);
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000951 result = v;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000952 }
953 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000954 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000955 return result;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000956}
957
958/* Python method */
959
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000960static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000961file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000962{
Guido van Rossum789a1611997-05-10 22:33:55 +0000963 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000964
Guido van Rossumd7297e61992-07-06 14:19:26 +0000965 if (f->f_fp == NULL)
966 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000967 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000968 return NULL;
969 if (n == 0)
970 return PyString_FromString("");
971 if (n < 0)
972 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000973 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000974}
975
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000976static PyObject *
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000977file_xreadlines(PyFileObject *f, PyObject *args)
978{
979 static PyObject* xreadlines_function = NULL;
Tim Petersf29b64d2001-01-15 06:33:19 +0000980
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000981 if (!PyArg_ParseTuple(args, ":xreadlines"))
982 return NULL;
Tim Petersf29b64d2001-01-15 06:33:19 +0000983
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000984 if (!xreadlines_function) {
985 PyObject *xreadlines_module =
986 PyImport_ImportModule("xreadlines");
987 if(!xreadlines_module)
988 return NULL;
989
990 xreadlines_function = PyObject_GetAttrString(xreadlines_module,
991 "xreadlines");
992 Py_DECREF(xreadlines_module);
993 if(!xreadlines_function)
994 return NULL;
995 }
996 return PyObject_CallFunction(xreadlines_function, "(O)", f);
997}
998
999static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001000file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001001{
Guido van Rossum789a1611997-05-10 22:33:55 +00001002 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003 PyObject *list;
1004 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +00001005 char small_buffer[SMALLCHUNK];
1006 char *buffer = small_buffer;
1007 size_t buffersize = SMALLCHUNK;
1008 PyObject *big_buffer = NULL;
1009 size_t nfilled = 0;
1010 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +00001011 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +00001012 char *p, *q, *end;
1013 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +00001014
Guido van Rossumd7297e61992-07-06 14:19:26 +00001015 if (f->f_fp == NULL)
1016 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +00001017 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +00001018 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001019 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001020 return NULL;
1021 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001022 Py_BEGIN_ALLOW_THREADS
1023 errno = 0;
1024 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
1025 Py_END_ALLOW_THREADS
1026 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +00001027 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +00001028 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +00001029 break;
1030 PyErr_SetFromErrno(PyExc_IOError);
1031 clearerr(f->f_fp);
1032 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001033 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +00001034 list = NULL;
1035 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001036 }
Guido van Rossum789a1611997-05-10 22:33:55 +00001037 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +00001038 p = memchr(buffer+nfilled, '\n', nread);
1039 if (p == NULL) {
1040 /* Need a larger buffer to fit this line */
1041 nfilled += nread;
1042 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +00001043 if (buffersize > INT_MAX) {
1044 PyErr_SetString(PyExc_OverflowError,
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001045 "line is longer than a Python string can hold");
Trent Mickf29f47b2000-08-11 19:02:59 +00001046 goto error;
1047 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001048 if (big_buffer == NULL) {
1049 /* Create the big buffer */
1050 big_buffer = PyString_FromStringAndSize(
1051 NULL, buffersize);
1052 if (big_buffer == NULL)
1053 goto error;
1054 buffer = PyString_AS_STRING(big_buffer);
1055 memcpy(buffer, small_buffer, nfilled);
1056 }
1057 else {
1058 /* Grow the big buffer */
1059 _PyString_Resize(&big_buffer, buffersize);
1060 buffer = PyString_AS_STRING(big_buffer);
1061 }
1062 continue;
1063 }
1064 end = buffer+nfilled+nread;
1065 q = buffer;
1066 do {
1067 /* Process complete lines */
1068 p++;
1069 line = PyString_FromStringAndSize(q, p-q);
1070 if (line == NULL)
1071 goto error;
1072 err = PyList_Append(list, line);
1073 Py_DECREF(line);
1074 if (err != 0)
1075 goto error;
1076 q = p;
1077 p = memchr(q, '\n', end-q);
1078 } while (p != NULL);
1079 /* Move the remaining incomplete line to the start */
1080 nfilled = end-q;
1081 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +00001082 if (sizehint > 0)
1083 if (totalread >= (size_t)sizehint)
1084 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001085 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001086 if (nfilled != 0) {
1087 /* Partial last line */
1088 line = PyString_FromStringAndSize(buffer, nfilled);
1089 if (line == NULL)
1090 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +00001091 if (sizehint > 0) {
1092 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +00001093 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +00001094 if (rest == NULL) {
1095 Py_DECREF(line);
1096 goto error;
1097 }
1098 PyString_Concat(&line, rest);
1099 Py_DECREF(rest);
1100 if (line == NULL)
1101 goto error;
1102 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001103 err = PyList_Append(list, line);
1104 Py_DECREF(line);
1105 if (err != 0)
1106 goto error;
1107 }
1108 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001109 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001110 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001111 }
Guido van Rossumce5ba841991-03-06 13:06:18 +00001112 return list;
1113}
1114
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001115static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001116file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001117{
Guido van Rossumd7297e61992-07-06 14:19:26 +00001118 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001120 if (f->f_fp == NULL)
1121 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +00001122 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001123 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001124 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001125 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001126 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001127 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001128 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001129 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001130 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +00001131 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132 return NULL;
1133 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001134 Py_INCREF(Py_None);
1135 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001136}
1137
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001138static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001139file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001140{
Guido van Rossumee70ad12000-03-13 16:27:06 +00001141#define CHUNKSIZE 1000
1142 PyObject *list, *line;
1143 PyObject *result;
1144 int i, j, index, len, nwritten, islist;
1145
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001146 if (f->f_fp == NULL)
1147 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +00001148 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001149 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001150 "writelines() argument must be a sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001151 return NULL;
1152 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001153 islist = PyList_Check(args);
1154
1155 /* Strategy: slurp CHUNKSIZE lines into a private list,
1156 checking that they are all strings, then write that list
1157 without holding the interpreter lock, then come back for more. */
1158 index = 0;
1159 if (islist)
1160 list = NULL;
1161 else {
1162 list = PyList_New(CHUNKSIZE);
1163 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001164 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001165 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001166 result = NULL;
1167
1168 for (;;) {
1169 if (islist) {
1170 Py_XDECREF(list);
1171 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
1172 if (list == NULL)
1173 return NULL;
1174 j = PyList_GET_SIZE(list);
1175 }
1176 else {
1177 for (j = 0; j < CHUNKSIZE; j++) {
1178 line = PySequence_GetItem(args, index+j);
1179 if (line == NULL) {
1180 if (PyErr_ExceptionMatches(
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001181 PyExc_IndexError)) {
Guido van Rossumee70ad12000-03-13 16:27:06 +00001182 PyErr_Clear();
1183 break;
1184 }
1185 /* Some other error occurred.
1186 XXX We may lose some output. */
1187 goto error;
1188 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001189 PyList_SetItem(list, j, line);
1190 }
1191 }
1192 if (j == 0)
1193 break;
1194
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001195 /* Check that all entries are indeed strings. If not,
1196 apply the same rules as for file.write() and
1197 convert the results to strings. This is slow, but
1198 seems to be the only way since all conversion APIs
1199 could potentially execute Python code. */
1200 for (i = 0; i < j; i++) {
1201 PyObject *v = PyList_GET_ITEM(list, i);
1202 if (!PyString_Check(v)) {
1203 const char *buffer;
1204 int len;
Tim Peters86821b22001-01-07 21:19:34 +00001205 if (((f->f_binary &&
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001206 PyObject_AsReadBuffer(v,
1207 (const void**)&buffer,
1208 &len)) ||
1209 PyObject_AsCharBuffer(v,
1210 &buffer,
1211 &len))) {
1212 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001213 "writelines() argument must be a sequence of strings");
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001214 goto error;
1215 }
1216 line = PyString_FromStringAndSize(buffer,
1217 len);
1218 if (line == NULL)
1219 goto error;
1220 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001221 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001222 }
1223 }
1224
1225 /* Since we are releasing the global lock, the
1226 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001227 Py_BEGIN_ALLOW_THREADS
1228 f->f_softspace = 0;
1229 errno = 0;
1230 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001231 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001232 len = PyString_GET_SIZE(line);
1233 nwritten = fwrite(PyString_AS_STRING(line),
1234 1, len, f->f_fp);
1235 if (nwritten != len) {
1236 Py_BLOCK_THREADS
1237 PyErr_SetFromErrno(PyExc_IOError);
1238 clearerr(f->f_fp);
1239 goto error;
1240 }
1241 }
1242 Py_END_ALLOW_THREADS
1243
1244 if (j < CHUNKSIZE)
1245 break;
1246 index += CHUNKSIZE;
1247 }
1248
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001249 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001250 result = Py_None;
1251 error:
1252 Py_XDECREF(list);
1253 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001254}
1255
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001256static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +00001257 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001258 {"read", (PyCFunction)file_read, 1},
1259 {"write", (PyCFunction)file_write, 0},
1260 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +00001261 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001262#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +00001263 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001264#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001265 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001266 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001267 {"readlines", (PyCFunction)file_readlines, 1},
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001268 {"xreadlines", (PyCFunction)file_xreadlines, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001269 {"writelines", (PyCFunction)file_writelines, 0},
1270 {"flush", (PyCFunction)file_flush, 0},
1271 {"close", (PyCFunction)file_close, 0},
1272 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001273 {NULL, NULL} /* sentinel */
1274};
1275
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001276#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001277
1278static struct memberlist file_memberlist[] = {
1279 {"softspace", T_INT, OFF(f_softspace)},
1280 {"mode", T_OBJECT, OFF(f_mode), RO},
1281 {"name", T_OBJECT, OFF(f_name), RO},
1282 /* getattr(f, "closed") is implemented without this table */
1283 {"closed", T_INT, 0, RO},
1284 {NULL} /* Sentinel */
1285};
1286
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001287static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001288file_getattr(PyFileObject *f, char *name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001289{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001290 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001291
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001292 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001293 if (res != NULL)
1294 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001295 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001296 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001297 return PyInt_FromLong((long)(f->f_fp == 0));
1298 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001299}
1300
1301static int
Fred Drakefd99de62000-07-09 05:02:18 +00001302file_setattr(PyFileObject *f, char *name, PyObject *v)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001303{
1304 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001305 PyErr_SetString(PyExc_AttributeError,
1306 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001307 return -1;
1308 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001309 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310}
1311
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001312PyTypeObject PyFile_Type = {
1313 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314 0,
1315 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001316 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001317 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001318 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001319 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001320 (getattrfunc)file_getattr, /*tp_getattr*/
1321 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001322 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001323 (reprfunc)file_repr, /*tp_repr*/
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}
1492
1493
1494