blob: 0bb2f252b2ce72e6deb714126ea32c4520b5fff7 [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 *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000192file_close(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000194 int sts = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000196 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000197 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000198 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000199 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000200 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000201 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 f->f_fp = NULL;
203 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000204 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000206 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207 return PyInt_FromLong((long)sts);
208 Py_INCREF(Py_None);
209 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210}
211
Trent Mickf29f47b2000-08-11 19:02:59 +0000212
Guido van Rossum4f53da02001-03-01 18:26:53 +0000213/* An 8-byte off_t-like type */
214#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
215typedef fpos_t Py_off_t;
216#else
217typedef off_t Py_off_t;
218#endif
219
220
Trent Mickf29f47b2000-08-11 19:02:59 +0000221/* a portable fseek() function
222 return 0 on success, non-zero on failure (with errno set) */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000223static int
Guido van Rossum4f53da02001-03-01 18:26:53 +0000224_portable_fseek(FILE *fp, Py_off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000225{
226#if defined(HAVE_FSEEKO)
227 return fseeko(fp, offset, whence);
228#elif defined(HAVE_FSEEK64)
229 return fseek64(fp, offset, whence);
Fred Drakedb810ac2000-10-06 20:42:33 +0000230#elif defined(__BEOS__)
231 return _fseek(fp, offset, whence);
Tim Peters86821b22001-01-07 21:19:34 +0000232#elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
Guido van Rossume54e0be2001-01-16 20:53:31 +0000233 /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
234 and fgetpos() to implement fseek()*/
Trent Mickf29f47b2000-08-11 19:02:59 +0000235 fpos_t pos;
236 switch (whence) {
Guido van Rossume54e0be2001-01-16 20:53:31 +0000237 case SEEK_END:
238 if (fseek(fp, 0, SEEK_END) != 0)
239 return -1;
240 /* fall through */
241 case SEEK_CUR:
242 if (fgetpos(fp, &pos) != 0)
243 return -1;
244 offset += pos;
245 break;
246 /* case SEEK_SET: break; */
Trent Mickf29f47b2000-08-11 19:02:59 +0000247 }
248 return fsetpos(fp, &offset);
249#else
250 return fseek(fp, offset, whence);
251#endif
252}
253
254
255/* a portable ftell() function
256 Return -1 on failure with errno set appropriately, current file
257 position on success */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000258static Py_off_t
Fred Drake8ce159a2000-08-31 05:18:54 +0000259_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000260{
Guido van Rossum4f53da02001-03-01 18:26:53 +0000261#if SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000262 fpos_t pos;
263 if (fgetpos(fp, &pos) != 0)
264 return -1;
265 return pos;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000266#elif defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
267 return ftello(fp);
268#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
269 return ftell64(fp);
Trent Mickf29f47b2000-08-11 19:02:59 +0000270#else
271 return ftell(fp);
272#endif
273}
274
275
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000276static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000277file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000279 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000280 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000281 Py_off_t offset;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000282 PyObject *offobj;
Tim Peters86821b22001-01-07 21:19:34 +0000283
Guido van Rossumd7297e61992-07-06 14:19:26 +0000284 if (f->f_fp == NULL)
285 return err_closed();
286 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000287 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000288 return NULL;
289#if !defined(HAVE_LARGEFILE_SUPPORT)
290 offset = PyInt_AsLong(offobj);
291#else
292 offset = PyLong_Check(offobj) ?
293 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
294#endif
295 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000296 return NULL;
Tim Peters86821b22001-01-07 21:19:34 +0000297
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000298 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000299 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000300 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000301 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000302
Guido van Rossumff4949e1992-08-05 19:58:53 +0000303 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000304 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000305 clearerr(f->f_fp);
306 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000307 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000308 Py_INCREF(Py_None);
309 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000310}
311
Trent Mickf29f47b2000-08-11 19:02:59 +0000312
Guido van Rossumd7047b31995-01-02 19:07:15 +0000313#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000315file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000316{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000317 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000318 Py_off_t newsize;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000319 PyObject *newsizeobj;
Tim Peters86821b22001-01-07 21:19:34 +0000320
Guido van Rossumd7047b31995-01-02 19:07:15 +0000321 if (f->f_fp == NULL)
322 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000323 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000324 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000325 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000326 if (newsizeobj != NULL) {
327#if !defined(HAVE_LARGEFILE_SUPPORT)
328 newsize = PyInt_AsLong(newsizeobj);
329#else
330 newsize = PyLong_Check(newsizeobj) ?
331 PyLong_AsLongLong(newsizeobj) :
332 PyInt_AsLong(newsizeobj);
333#endif
334 if (PyErr_Occurred())
335 return NULL;
336 } else {
337 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000338 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000339 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000340 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000341 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000342 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000343 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000344 clearerr(f->f_fp);
345 return NULL;
346 }
347 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000348 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000349 errno = 0;
350 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000352 if (ret != 0) goto onioerror;
353
354#ifdef MS_WIN32
355 /* can use _chsize; if, however, the newsize overflows 32-bits then
356 _chsize is *not* adequate; in this case, an OverflowError is raised */
357 if (newsize > LONG_MAX) {
358 PyErr_SetString(PyExc_OverflowError,
359 "the new size is too long for _chsize (it is limited to 32-bit values)");
Guido van Rossumd7047b31995-01-02 19:07:15 +0000360 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000361 } else {
362 Py_BEGIN_ALLOW_THREADS
363 errno = 0;
364 ret = _chsize(fileno(f->f_fp), newsize);
365 Py_END_ALLOW_THREADS
366 if (ret != 0) goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000367 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000368#else
369 Py_BEGIN_ALLOW_THREADS
370 errno = 0;
371 ret = ftruncate(fileno(f->f_fp), newsize);
372 Py_END_ALLOW_THREADS
373 if (ret != 0) goto onioerror;
374#endif /* !MS_WIN32 */
Tim Peters86821b22001-01-07 21:19:34 +0000375
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000376 Py_INCREF(Py_None);
377 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000378
379onioerror:
380 PyErr_SetFromErrno(PyExc_IOError);
381 clearerr(f->f_fp);
382 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000383}
384#endif /* HAVE_FTRUNCATE */
385
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000386static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000387file_tell(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000388{
Guido van Rossum4f53da02001-03-01 18:26:53 +0000389 Py_off_t pos;
Trent Mickf29f47b2000-08-11 19:02:59 +0000390
Guido van Rossumd7297e61992-07-06 14:19:26 +0000391 if (f->f_fp == NULL)
392 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000393 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000394 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000395 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000396 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000397 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000398 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000399 clearerr(f->f_fp);
400 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000401 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000402#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000403 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000404#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000405 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000406#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000407}
408
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000409static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000410file_fileno(PyFileObject *f)
Guido van Rossumed233a51992-06-23 09:07:03 +0000411{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000412 if (f->f_fp == NULL)
413 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000414 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000415}
416
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000417static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000418file_flush(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000419{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000420 int res;
Tim Peters86821b22001-01-07 21:19:34 +0000421
Guido van Rossumd7297e61992-07-06 14:19:26 +0000422 if (f->f_fp == NULL)
423 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000424 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000425 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000426 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000427 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000428 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000429 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000430 clearerr(f->f_fp);
431 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000432 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000433 Py_INCREF(Py_None);
434 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000435}
436
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000438file_isatty(PyFileObject *f)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000439{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000440 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000441 if (f->f_fp == NULL)
442 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000443 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000444 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000445 Py_END_ALLOW_THREADS
446 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000447}
448
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000449
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000450#if BUFSIZ < 8192
451#define SMALLCHUNK 8192
452#else
453#define SMALLCHUNK BUFSIZ
454#endif
455
Guido van Rossum3c259041999-01-14 19:00:14 +0000456#if SIZEOF_INT < 4
457#define BIGCHUNK (512 * 32)
458#else
459#define BIGCHUNK (512 * 1024)
460#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000461
462static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000463new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000464{
465#ifdef HAVE_FSTAT
Fred Drake1bc8fab2001-07-19 21:49:38 +0000466 off_t pos, end;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000467 struct stat st;
468 if (fstat(fileno(f->f_fp), &st) == 0) {
469 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000470 /* The following is not a bug: we really need to call lseek()
471 *and* ftell(). The reason is that some stdio libraries
472 mistakenly flush their buffer when ftell() is called and
473 the lseek() call it makes fails, thereby throwing away
474 data that cannot be recovered in any way. To avoid this,
475 we first test lseek(), and only call ftell() if lseek()
476 works. We can't use the lseek() value either, because we
477 need to take the amount of buffered data into account.
478 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000479 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
480 if (pos >= 0)
481 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000482 if (pos < 0)
483 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000484 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000485 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000486 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000487 }
488#endif
489 if (currentsize > SMALLCHUNK) {
490 /* Keep doubling until we reach BIGCHUNK;
491 then keep adding BIGCHUNK. */
492 if (currentsize <= BIGCHUNK)
493 return currentsize + currentsize;
494 else
495 return currentsize + BIGCHUNK;
496 }
497 return currentsize + SMALLCHUNK;
498}
499
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000500static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000501file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000502{
Guido van Rossum789a1611997-05-10 22:33:55 +0000503 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000504 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000505 PyObject *v;
Tim Peters86821b22001-01-07 21:19:34 +0000506
Guido van Rossumd7297e61992-07-06 14:19:26 +0000507 if (f->f_fp == NULL)
508 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000509 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000510 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000511 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000512 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000513 else
514 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000515 if (buffersize > INT_MAX) {
516 PyErr_SetString(PyExc_OverflowError,
517 "requested number of bytes is more than a Python string can hold");
518 return NULL;
519 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000520 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000521 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000522 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000523 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000524 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000525 Py_BEGIN_ALLOW_THREADS
526 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000527 chunksize = fread(BUF(v) + bytesread, 1,
528 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000529 Py_END_ALLOW_THREADS
530 if (chunksize == 0) {
531 if (!ferror(f->f_fp))
532 break;
533 PyErr_SetFromErrno(PyExc_IOError);
534 clearerr(f->f_fp);
535 Py_DECREF(v);
536 return NULL;
537 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000538 bytesread += chunksize;
539 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000540 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000541 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000542 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000543 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000544 return NULL;
545 }
546 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000547 if (bytesread != buffersize)
548 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000549 return v;
550}
551
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000552static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000553file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000554{
555 char *ptr;
Trent Mickf29f47b2000-08-11 19:02:59 +0000556 size_t ntodo, ndone, nnow;
Tim Peters86821b22001-01-07 21:19:34 +0000557
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000558 if (f->f_fp == NULL)
559 return err_closed();
560 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
561 return NULL;
562 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000563 while (ntodo > 0) {
564 Py_BEGIN_ALLOW_THREADS
565 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000566 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000567 Py_END_ALLOW_THREADS
568 if (nnow == 0) {
569 if (!ferror(f->f_fp))
570 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000571 PyErr_SetFromErrno(PyExc_IOError);
572 clearerr(f->f_fp);
573 return NULL;
574 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000575 ndone += nnow;
576 ntodo -= nnow;
577 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000578 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000579}
580
Tim Peters86821b22001-01-07 21:19:34 +0000581/**************************************************************************
Tim Petersf29b64d2001-01-15 06:33:19 +0000582Routine to get next line using platform fgets().
Tim Peters86821b22001-01-07 21:19:34 +0000583
584Under MSVC 6:
585
Tim Peters1c733232001-01-08 04:02:07 +0000586+ MS threadsafe getc is very slow (multiple layers of function calls before+
587 after each character, to lock+unlock the stream).
588+ The stream-locking functions are MS-internal -- can't access them from user
589 code.
590+ There's nothing Tim could find in the MS C or platform SDK libraries that
591 can worm around this.
Tim Peters86821b22001-01-07 21:19:34 +0000592+ MS fgets locks/unlocks only once per line; it's the only hook we have.
593
594So we use fgets for speed(!), despite that it's painful.
595
596MS realloc is also slow.
597
Tim Petersf29b64d2001-01-15 06:33:19 +0000598Reports from other platforms on this method vs getc_unlocked (which MS doesn't
599have):
600 Linux a wash
601 Solaris a wash
602 Tru64 Unix getline_via_fgets significantly faster
Tim Peters86821b22001-01-07 21:19:34 +0000603
Tim Petersf29b64d2001-01-15 06:33:19 +0000604CAUTION: The C std isn't clear about this: in those cases where fgets
605writes something into the buffer, can it write into any position beyond the
606required trailing null byte? MSVC 6 fgets does not, and no platform is (yet)
607known on which it does; and it would be a strange way to code fgets. Still,
608getline_via_fgets may not work correctly if it does. The std test
609test_bufio.py should fail if platform fgets() routinely writes beyond the
610trailing null byte. #define DONT_USE_FGETS_IN_GETLINE to disable this code.
Tim Peters86821b22001-01-07 21:19:34 +0000611**************************************************************************/
612
Tim Petersf29b64d2001-01-15 06:33:19 +0000613/* Use this routine if told to, or by default on non-get_unlocked()
614 * platforms unless told not to. Yikes! Let's spell that out:
615 * On a platform with getc_unlocked():
616 * By default, use getc_unlocked().
617 * If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
618 * On a platform without getc_unlocked():
619 * By default, use fgets().
620 * If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
621 */
622#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
623#define USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000624#endif
625
Tim Petersf29b64d2001-01-15 06:33:19 +0000626#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
627#undef USE_FGETS_IN_GETLINE
628#endif
629
630#ifdef USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000631static PyObject*
Tim Petersf29b64d2001-01-15 06:33:19 +0000632getline_via_fgets(FILE *fp)
Tim Peters86821b22001-01-07 21:19:34 +0000633{
Tim Peters15b83852001-01-08 00:53:12 +0000634/* INITBUFSIZE is the maximum line length that lets us get away with the fast
Tim Peters142297a2001-01-15 10:36:56 +0000635 * no-realloc, one-fgets()-call path. Boosting it isn't free, because we have
636 * to fill this much of the buffer with a known value in order to figure out
637 * how much of the buffer fgets() overwrites. So if INITBUFSIZE is larger
638 * than "most" lines, we waste time filling unused buffer slots. 100 is
639 * surely adequate for most peoples' email archives, chewing over source code,
640 * etc -- "regular old text files".
641 * MAXBUFSIZE is the maximum line length that lets us get away with the less
642 * fast (but still zippy) no-realloc, two-fgets()-call path. See above for
643 * cautions about boosting that. 300 was chosen because the worst real-life
644 * text-crunching job reported on Python-Dev was a mail-log crawler where over
645 * half the lines were 254 chars.
646 * INCBUFSIZE is the amount by which we grow the buffer, if MAXBUFSIZE isn't
647 * enough. It doesn't much matter what this is set to: we only get here for
648 * absurdly long lines anyway.
Tim Peters15b83852001-01-08 00:53:12 +0000649 */
Tim Peters142297a2001-01-15 10:36:56 +0000650#define INITBUFSIZE 100
651#define MAXBUFSIZE 300
Tim Peters86821b22001-01-07 21:19:34 +0000652#define INCBUFSIZE 1000
Tim Peters142297a2001-01-15 10:36:56 +0000653 char* p; /* temp */
654 char buf[MAXBUFSIZE];
Tim Peters86821b22001-01-07 21:19:34 +0000655 PyObject* v; /* the string object result */
Tim Peters86821b22001-01-07 21:19:34 +0000656 char* pvfree; /* address of next free slot */
657 char* pvend; /* address one beyond last free slot */
Tim Peters142297a2001-01-15 10:36:56 +0000658 size_t nfree; /* # of free buffer slots; pvend-pvfree */
659 size_t total_v_size; /* total # of slots in buffer */
Tim Peters86821b22001-01-07 21:19:34 +0000660
Tim Peters15b83852001-01-08 00:53:12 +0000661 /* Optimize for normal case: avoid _PyString_Resize if at all
Tim Peters142297a2001-01-15 10:36:56 +0000662 * possible via first reading into stack buffer "buf".
Tim Peters15b83852001-01-08 00:53:12 +0000663 */
Tim Peters142297a2001-01-15 10:36:56 +0000664 total_v_size = INITBUFSIZE; /* start small and pray */
665 pvfree = buf;
666 for (;;) {
667 Py_BEGIN_ALLOW_THREADS
668 pvend = buf + total_v_size;
669 nfree = pvend - pvfree;
670 memset(pvfree, '\n', nfree);
671 p = fgets(pvfree, nfree, fp);
672 Py_END_ALLOW_THREADS
Tim Peters15b83852001-01-08 00:53:12 +0000673
Tim Peters142297a2001-01-15 10:36:56 +0000674 if (p == NULL) {
675 clearerr(fp);
676 if (PyErr_CheckSignals())
677 return NULL;
678 v = PyString_FromStringAndSize(buf, pvfree - buf);
Tim Peters86821b22001-01-07 21:19:34 +0000679 return v;
680 }
Tim Peters142297a2001-01-15 10:36:56 +0000681 /* fgets read *something* */
682 p = memchr(pvfree, '\n', nfree);
683 if (p != NULL) {
684 /* Did the \n come from fgets or from us?
685 * Since fgets stops at the first \n, and then writes
686 * \0, if it's from fgets a \0 must be next. But if
687 * that's so, it could not have come from us, since
688 * the \n's we filled the buffer with have only more
689 * \n's to the right.
690 */
691 if (p+1 < pvend && *(p+1) == '\0') {
692 /* It's from fgets: we win! In particular,
693 * we haven't done any mallocs yet, and can
694 * build the final result on the first try.
695 */
696 ++p; /* include \n from fgets */
697 }
698 else {
699 /* Must be from us: fgets didn't fill the
700 * buffer and didn't find a newline, so it
701 * must be the last and newline-free line of
702 * the file.
703 */
704 assert(p > pvfree && *(p-1) == '\0');
705 --p; /* don't include \0 from fgets */
706 }
707 v = PyString_FromStringAndSize(buf, p - buf);
708 return v;
709 }
710 /* yuck: fgets overwrote all the newlines, i.e. the entire
711 * buffer. So this line isn't over yet, or maybe it is but
712 * we're exactly at EOF. If we haven't already, try using the
713 * rest of the stack buffer.
Tim Peters86821b22001-01-07 21:19:34 +0000714 */
Tim Peters142297a2001-01-15 10:36:56 +0000715 assert(*(pvend-1) == '\0');
716 if (pvfree == buf) {
717 pvfree = pvend - 1; /* overwrite trailing null */
718 total_v_size = MAXBUFSIZE;
719 }
720 else
721 break;
Tim Peters86821b22001-01-07 21:19:34 +0000722 }
Tim Peters142297a2001-01-15 10:36:56 +0000723
724 /* The stack buffer isn't big enough; malloc a string object and read
725 * into its buffer.
Tim Peters15b83852001-01-08 00:53:12 +0000726 */
Tim Peters142297a2001-01-15 10:36:56 +0000727 total_v_size = MAXBUFSIZE + INCBUFSIZE;
Tim Peters1c733232001-01-08 04:02:07 +0000728 v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
Tim Peters15b83852001-01-08 00:53:12 +0000729 if (v == NULL)
730 return v;
731 /* copy over everything except the last null byte */
Tim Peters142297a2001-01-15 10:36:56 +0000732 memcpy(BUF(v), buf, MAXBUFSIZE-1);
733 pvfree = BUF(v) + MAXBUFSIZE - 1;
Tim Peters86821b22001-01-07 21:19:34 +0000734
735 /* Keep reading stuff into v; if it ever ends successfully, break
Tim Peters15b83852001-01-08 00:53:12 +0000736 * after setting p one beyond the end of the line. The code here is
737 * very much like the code above, except reads into v's buffer; see
738 * the code above for detailed comments about the logic.
Tim Peters86821b22001-01-07 21:19:34 +0000739 */
740 for (;;) {
Tim Peters86821b22001-01-07 21:19:34 +0000741 Py_BEGIN_ALLOW_THREADS
742 pvend = BUF(v) + total_v_size;
743 nfree = pvend - pvfree;
744 memset(pvfree, '\n', nfree);
745 p = fgets(pvfree, nfree, fp);
746 Py_END_ALLOW_THREADS
747
748 if (p == NULL) {
749 clearerr(fp);
750 if (PyErr_CheckSignals()) {
751 Py_DECREF(v);
752 return NULL;
753 }
754 p = pvfree;
755 break;
756 }
Tim Peters86821b22001-01-07 21:19:34 +0000757 p = memchr(pvfree, '\n', nfree);
758 if (p != NULL) {
759 if (p+1 < pvend && *(p+1) == '\0') {
760 /* \n came from fgets */
761 ++p;
762 break;
763 }
764 /* \n came from us; last line of file, no newline */
765 assert(p > pvfree && *(p-1) == '\0');
766 --p;
767 break;
768 }
769 /* expand buffer and try again */
770 assert(*(pvend-1) == '\0');
771 total_v_size += INCBUFSIZE;
772 if (total_v_size > INT_MAX) {
773 PyErr_SetString(PyExc_OverflowError,
774 "line is longer than a Python string can hold");
775 Py_DECREF(v);
776 return NULL;
777 }
778 if (_PyString_Resize(&v, (int)total_v_size) < 0)
779 return NULL;
780 /* overwrite the trailing null byte */
781 pvfree = BUF(v) + (total_v_size - INCBUFSIZE - 1);
782 }
783 if (BUF(v) + total_v_size != p)
784 _PyString_Resize(&v, p - BUF(v));
785 return v;
786#undef INITBUFSIZE
Tim Peters142297a2001-01-15 10:36:56 +0000787#undef MAXBUFSIZE
Tim Peters86821b22001-01-07 21:19:34 +0000788#undef INCBUFSIZE
789}
Tim Petersf29b64d2001-01-15 06:33:19 +0000790#endif /* ifdef USE_FGETS_IN_GETLINE */
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000791
Guido van Rossum0bd24411991-04-04 15:21:57 +0000792/* Internal routine to get a line.
793 Size argument interpretation:
794 > 0: max length;
Guido van Rossum86282062001-01-08 01:26:47 +0000795 <= 0: read arbitrary line
Guido van Rossumce5ba841991-03-06 13:06:18 +0000796*/
797
Guido van Rossum1187aa42001-01-05 14:43:05 +0000798#ifdef HAVE_GETC_UNLOCKED
799#define GETC(f) getc_unlocked(f)
800#define FLOCKFILE(f) flockfile(f)
801#define FUNLOCKFILE(f) funlockfile(f)
802#else
803#define GETC(f) getc(f)
804#define FLOCKFILE(f)
805#define FUNLOCKFILE(f)
806#endif
807
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000808static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000809get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000810{
Guido van Rossum1187aa42001-01-05 14:43:05 +0000811 FILE *fp = f->f_fp;
812 int c;
Andrew M. Kuchling4b2b4452000-11-29 02:53:22 +0000813 char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000814 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000815 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000816
Tim Petersf29b64d2001-01-15 06:33:19 +0000817#ifdef USE_FGETS_IN_GETLINE
Guido van Rossum86282062001-01-08 01:26:47 +0000818 if (n <= 0)
Tim Petersf29b64d2001-01-15 06:33:19 +0000819 return getline_via_fgets(fp);
Tim Peters86821b22001-01-07 21:19:34 +0000820#endif
Guido van Rossum0bd24411991-04-04 15:21:57 +0000821 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000822 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000823 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000825 buf = BUF(v);
826 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000827
Guido van Rossumce5ba841991-03-06 13:06:18 +0000828 for (;;) {
Guido van Rossum1187aa42001-01-05 14:43:05 +0000829 Py_BEGIN_ALLOW_THREADS
830 FLOCKFILE(fp);
831 while ((c = GETC(fp)) != EOF &&
832 (*buf++ = c) != '\n' &&
833 buf != end)
834 ;
835 FUNLOCKFILE(fp);
836 Py_END_ALLOW_THREADS
837 if (c == '\n')
838 break;
839 if (c == EOF) {
Guido van Rossum29206bc2001-08-09 18:14:59 +0000840 if (ferror(fp)) {
841 PyErr_SetFromErrno(PyExc_IOError);
842 clearerr(fp);
843 Py_DECREF(v);
844 return NULL;
845 }
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000846 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000847 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000848 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000849 return NULL;
850 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000851 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000852 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000853 /* Must be because buf == end */
854 if (n > 0)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000855 break;
Guido van Rossum1187aa42001-01-05 14:43:05 +0000856 n1 = n2;
857 n2 += 1000;
858 if (n2 > INT_MAX) {
859 PyErr_SetString(PyExc_OverflowError,
860 "line is longer than a Python string can hold");
Tim Peters86821b22001-01-07 21:19:34 +0000861 Py_DECREF(v);
Guido van Rossum1187aa42001-01-05 14:43:05 +0000862 return NULL;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000863 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000864 if (_PyString_Resize(&v, n2) < 0)
865 return NULL;
866 buf = BUF(v) + n1;
867 end = BUF(v) + n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000868 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000869
Guido van Rossumce5ba841991-03-06 13:06:18 +0000870 n1 = buf - BUF(v);
871 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000872 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000873 return v;
874}
875
Guido van Rossum0bd24411991-04-04 15:21:57 +0000876/* External C interface */
877
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000878PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000879PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000880{
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000881 PyObject *result;
882
Guido van Rossum3165fe61992-09-25 21:59:05 +0000883 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000884 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000885 return NULL;
886 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000887
888 if (PyFile_Check(f)) {
889 if (((PyFileObject*)f)->f_fp == NULL)
890 return err_closed();
891 result = get_line((PyFileObject *)f, n);
892 }
893 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000894 PyObject *reader;
895 PyObject *args;
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000896
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000897 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000898 if (reader == NULL)
899 return NULL;
900 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000901 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000902 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000904 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000905 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000906 return NULL;
907 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908 result = PyEval_CallObject(reader, args);
909 Py_DECREF(reader);
910 Py_DECREF(args);
911 if (result != NULL && !PyString_Check(result)) {
912 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000913 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000914 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000915 "object.readline() returned non-string");
916 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000917 }
918
919 if (n < 0 && result != NULL && PyString_Check(result)) {
920 char *s = PyString_AS_STRING(result);
921 int len = PyString_GET_SIZE(result);
922 if (len == 0) {
923 Py_DECREF(result);
924 result = NULL;
925 PyErr_SetString(PyExc_EOFError,
926 "EOF when reading a line");
927 }
928 else if (s[len-1] == '\n') {
929 if (result->ob_refcnt == 1)
930 _PyString_Resize(&result, len-1);
931 else {
932 PyObject *v;
933 v = PyString_FromStringAndSize(s, len-1);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000934 Py_DECREF(result);
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000935 result = v;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000936 }
937 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000938 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000939 return result;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000940}
941
942/* Python method */
943
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000944static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000945file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000946{
Guido van Rossum789a1611997-05-10 22:33:55 +0000947 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000948
Guido van Rossumd7297e61992-07-06 14:19:26 +0000949 if (f->f_fp == NULL)
950 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000951 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000952 return NULL;
953 if (n == 0)
954 return PyString_FromString("");
955 if (n < 0)
956 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000957 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000958}
959
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000960static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000961file_xreadlines(PyFileObject *f)
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000962{
963 static PyObject* xreadlines_function = NULL;
Tim Petersf29b64d2001-01-15 06:33:19 +0000964
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000965 if (!xreadlines_function) {
966 PyObject *xreadlines_module =
967 PyImport_ImportModule("xreadlines");
968 if(!xreadlines_module)
969 return NULL;
970
971 xreadlines_function = PyObject_GetAttrString(xreadlines_module,
972 "xreadlines");
973 Py_DECREF(xreadlines_module);
974 if(!xreadlines_function)
975 return NULL;
976 }
977 return PyObject_CallFunction(xreadlines_function, "(O)", f);
978}
979
980static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000981file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000982{
Guido van Rossum789a1611997-05-10 22:33:55 +0000983 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000984 PyObject *list;
985 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000986 char small_buffer[SMALLCHUNK];
987 char *buffer = small_buffer;
988 size_t buffersize = SMALLCHUNK;
989 PyObject *big_buffer = NULL;
990 size_t nfilled = 0;
991 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000992 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000993 char *p, *q, *end;
994 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000995
Guido van Rossumd7297e61992-07-06 14:19:26 +0000996 if (f->f_fp == NULL)
997 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000998 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000999 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001000 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001001 return NULL;
1002 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001003 Py_BEGIN_ALLOW_THREADS
1004 errno = 0;
1005 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
1006 Py_END_ALLOW_THREADS
1007 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +00001008 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +00001009 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +00001010 break;
1011 PyErr_SetFromErrno(PyExc_IOError);
1012 clearerr(f->f_fp);
1013 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001014 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +00001015 list = NULL;
1016 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001017 }
Guido van Rossum789a1611997-05-10 22:33:55 +00001018 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +00001019 p = memchr(buffer+nfilled, '\n', nread);
1020 if (p == NULL) {
1021 /* Need a larger buffer to fit this line */
1022 nfilled += nread;
1023 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +00001024 if (buffersize > INT_MAX) {
1025 PyErr_SetString(PyExc_OverflowError,
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001026 "line is longer than a Python string can hold");
Trent Mickf29f47b2000-08-11 19:02:59 +00001027 goto error;
1028 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001029 if (big_buffer == NULL) {
1030 /* Create the big buffer */
1031 big_buffer = PyString_FromStringAndSize(
1032 NULL, buffersize);
1033 if (big_buffer == NULL)
1034 goto error;
1035 buffer = PyString_AS_STRING(big_buffer);
1036 memcpy(buffer, small_buffer, nfilled);
1037 }
1038 else {
1039 /* Grow the big buffer */
1040 _PyString_Resize(&big_buffer, buffersize);
1041 buffer = PyString_AS_STRING(big_buffer);
1042 }
1043 continue;
1044 }
1045 end = buffer+nfilled+nread;
1046 q = buffer;
1047 do {
1048 /* Process complete lines */
1049 p++;
1050 line = PyString_FromStringAndSize(q, p-q);
1051 if (line == NULL)
1052 goto error;
1053 err = PyList_Append(list, line);
1054 Py_DECREF(line);
1055 if (err != 0)
1056 goto error;
1057 q = p;
1058 p = memchr(q, '\n', end-q);
1059 } while (p != NULL);
1060 /* Move the remaining incomplete line to the start */
1061 nfilled = end-q;
1062 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +00001063 if (sizehint > 0)
1064 if (totalread >= (size_t)sizehint)
1065 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001066 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001067 if (nfilled != 0) {
1068 /* Partial last line */
1069 line = PyString_FromStringAndSize(buffer, nfilled);
1070 if (line == NULL)
1071 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +00001072 if (sizehint > 0) {
1073 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +00001074 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +00001075 if (rest == NULL) {
1076 Py_DECREF(line);
1077 goto error;
1078 }
1079 PyString_Concat(&line, rest);
1080 Py_DECREF(rest);
1081 if (line == NULL)
1082 goto error;
1083 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001084 err = PyList_Append(list, line);
1085 Py_DECREF(line);
1086 if (err != 0)
1087 goto error;
1088 }
1089 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001090 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001091 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001092 }
Guido van Rossumce5ba841991-03-06 13:06:18 +00001093 return list;
1094}
1095
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001096static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001097file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001098{
Guido van Rossumd7297e61992-07-06 14:19:26 +00001099 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001100 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001101 if (f->f_fp == NULL)
1102 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +00001103 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001104 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001105 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001106 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001107 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001108 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001109 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001110 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001111 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +00001112 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001113 return NULL;
1114 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001115 Py_INCREF(Py_None);
1116 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001117}
1118
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001119static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001120file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001121{
Guido van Rossumee70ad12000-03-13 16:27:06 +00001122#define CHUNKSIZE 1000
1123 PyObject *list, *line;
1124 PyObject *result;
1125 int i, j, index, len, nwritten, islist;
1126
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001127 if (f->f_fp == NULL)
1128 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +00001129 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001130 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001131 "writelines() argument must be a sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001132 return NULL;
1133 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001134 islist = PyList_Check(args);
1135
1136 /* Strategy: slurp CHUNKSIZE lines into a private list,
1137 checking that they are all strings, then write that list
1138 without holding the interpreter lock, then come back for more. */
1139 index = 0;
1140 if (islist)
1141 list = NULL;
1142 else {
1143 list = PyList_New(CHUNKSIZE);
1144 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001145 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001146 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001147 result = NULL;
1148
1149 for (;;) {
1150 if (islist) {
1151 Py_XDECREF(list);
1152 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
1153 if (list == NULL)
1154 return NULL;
1155 j = PyList_GET_SIZE(list);
1156 }
1157 else {
1158 for (j = 0; j < CHUNKSIZE; j++) {
1159 line = PySequence_GetItem(args, index+j);
1160 if (line == NULL) {
1161 if (PyErr_ExceptionMatches(
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001162 PyExc_IndexError)) {
Guido van Rossumee70ad12000-03-13 16:27:06 +00001163 PyErr_Clear();
1164 break;
1165 }
1166 /* Some other error occurred.
1167 XXX We may lose some output. */
1168 goto error;
1169 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001170 PyList_SetItem(list, j, line);
1171 }
1172 }
1173 if (j == 0)
1174 break;
1175
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001176 /* Check that all entries are indeed strings. If not,
1177 apply the same rules as for file.write() and
1178 convert the results to strings. This is slow, but
1179 seems to be the only way since all conversion APIs
1180 could potentially execute Python code. */
1181 for (i = 0; i < j; i++) {
1182 PyObject *v = PyList_GET_ITEM(list, i);
1183 if (!PyString_Check(v)) {
1184 const char *buffer;
1185 int len;
Tim Peters86821b22001-01-07 21:19:34 +00001186 if (((f->f_binary &&
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001187 PyObject_AsReadBuffer(v,
1188 (const void**)&buffer,
1189 &len)) ||
1190 PyObject_AsCharBuffer(v,
1191 &buffer,
1192 &len))) {
1193 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001194 "writelines() argument must be a sequence of strings");
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001195 goto error;
1196 }
1197 line = PyString_FromStringAndSize(buffer,
1198 len);
1199 if (line == NULL)
1200 goto error;
1201 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001202 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001203 }
1204 }
1205
1206 /* Since we are releasing the global lock, the
1207 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001208 Py_BEGIN_ALLOW_THREADS
1209 f->f_softspace = 0;
1210 errno = 0;
1211 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001212 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001213 len = PyString_GET_SIZE(line);
1214 nwritten = fwrite(PyString_AS_STRING(line),
1215 1, len, f->f_fp);
1216 if (nwritten != len) {
1217 Py_BLOCK_THREADS
1218 PyErr_SetFromErrno(PyExc_IOError);
1219 clearerr(f->f_fp);
1220 goto error;
1221 }
1222 }
1223 Py_END_ALLOW_THREADS
1224
1225 if (j < CHUNKSIZE)
1226 break;
1227 index += CHUNKSIZE;
1228 }
1229
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001230 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001231 result = Py_None;
1232 error:
1233 Py_XDECREF(list);
1234 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001235}
1236
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001237static PyMethodDef file_methods[] = {
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001238 {"readline", (PyCFunction)file_readline, METH_VARARGS},
1239 {"read", (PyCFunction)file_read, METH_VARARGS},
1240 {"write", (PyCFunction)file_write, METH_OLDARGS},
1241 {"fileno", (PyCFunction)file_fileno, METH_NOARGS},
1242 {"seek", (PyCFunction)file_seek, METH_VARARGS},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001243#ifdef HAVE_FTRUNCATE
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001244 {"truncate", (PyCFunction)file_truncate, METH_VARARGS},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001245#endif
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001246 {"tell", (PyCFunction)file_tell, METH_NOARGS},
1247 {"readinto", (PyCFunction)file_readinto, METH_OLDARGS},
1248 {"readlines", (PyCFunction)file_readlines, METH_VARARGS},
1249 {"xreadlines", (PyCFunction)file_xreadlines, METH_NOARGS},
1250 {"writelines", (PyCFunction)file_writelines, METH_O},
1251 {"flush", (PyCFunction)file_flush, METH_NOARGS},
1252 {"close", (PyCFunction)file_close, METH_NOARGS},
1253 {"isatty", (PyCFunction)file_isatty, METH_NOARGS},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254 {NULL, NULL} /* sentinel */
1255};
1256
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001257#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001258
1259static struct memberlist file_memberlist[] = {
1260 {"softspace", T_INT, OFF(f_softspace)},
1261 {"mode", T_OBJECT, OFF(f_mode), RO},
1262 {"name", T_OBJECT, OFF(f_name), RO},
1263 /* getattr(f, "closed") is implemented without this table */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001264 {NULL} /* Sentinel */
1265};
1266
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001267static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00001268get_closed(PyFileObject *f, void *closure)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269{
Tim Peters6d6c1a32001-08-02 04:15:00 +00001270 return PyInt_FromLong((long)(f->f_fp == 0));
Guido van Rossumb6775db1994-08-01 11:34:53 +00001271}
1272
Tim Peters6d6c1a32001-08-02 04:15:00 +00001273static struct getsetlist file_getsetlist[] = {
1274 {"closed", (getter)get_closed, NULL, NULL},
1275 {0},
1276};
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001277
Guido van Rossum65967252001-04-21 13:20:18 +00001278static PyObject *
Guido van Rossum5b021842001-05-22 16:48:37 +00001279file_getiter(PyObject *f)
Guido van Rossum65967252001-04-21 13:20:18 +00001280{
Guido van Rossum5b021842001-05-22 16:48:37 +00001281 return PyObject_CallMethod(f, "xreadlines", "");
Guido van Rossum65967252001-04-21 13:20:18 +00001282}
1283
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001284PyTypeObject PyFile_Type = {
1285 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001286 0,
1287 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001288 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001289 0,
Guido van Rossum65967252001-04-21 13:20:18 +00001290 (destructor)file_dealloc, /* tp_dealloc */
1291 0, /* tp_print */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001292 0, /* tp_getattr */
1293 0, /* tp_setattr */
Guido van Rossum65967252001-04-21 13:20:18 +00001294 0, /* tp_compare */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001295 (reprfunc)file_repr, /* tp_repr */
Guido van Rossum65967252001-04-21 13:20:18 +00001296 0, /* tp_as_number */
1297 0, /* tp_as_sequence */
1298 0, /* tp_as_mapping */
1299 0, /* tp_hash */
1300 0, /* tp_call */
1301 0, /* tp_str */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001302 PyObject_GenericGetAttr, /* tp_getattro */
Guido van Rossum65967252001-04-21 13:20:18 +00001303 0, /* tp_setattro */
1304 0, /* tp_as_buffer */
1305 Py_TPFLAGS_DEFAULT, /* tp_flags */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001306 0, /* tp_doc */
1307 0, /* tp_traverse */
1308 0, /* tp_clear */
Guido van Rossum65967252001-04-21 13:20:18 +00001309 0, /* tp_richcompare */
1310 0, /* tp_weaklistoffset */
Guido van Rossum5b021842001-05-22 16:48:37 +00001311 file_getiter, /* tp_iter */
Guido van Rossum213c7a62001-04-23 14:08:49 +00001312 0, /* tp_iternext */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001313 file_methods, /* tp_methods */
1314 file_memberlist, /* tp_members */
1315 file_getsetlist, /* tp_getset */
1316 0, /* tp_base */
1317 0, /* tp_dict */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001318};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001319
1320/* Interface for the 'soft space' between print items. */
1321
1322int
Fred Drakefd99de62000-07-09 05:02:18 +00001323PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001324{
1325 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001326 if (f == NULL) {
1327 /* Do nothing */
1328 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001329 else if (PyFile_Check(f)) {
1330 oldflag = ((PyFileObject *)f)->f_softspace;
1331 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001332 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001333 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001334 PyObject *v;
1335 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001336 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001337 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001338 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001339 if (PyInt_Check(v))
1340 oldflag = PyInt_AsLong(v);
1341 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001342 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001343 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001344 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001345 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001346 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001347 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1348 PyErr_Clear();
1349 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001350 }
1351 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001352 return oldflag;
1353}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001354
1355/* Interfaces to write objects/strings to file-like objects */
1356
1357int
Fred Drakefd99de62000-07-09 05:02:18 +00001358PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001359{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001360 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001361 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001362 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001363 return -1;
1364 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001365 else if (PyFile_Check(f)) {
1366 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001367 if (fp == NULL) {
1368 err_closed();
1369 return -1;
1370 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001371 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001372 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001373 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001374 if (writer == NULL)
1375 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001376 if (flags & Py_PRINT_RAW)
1377 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001378 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001379 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001380 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001381 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001382 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001383 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001384 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001385 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001386 Py_DECREF(value);
1387 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001388 return -1;
1389 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001390 result = PyEval_CallObject(writer, args);
1391 Py_DECREF(args);
1392 Py_DECREF(value);
1393 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001394 if (result == NULL)
1395 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001396 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001397 return 0;
1398}
1399
Guido van Rossum27a60b11997-05-22 22:25:11 +00001400int
Fred Drakefd99de62000-07-09 05:02:18 +00001401PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001402{
1403 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001404 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001405 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001406 PyErr_SetString(PyExc_SystemError,
1407 "null file for PyFile_WriteString");
1408 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001409 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001410 else if (PyFile_Check(f)) {
1411 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001412 if (fp == NULL) {
1413 err_closed();
1414 return -1;
1415 }
1416 fputs(s, fp);
1417 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001418 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001419 else if (!PyErr_Occurred()) {
1420 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001421 int err;
1422 if (v == NULL)
1423 return -1;
1424 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1425 Py_DECREF(v);
1426 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001427 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001428 else
1429 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001430}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001431
1432/* Try to get a file-descriptor from a Python object. If the object
1433 is an integer or long integer, its value is returned. If not, the
1434 object's fileno() method is called if it exists; the method must return
1435 an integer or long integer, which is returned as the file descriptor value.
1436 -1 is returned on failure.
1437*/
1438
1439int PyObject_AsFileDescriptor(PyObject *o)
1440{
1441 int fd;
1442 PyObject *meth;
1443
1444 if (PyInt_Check(o)) {
1445 fd = PyInt_AsLong(o);
1446 }
1447 else if (PyLong_Check(o)) {
1448 fd = PyLong_AsLong(o);
1449 }
1450 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1451 {
1452 PyObject *fno = PyEval_CallObject(meth, NULL);
1453 Py_DECREF(meth);
1454 if (fno == NULL)
1455 return -1;
Tim Peters86821b22001-01-07 21:19:34 +00001456
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001457 if (PyInt_Check(fno)) {
1458 fd = PyInt_AsLong(fno);
1459 Py_DECREF(fno);
1460 }
1461 else if (PyLong_Check(fno)) {
1462 fd = PyLong_AsLong(fno);
1463 Py_DECREF(fno);
1464 }
1465 else {
1466 PyErr_SetString(PyExc_TypeError,
1467 "fileno() returned a non-integer");
1468 Py_DECREF(fno);
1469 return -1;
1470 }
1471 }
1472 else {
1473 PyErr_SetString(PyExc_TypeError,
1474 "argument must be an int, or have a fileno() method.");
1475 return -1;
1476 }
1477
1478 if (fd < 0) {
1479 PyErr_Format(PyExc_ValueError,
1480 "file descriptor cannot be a negative integer (%i)",
1481 fd);
1482 return -1;
1483 }
1484 return fd;
1485}