blob: ebe0d2993c0fdcd4f6072e934889befd2ebe6c59 [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 Rossumb8199141997-05-06 15:23:24 +000011#ifdef MS_WIN32
Guido van Rossumb8199141997-05-06 15:23:24 +000012#define fileno _fileno
Tim Petersfb05db22002-03-11 00:24:00 +000013/* can simulate truncate with Win32 API functions; see file_truncate */
Guido van Rossumb8199141997-05-06 15:23:24 +000014#define HAVE_FTRUNCATE
Tim Petersfb05db22002-03-11 00:24:00 +000015#define WINDOWS_LEAN_AND_MEAN
16#include <windows.h>
Guido van Rossumb8199141997-05-06 15:23:24 +000017#endif
18
Guido van Rossumf2044e11998-04-28 16:05:59 +000019#ifdef macintosh
20#ifdef USE_GUSI
21#define HAVE_FTRUNCATE
22#endif
23#endif
24
Jack Jansene08dea191995-04-23 22:12:47 +000025#ifdef __MWERKS__
26/* Mwerks fopen() doesn't always set errno */
27#define NO_FOPEN_ERRNO
28#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000029
Andrew MacIntyrec4874392002-02-26 11:36:35 +000030#if defined(PYOS_OS2) && defined(PYCC_GCC)
31#include <io.h>
32#endif
33
Guido van Rossumc0b618a1997-05-02 03:12:38 +000034#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000035
Guido van Rossumff7e83d1999-08-27 20:39:37 +000036#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000037#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000038#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039
Trent Mickf29f47b2000-08-11 19:02:59 +000040
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041FILE *
Fred Drakefd99de62000-07-09 05:02:18 +000042PyFile_AsFile(PyObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000044 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000046 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000047 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000048}
49
Guido van Rossumc0b618a1997-05-02 03:12:38 +000050PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000051PyFile_Name(PyObject *f)
Guido van Rossumdb3165e1993-10-18 17:06:59 +000052{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000053 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000054 return NULL;
55 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000056 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000057}
58
Neil Schemenauered19b882002-03-23 02:06:50 +000059/* On Unix, fopen will succeed for directories.
60 In Python, there should be no file objects referring to
61 directories, so we need a check. */
62
63static PyFileObject*
64dircheck(PyFileObject* f)
65{
66#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
67 struct stat buf;
68 if (f->f_fp == NULL)
69 return f;
70 if (fstat(fileno(f->f_fp), &buf) == 0 &&
71 S_ISDIR(buf.st_mode)) {
72#ifdef HAVE_STRERROR
73 char *msg = strerror(EISDIR);
74#else
75 char *msg = "Is a directory";
76#endif
77 PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(is)", EISDIR, msg);
78 PyErr_SetObject(PyExc_IOError, exc);
79 return NULL;
80 }
81#endif
82 return f;
83}
84
Tim Peters59c9a642001-09-13 05:38:56 +000085
86static PyObject *
87fill_file_fields(PyFileObject *f, FILE *fp, char *name, char *mode,
88 int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089{
Tim Peters59c9a642001-09-13 05:38:56 +000090 assert(f != NULL);
91 assert(PyFile_Check(f));
Tim Peters44410012001-09-14 03:26:08 +000092 assert(f->f_fp == NULL);
93
94 Py_DECREF(f->f_name);
95 Py_DECREF(f->f_mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +000096 f->f_name = PyString_FromString(name);
97 f->f_mode = PyString_FromString(mode);
Tim Peters44410012001-09-14 03:26:08 +000098
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000099 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000100 f->f_softspace = 0;
Tim Peters59c9a642001-09-13 05:38:56 +0000101 f->f_binary = strchr(mode,'b') != NULL;
Tim Peters44410012001-09-14 03:26:08 +0000102
Tim Peters59c9a642001-09-13 05:38:56 +0000103 if (f->f_name == NULL || f->f_mode == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105 f->f_fp = fp;
Neil Schemenauered19b882002-03-23 02:06:50 +0000106 f = dircheck(f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108}
109
Tim Peters59c9a642001-09-13 05:38:56 +0000110static PyObject *
111open_the_file(PyFileObject *f, char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112{
Tim Peters59c9a642001-09-13 05:38:56 +0000113 assert(f != NULL);
114 assert(PyFile_Check(f));
115 assert(name != NULL);
116 assert(mode != NULL);
Tim Peters44410012001-09-14 03:26:08 +0000117 assert(f->f_fp == NULL);
Tim Peters59c9a642001-09-13 05:38:56 +0000118
Tim Peters8fa45672001-09-13 21:01:29 +0000119 /* rexec.py can't stop a user from getting the file() constructor --
120 all they have to do is get *any* file object f, and then do
121 type(f). Here we prevent them from doing damage with it. */
122 if (PyEval_GetRestricted()) {
123 PyErr_SetString(PyExc_IOError,
124 "file() constructor not accessible in restricted mode");
125 return NULL;
126 }
Tim Petersa27a1502001-11-09 20:59:14 +0000127 errno = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000128#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000129 if (*mode == '*') {
130 FILE *fopenRF();
131 f->f_fp = fopenRF(name, mode+1);
132 }
133 else
134#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000135 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000136 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000137 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000138 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000139 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000140 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000141#ifdef NO_FOPEN_ERRNO
Jack Jansenb3be2162001-11-30 14:16:36 +0000142 /* Metroworks only, wich does not always sets errno */
Jeremy Hylton41c83212001-11-09 16:17:24 +0000143 if (errno == 0) {
Jack Jansenb3be2162001-11-30 14:16:36 +0000144 PyObject *v;
145 v = Py_BuildValue("(is)", 0, "Cannot open file");
146 if (v != NULL) {
147 PyErr_SetObject(PyExc_IOError, v);
148 Py_DECREF(v);
149 }
Jack Jansene08dea191995-04-23 22:12:47 +0000150 return NULL;
151 }
152#endif
Jeremy Hylton41c83212001-11-09 16:17:24 +0000153 if (errno == EINVAL)
154 PyErr_Format(PyExc_IOError, "invalid argument: %s",
155 mode);
156 else
157 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Tim Peters59c9a642001-09-13 05:38:56 +0000158 f = NULL;
159 }
Neil Schemenauered19b882002-03-23 02:06:50 +0000160 if (f != NULL)
161 f = dircheck(f);
Tim Peters59c9a642001-09-13 05:38:56 +0000162 return (PyObject *)f;
163}
164
165PyObject *
166PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
167{
Tim Peters44410012001-09-14 03:26:08 +0000168 PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type,
169 NULL, NULL);
Tim Peters59c9a642001-09-13 05:38:56 +0000170 if (f != NULL) {
171 if (fill_file_fields(f, fp, name, mode, close) == NULL) {
172 Py_DECREF(f);
173 f = NULL;
174 }
175 }
176 return (PyObject *) f;
177}
178
179PyObject *
180PyFile_FromString(char *name, char *mode)
181{
182 extern int fclose(FILE *);
183 PyFileObject *f;
184
185 f = (PyFileObject *)PyFile_FromFile((FILE *)NULL, name, mode, fclose);
186 if (f != NULL) {
187 if (open_the_file(f, name, mode) == NULL) {
188 Py_DECREF(f);
189 f = NULL;
190 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000192 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193}
194
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195void
Fred Drakefd99de62000-07-09 05:02:18 +0000196PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197{
198 if (bufsize >= 0) {
199#ifdef HAVE_SETVBUF
200 int type;
201 switch (bufsize) {
202 case 0:
203 type = _IONBF;
204 break;
205 case 1:
206 type = _IOLBF;
207 bufsize = BUFSIZ;
208 break;
209 default:
210 type = _IOFBF;
211 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000212 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
213 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000214#else /* !HAVE_SETVBUF */
215 if (bufsize <= 1)
216 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
217#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218 }
219}
220
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000222err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000223{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000225 return NULL;
226}
227
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228/* Methods */
229
230static void
Fred Drakefd99de62000-07-09 05:02:18 +0000231file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000233 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000235 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000236 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000237 }
Tim Peters44410012001-09-14 03:26:08 +0000238 Py_XDECREF(f->f_name);
239 Py_XDECREF(f->f_mode);
Guido van Rossum9475a232001-10-05 20:51:39 +0000240 f->ob_type->tp_free((PyObject *)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241}
242
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000243static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000244file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245{
Barry Warsaw7ce36942001-08-24 18:34:26 +0000246 return PyString_FromFormat("<%s file '%s', mode '%s' at %p>",
247 f->f_fp == NULL ? "closed" : "open",
248 PyString_AsString(f->f_name),
249 PyString_AsString(f->f_mode),
250 f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251}
252
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000253static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000254file_close(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000255{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000256 int sts = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000257 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000258 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000259 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000260 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000261 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000262 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000263 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264 f->f_fp = NULL;
265 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000266 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000267 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000268 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000269 return PyInt_FromLong((long)sts);
270 Py_INCREF(Py_None);
271 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272}
273
Trent Mickf29f47b2000-08-11 19:02:59 +0000274
Guido van Rossumb8552162001-09-05 14:58:11 +0000275/* Our very own off_t-like type, 64-bit if possible */
276#if !defined(HAVE_LARGEFILE_SUPPORT)
277typedef off_t Py_off_t;
278#elif SIZEOF_OFF_T >= 8
279typedef off_t Py_off_t;
280#elif SIZEOF_FPOS_T >= 8
Guido van Rossum4f53da02001-03-01 18:26:53 +0000281typedef fpos_t Py_off_t;
282#else
Guido van Rossumb8552162001-09-05 14:58:11 +0000283#error "Large file support, but neither off_t nor fpos_t is large enough."
Guido van Rossum4f53da02001-03-01 18:26:53 +0000284#endif
285
286
Trent Mickf29f47b2000-08-11 19:02:59 +0000287/* a portable fseek() function
288 return 0 on success, non-zero on failure (with errno set) */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000289static int
Guido van Rossum4f53da02001-03-01 18:26:53 +0000290_portable_fseek(FILE *fp, Py_off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000291{
Guido van Rossumb8552162001-09-05 14:58:11 +0000292#if !defined(HAVE_LARGEFILE_SUPPORT)
293 return fseek(fp, offset, whence);
294#elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000295 return fseeko(fp, offset, whence);
296#elif defined(HAVE_FSEEK64)
297 return fseek64(fp, offset, whence);
Fred Drakedb810ac2000-10-06 20:42:33 +0000298#elif defined(__BEOS__)
299 return _fseek(fp, offset, whence);
Guido van Rossumb8552162001-09-05 14:58:11 +0000300#elif SIZEOF_FPOS_T >= 8
Guido van Rossume54e0be2001-01-16 20:53:31 +0000301 /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
302 and fgetpos() to implement fseek()*/
Trent Mickf29f47b2000-08-11 19:02:59 +0000303 fpos_t pos;
304 switch (whence) {
Guido van Rossume54e0be2001-01-16 20:53:31 +0000305 case SEEK_END:
Guido van Rossum8b4e43e2001-09-10 20:43:35 +0000306#ifdef MS_WINDOWS
307 fflush(fp);
308 if (_lseeki64(fileno(fp), 0, 2) == -1)
309 return -1;
310#else
Guido van Rossume54e0be2001-01-16 20:53:31 +0000311 if (fseek(fp, 0, SEEK_END) != 0)
312 return -1;
Guido van Rossum8b4e43e2001-09-10 20:43:35 +0000313#endif
Guido van Rossume54e0be2001-01-16 20:53:31 +0000314 /* fall through */
315 case SEEK_CUR:
316 if (fgetpos(fp, &pos) != 0)
317 return -1;
318 offset += pos;
319 break;
320 /* case SEEK_SET: break; */
Trent Mickf29f47b2000-08-11 19:02:59 +0000321 }
322 return fsetpos(fp, &offset);
323#else
Guido van Rossumb8552162001-09-05 14:58:11 +0000324#error "Large file support, but no way to fseek."
Trent Mickf29f47b2000-08-11 19:02:59 +0000325#endif
326}
327
328
329/* a portable ftell() function
330 Return -1 on failure with errno set appropriately, current file
331 position on success */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000332static Py_off_t
Fred Drake8ce159a2000-08-31 05:18:54 +0000333_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000334{
Guido van Rossumb8552162001-09-05 14:58:11 +0000335#if !defined(HAVE_LARGEFILE_SUPPORT)
336 return ftell(fp);
337#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8
338 return ftello(fp);
339#elif defined(HAVE_FTELL64)
340 return ftell64(fp);
341#elif SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000342 fpos_t pos;
343 if (fgetpos(fp, &pos) != 0)
344 return -1;
345 return pos;
346#else
Guido van Rossumb8552162001-09-05 14:58:11 +0000347#error "Large file support, but no way to ftell."
Trent Mickf29f47b2000-08-11 19:02:59 +0000348#endif
349}
350
351
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000353file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000355 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000356 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000357 Py_off_t offset;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000358 PyObject *offobj;
Tim Peters86821b22001-01-07 21:19:34 +0000359
Guido van Rossumd7297e61992-07-06 14:19:26 +0000360 if (f->f_fp == NULL)
361 return err_closed();
362 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000363 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000364 return NULL;
365#if !defined(HAVE_LARGEFILE_SUPPORT)
366 offset = PyInt_AsLong(offobj);
367#else
368 offset = PyLong_Check(offobj) ?
369 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
370#endif
371 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000372 return NULL;
Tim Peters86821b22001-01-07 21:19:34 +0000373
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000374 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000375 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000376 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000377 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000378
Guido van Rossumff4949e1992-08-05 19:58:53 +0000379 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000381 clearerr(f->f_fp);
382 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000383 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000384 Py_INCREF(Py_None);
385 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000386}
387
Trent Mickf29f47b2000-08-11 19:02:59 +0000388
Guido van Rossumd7047b31995-01-02 19:07:15 +0000389#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000391file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000392{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000393 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000394 Py_off_t newsize;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000395 PyObject *newsizeobj;
Tim Peters86821b22001-01-07 21:19:34 +0000396
Guido van Rossumd7047b31995-01-02 19:07:15 +0000397 if (f->f_fp == NULL)
398 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000399 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000400 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000401 return NULL;
Tim Petersfb05db22002-03-11 00:24:00 +0000402
403 /* Set newsize to current postion if newsizeobj NULL, else to the
404 specified value. */
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000405 if (newsizeobj != NULL) {
406#if !defined(HAVE_LARGEFILE_SUPPORT)
407 newsize = PyInt_AsLong(newsizeobj);
408#else
409 newsize = PyLong_Check(newsizeobj) ?
410 PyLong_AsLongLong(newsizeobj) :
411 PyInt_AsLong(newsizeobj);
412#endif
413 if (PyErr_Occurred())
414 return NULL;
Tim Petersfb05db22002-03-11 00:24:00 +0000415 }
416 else {
417 /* Default to current position. */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000418 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000419 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000420 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000421 Py_END_ALLOW_THREADS
Tim Petersfb05db22002-03-11 00:24:00 +0000422 if (newsize == -1)
423 goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000424 }
Tim Petersfb05db22002-03-11 00:24:00 +0000425
426 /* Flush the file. */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000427 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000428 errno = 0;
429 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000430 Py_END_ALLOW_THREADS
Tim Petersfb05db22002-03-11 00:24:00 +0000431 if (ret != 0)
432 goto onioerror;
Trent Mickf29f47b2000-08-11 19:02:59 +0000433
434#ifdef MS_WIN32
Tim Petersfb05db22002-03-11 00:24:00 +0000435 /* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
Tim Peters8f01b682002-03-12 03:04:44 +0000436 so don't even try using it. */
Tim Petersfb05db22002-03-11 00:24:00 +0000437 {
Tim Peters8f01b682002-03-12 03:04:44 +0000438 Py_off_t current; /* current file position */
Tim Petersfb05db22002-03-11 00:24:00 +0000439 HANDLE hFile;
440 int error;
441
Tim Peters8f01b682002-03-12 03:04:44 +0000442 /* current <- current file postion. */
443 if (newsizeobj == NULL)
444 current = newsize;
445 else {
Tim Petersfb05db22002-03-11 00:24:00 +0000446 Py_BEGIN_ALLOW_THREADS
447 errno = 0;
Tim Peters8f01b682002-03-12 03:04:44 +0000448 current = _portable_ftell(f->f_fp);
449 Py_END_ALLOW_THREADS
450 if (current == -1)
451 goto onioerror;
452 }
453
454 /* Move to newsize. */
455 if (current != newsize) {
456 Py_BEGIN_ALLOW_THREADS
457 errno = 0;
458 error = _portable_fseek(f->f_fp, newsize, SEEK_SET)
459 != 0;
Tim Petersfb05db22002-03-11 00:24:00 +0000460 Py_END_ALLOW_THREADS
461 if (error)
462 goto onioerror;
463 }
464
Tim Peters8f01b682002-03-12 03:04:44 +0000465 /* Truncate. Note that this may grow the file! */
466 Py_BEGIN_ALLOW_THREADS
467 errno = 0;
468 hFile = (HANDLE)_get_osfhandle(fileno(f->f_fp));
469 error = hFile == (HANDLE)-1;
470 if (!error) {
471 error = SetEndOfFile(hFile) == 0;
472 if (error)
473 errno = EACCES;
474 }
475 Py_END_ALLOW_THREADS
476 if (error)
477 goto onioerror;
478
479 /* Restore original file position. */
480 if (current != newsize) {
481 Py_BEGIN_ALLOW_THREADS
482 errno = 0;
483 error = _portable_fseek(f->f_fp, current, SEEK_SET)
484 != 0;
485 Py_END_ALLOW_THREADS
486 if (error)
487 goto onioerror;
488 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000489 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000490#else
491 Py_BEGIN_ALLOW_THREADS
492 errno = 0;
493 ret = ftruncate(fileno(f->f_fp), newsize);
494 Py_END_ALLOW_THREADS
495 if (ret != 0) goto onioerror;
496#endif /* !MS_WIN32 */
Tim Peters86821b22001-01-07 21:19:34 +0000497
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000498 Py_INCREF(Py_None);
499 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000500
501onioerror:
502 PyErr_SetFromErrno(PyExc_IOError);
503 clearerr(f->f_fp);
504 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000505}
506#endif /* HAVE_FTRUNCATE */
507
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000509file_tell(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000510{
Guido van Rossum4f53da02001-03-01 18:26:53 +0000511 Py_off_t pos;
Trent Mickf29f47b2000-08-11 19:02:59 +0000512
Guido van Rossumd7297e61992-07-06 14:19:26 +0000513 if (f->f_fp == NULL)
514 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000515 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000516 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000517 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000518 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000519 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000520 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000521 clearerr(f->f_fp);
522 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000523 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000524#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000525 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000526#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000527 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000528#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000529}
530
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000531static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000532file_fileno(PyFileObject *f)
Guido van Rossumed233a51992-06-23 09:07:03 +0000533{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000534 if (f->f_fp == NULL)
535 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000536 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000537}
538
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000539static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000540file_flush(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000541{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000542 int res;
Tim Peters86821b22001-01-07 21:19:34 +0000543
Guido van Rossumd7297e61992-07-06 14:19:26 +0000544 if (f->f_fp == NULL)
545 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000546 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000547 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000548 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000549 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000550 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000551 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000552 clearerr(f->f_fp);
553 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000554 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000555 Py_INCREF(Py_None);
556 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000557}
558
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000560file_isatty(PyFileObject *f)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000561{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000562 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000563 if (f->f_fp == NULL)
564 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000565 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000566 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000567 Py_END_ALLOW_THREADS
568 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000569}
570
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000571
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000572#if BUFSIZ < 8192
573#define SMALLCHUNK 8192
574#else
575#define SMALLCHUNK BUFSIZ
576#endif
577
Guido van Rossum3c259041999-01-14 19:00:14 +0000578#if SIZEOF_INT < 4
579#define BIGCHUNK (512 * 32)
580#else
581#define BIGCHUNK (512 * 1024)
582#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000583
584static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000585new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000586{
587#ifdef HAVE_FSTAT
Fred Drake1bc8fab2001-07-19 21:49:38 +0000588 off_t pos, end;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000589 struct stat st;
590 if (fstat(fileno(f->f_fp), &st) == 0) {
591 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000592 /* The following is not a bug: we really need to call lseek()
593 *and* ftell(). The reason is that some stdio libraries
594 mistakenly flush their buffer when ftell() is called and
595 the lseek() call it makes fails, thereby throwing away
596 data that cannot be recovered in any way. To avoid this,
597 we first test lseek(), and only call ftell() if lseek()
598 works. We can't use the lseek() value either, because we
599 need to take the amount of buffered data into account.
600 (Yet another reason why stdio stinks. :-) */
Jack Jansen2771b5b2001-10-10 22:03:27 +0000601#ifdef USE_GUSI2
602 pos = lseek(fileno(f->f_fp), 1L, SEEK_CUR);
603 pos = lseek(fileno(f->f_fp), -1L, SEEK_CUR);
604#else
Guido van Rossum91aaa921998-05-05 22:21:35 +0000605 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
Jack Jansen2771b5b2001-10-10 22:03:27 +0000606#endif
607 if (pos >= 0) {
Guido van Rossum91aaa921998-05-05 22:21:35 +0000608 pos = ftell(f->f_fp);
Jack Jansen2771b5b2001-10-10 22:03:27 +0000609 }
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000610 if (pos < 0)
611 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000612 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000613 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000614 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000615 }
616#endif
617 if (currentsize > SMALLCHUNK) {
618 /* Keep doubling until we reach BIGCHUNK;
619 then keep adding BIGCHUNK. */
620 if (currentsize <= BIGCHUNK)
621 return currentsize + currentsize;
622 else
623 return currentsize + BIGCHUNK;
624 }
625 return currentsize + SMALLCHUNK;
626}
627
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000628static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000629file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000630{
Guido van Rossum789a1611997-05-10 22:33:55 +0000631 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000632 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000633 PyObject *v;
Tim Peters86821b22001-01-07 21:19:34 +0000634
Guido van Rossumd7297e61992-07-06 14:19:26 +0000635 if (f->f_fp == NULL)
636 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000637 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000638 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000639 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000640 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000641 else
642 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000643 if (buffersize > INT_MAX) {
644 PyErr_SetString(PyExc_OverflowError,
645 "requested number of bytes is more than a Python string can hold");
646 return NULL;
647 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000648 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000649 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000650 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000651 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000652 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000653 Py_BEGIN_ALLOW_THREADS
654 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000655 chunksize = fread(BUF(v) + bytesread, 1,
656 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000657 Py_END_ALLOW_THREADS
658 if (chunksize == 0) {
659 if (!ferror(f->f_fp))
660 break;
661 PyErr_SetFromErrno(PyExc_IOError);
662 clearerr(f->f_fp);
663 Py_DECREF(v);
664 return NULL;
665 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000666 bytesread += chunksize;
667 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000668 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000669 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000670 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000671 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000672 return NULL;
673 }
674 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000675 if (bytesread != buffersize)
676 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000677 return v;
678}
679
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000680static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000681file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000682{
683 char *ptr;
Guido van Rossum00ebd462001-10-23 21:25:24 +0000684 int ntodo;
685 size_t ndone, nnow;
Tim Peters86821b22001-01-07 21:19:34 +0000686
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000687 if (f->f_fp == NULL)
688 return err_closed();
689 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
690 return NULL;
691 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000692 while (ntodo > 0) {
693 Py_BEGIN_ALLOW_THREADS
694 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000695 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000696 Py_END_ALLOW_THREADS
697 if (nnow == 0) {
698 if (!ferror(f->f_fp))
699 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000700 PyErr_SetFromErrno(PyExc_IOError);
701 clearerr(f->f_fp);
702 return NULL;
703 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000704 ndone += nnow;
705 ntodo -= nnow;
706 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000707 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000708}
709
Tim Peters86821b22001-01-07 21:19:34 +0000710/**************************************************************************
Tim Petersf29b64d2001-01-15 06:33:19 +0000711Routine to get next line using platform fgets().
Tim Peters86821b22001-01-07 21:19:34 +0000712
713Under MSVC 6:
714
Tim Peters1c733232001-01-08 04:02:07 +0000715+ MS threadsafe getc is very slow (multiple layers of function calls before+
716 after each character, to lock+unlock the stream).
717+ The stream-locking functions are MS-internal -- can't access them from user
718 code.
719+ There's nothing Tim could find in the MS C or platform SDK libraries that
720 can worm around this.
Tim Peters86821b22001-01-07 21:19:34 +0000721+ MS fgets locks/unlocks only once per line; it's the only hook we have.
722
723So we use fgets for speed(!), despite that it's painful.
724
725MS realloc is also slow.
726
Tim Petersf29b64d2001-01-15 06:33:19 +0000727Reports from other platforms on this method vs getc_unlocked (which MS doesn't
728have):
729 Linux a wash
730 Solaris a wash
731 Tru64 Unix getline_via_fgets significantly faster
Tim Peters86821b22001-01-07 21:19:34 +0000732
Tim Petersf29b64d2001-01-15 06:33:19 +0000733CAUTION: The C std isn't clear about this: in those cases where fgets
734writes something into the buffer, can it write into any position beyond the
735required trailing null byte? MSVC 6 fgets does not, and no platform is (yet)
736known on which it does; and it would be a strange way to code fgets. Still,
737getline_via_fgets may not work correctly if it does. The std test
738test_bufio.py should fail if platform fgets() routinely writes beyond the
739trailing null byte. #define DONT_USE_FGETS_IN_GETLINE to disable this code.
Tim Peters86821b22001-01-07 21:19:34 +0000740**************************************************************************/
741
Tim Petersf29b64d2001-01-15 06:33:19 +0000742/* Use this routine if told to, or by default on non-get_unlocked()
743 * platforms unless told not to. Yikes! Let's spell that out:
744 * On a platform with getc_unlocked():
745 * By default, use getc_unlocked().
746 * If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
747 * On a platform without getc_unlocked():
748 * By default, use fgets().
749 * If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
750 */
751#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
752#define USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000753#endif
754
Tim Petersf29b64d2001-01-15 06:33:19 +0000755#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
756#undef USE_FGETS_IN_GETLINE
757#endif
758
759#ifdef USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000760static PyObject*
Tim Petersf29b64d2001-01-15 06:33:19 +0000761getline_via_fgets(FILE *fp)
Tim Peters86821b22001-01-07 21:19:34 +0000762{
Tim Peters15b83852001-01-08 00:53:12 +0000763/* INITBUFSIZE is the maximum line length that lets us get away with the fast
Tim Peters142297a2001-01-15 10:36:56 +0000764 * no-realloc, one-fgets()-call path. Boosting it isn't free, because we have
765 * to fill this much of the buffer with a known value in order to figure out
766 * how much of the buffer fgets() overwrites. So if INITBUFSIZE is larger
767 * than "most" lines, we waste time filling unused buffer slots. 100 is
768 * surely adequate for most peoples' email archives, chewing over source code,
769 * etc -- "regular old text files".
770 * MAXBUFSIZE is the maximum line length that lets us get away with the less
771 * fast (but still zippy) no-realloc, two-fgets()-call path. See above for
772 * cautions about boosting that. 300 was chosen because the worst real-life
773 * text-crunching job reported on Python-Dev was a mail-log crawler where over
774 * half the lines were 254 chars.
Tim Peters15b83852001-01-08 00:53:12 +0000775 */
Tim Peters142297a2001-01-15 10:36:56 +0000776#define INITBUFSIZE 100
777#define MAXBUFSIZE 300
Tim Peters142297a2001-01-15 10:36:56 +0000778 char* p; /* temp */
779 char buf[MAXBUFSIZE];
Tim Peters86821b22001-01-07 21:19:34 +0000780 PyObject* v; /* the string object result */
Tim Peters86821b22001-01-07 21:19:34 +0000781 char* pvfree; /* address of next free slot */
782 char* pvend; /* address one beyond last free slot */
Tim Peters142297a2001-01-15 10:36:56 +0000783 size_t nfree; /* # of free buffer slots; pvend-pvfree */
784 size_t total_v_size; /* total # of slots in buffer */
Tim Petersddea2082002-03-23 10:03:50 +0000785 size_t increment; /* amount to increment the buffer */
Tim Peters86821b22001-01-07 21:19:34 +0000786
Tim Peters15b83852001-01-08 00:53:12 +0000787 /* Optimize for normal case: avoid _PyString_Resize if at all
Tim Peters142297a2001-01-15 10:36:56 +0000788 * possible via first reading into stack buffer "buf".
Tim Peters15b83852001-01-08 00:53:12 +0000789 */
Tim Peters142297a2001-01-15 10:36:56 +0000790 total_v_size = INITBUFSIZE; /* start small and pray */
791 pvfree = buf;
792 for (;;) {
793 Py_BEGIN_ALLOW_THREADS
794 pvend = buf + total_v_size;
795 nfree = pvend - pvfree;
796 memset(pvfree, '\n', nfree);
797 p = fgets(pvfree, nfree, fp);
798 Py_END_ALLOW_THREADS
Tim Peters15b83852001-01-08 00:53:12 +0000799
Tim Peters142297a2001-01-15 10:36:56 +0000800 if (p == NULL) {
801 clearerr(fp);
802 if (PyErr_CheckSignals())
803 return NULL;
804 v = PyString_FromStringAndSize(buf, pvfree - buf);
Tim Peters86821b22001-01-07 21:19:34 +0000805 return v;
806 }
Tim Peters142297a2001-01-15 10:36:56 +0000807 /* fgets read *something* */
808 p = memchr(pvfree, '\n', nfree);
809 if (p != NULL) {
810 /* Did the \n come from fgets or from us?
811 * Since fgets stops at the first \n, and then writes
812 * \0, if it's from fgets a \0 must be next. But if
813 * that's so, it could not have come from us, since
814 * the \n's we filled the buffer with have only more
815 * \n's to the right.
816 */
817 if (p+1 < pvend && *(p+1) == '\0') {
818 /* It's from fgets: we win! In particular,
819 * we haven't done any mallocs yet, and can
820 * build the final result on the first try.
821 */
822 ++p; /* include \n from fgets */
823 }
824 else {
825 /* Must be from us: fgets didn't fill the
826 * buffer and didn't find a newline, so it
827 * must be the last and newline-free line of
828 * the file.
829 */
830 assert(p > pvfree && *(p-1) == '\0');
831 --p; /* don't include \0 from fgets */
832 }
833 v = PyString_FromStringAndSize(buf, p - buf);
834 return v;
835 }
836 /* yuck: fgets overwrote all the newlines, i.e. the entire
837 * buffer. So this line isn't over yet, or maybe it is but
838 * we're exactly at EOF. If we haven't already, try using the
839 * rest of the stack buffer.
Tim Peters86821b22001-01-07 21:19:34 +0000840 */
Tim Peters142297a2001-01-15 10:36:56 +0000841 assert(*(pvend-1) == '\0');
842 if (pvfree == buf) {
843 pvfree = pvend - 1; /* overwrite trailing null */
844 total_v_size = MAXBUFSIZE;
845 }
846 else
847 break;
Tim Peters86821b22001-01-07 21:19:34 +0000848 }
Tim Peters142297a2001-01-15 10:36:56 +0000849
850 /* The stack buffer isn't big enough; malloc a string object and read
851 * into its buffer.
Tim Peters15b83852001-01-08 00:53:12 +0000852 */
Tim Petersddea2082002-03-23 10:03:50 +0000853 total_v_size = MAXBUFSIZE << 1;
Tim Peters1c733232001-01-08 04:02:07 +0000854 v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
Tim Peters15b83852001-01-08 00:53:12 +0000855 if (v == NULL)
856 return v;
857 /* copy over everything except the last null byte */
Tim Peters142297a2001-01-15 10:36:56 +0000858 memcpy(BUF(v), buf, MAXBUFSIZE-1);
859 pvfree = BUF(v) + MAXBUFSIZE - 1;
Tim Peters86821b22001-01-07 21:19:34 +0000860
861 /* Keep reading stuff into v; if it ever ends successfully, break
Tim Peters15b83852001-01-08 00:53:12 +0000862 * after setting p one beyond the end of the line. The code here is
863 * very much like the code above, except reads into v's buffer; see
864 * the code above for detailed comments about the logic.
Tim Peters86821b22001-01-07 21:19:34 +0000865 */
866 for (;;) {
Tim Peters86821b22001-01-07 21:19:34 +0000867 Py_BEGIN_ALLOW_THREADS
868 pvend = BUF(v) + total_v_size;
869 nfree = pvend - pvfree;
870 memset(pvfree, '\n', nfree);
871 p = fgets(pvfree, nfree, fp);
872 Py_END_ALLOW_THREADS
873
874 if (p == NULL) {
875 clearerr(fp);
876 if (PyErr_CheckSignals()) {
877 Py_DECREF(v);
878 return NULL;
879 }
880 p = pvfree;
881 break;
882 }
Tim Peters86821b22001-01-07 21:19:34 +0000883 p = memchr(pvfree, '\n', nfree);
884 if (p != NULL) {
885 if (p+1 < pvend && *(p+1) == '\0') {
886 /* \n came from fgets */
887 ++p;
888 break;
889 }
890 /* \n came from us; last line of file, no newline */
891 assert(p > pvfree && *(p-1) == '\0');
892 --p;
893 break;
894 }
895 /* expand buffer and try again */
896 assert(*(pvend-1) == '\0');
Tim Petersddea2082002-03-23 10:03:50 +0000897 increment = total_v_size >> 2; /* mild exponential growth */
898 total_v_size += increment;
Tim Peters86821b22001-01-07 21:19:34 +0000899 if (total_v_size > INT_MAX) {
900 PyErr_SetString(PyExc_OverflowError,
901 "line is longer than a Python string can hold");
902 Py_DECREF(v);
903 return NULL;
904 }
905 if (_PyString_Resize(&v, (int)total_v_size) < 0)
906 return NULL;
907 /* overwrite the trailing null byte */
Tim Petersddea2082002-03-23 10:03:50 +0000908 pvfree = BUF(v) + (total_v_size - increment - 1);
Tim Peters86821b22001-01-07 21:19:34 +0000909 }
910 if (BUF(v) + total_v_size != p)
911 _PyString_Resize(&v, p - BUF(v));
912 return v;
913#undef INITBUFSIZE
Tim Peters142297a2001-01-15 10:36:56 +0000914#undef MAXBUFSIZE
Tim Peters86821b22001-01-07 21:19:34 +0000915}
Tim Petersf29b64d2001-01-15 06:33:19 +0000916#endif /* ifdef USE_FGETS_IN_GETLINE */
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000917
Guido van Rossum0bd24411991-04-04 15:21:57 +0000918/* Internal routine to get a line.
919 Size argument interpretation:
920 > 0: max length;
Guido van Rossum86282062001-01-08 01:26:47 +0000921 <= 0: read arbitrary line
Guido van Rossumce5ba841991-03-06 13:06:18 +0000922*/
923
Guido van Rossum1187aa42001-01-05 14:43:05 +0000924#ifdef HAVE_GETC_UNLOCKED
925#define GETC(f) getc_unlocked(f)
926#define FLOCKFILE(f) flockfile(f)
927#define FUNLOCKFILE(f) funlockfile(f)
928#else
929#define GETC(f) getc(f)
930#define FLOCKFILE(f)
931#define FUNLOCKFILE(f)
932#endif
933
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000934static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000935get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000936{
Guido van Rossum1187aa42001-01-05 14:43:05 +0000937 FILE *fp = f->f_fp;
938 int c;
Andrew M. Kuchling4b2b4452000-11-29 02:53:22 +0000939 char *buf, *end;
Neil Schemenauer3a204a72002-03-23 19:41:34 +0000940 size_t total_v_size; /* total # of slots in buffer */
941 size_t used_v_size; /* # used slots in buffer */
942 size_t increment; /* amount to increment the buffer */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000943 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000944
Tim Petersf29b64d2001-01-15 06:33:19 +0000945#ifdef USE_FGETS_IN_GETLINE
Guido van Rossum86282062001-01-08 01:26:47 +0000946 if (n <= 0)
Tim Petersf29b64d2001-01-15 06:33:19 +0000947 return getline_via_fgets(fp);
Tim Peters86821b22001-01-07 21:19:34 +0000948#endif
Neil Schemenauer3a204a72002-03-23 19:41:34 +0000949 total_v_size = n > 0 ? n : 100;
950 v = PyString_FromStringAndSize((char *)NULL, total_v_size);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000951 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000952 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000953 buf = BUF(v);
Neil Schemenauer3a204a72002-03-23 19:41:34 +0000954 end = buf + total_v_size;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000955
Guido van Rossumce5ba841991-03-06 13:06:18 +0000956 for (;;) {
Guido van Rossum1187aa42001-01-05 14:43:05 +0000957 Py_BEGIN_ALLOW_THREADS
958 FLOCKFILE(fp);
959 while ((c = GETC(fp)) != EOF &&
960 (*buf++ = c) != '\n' &&
961 buf != end)
962 ;
963 FUNLOCKFILE(fp);
964 Py_END_ALLOW_THREADS
965 if (c == '\n')
966 break;
967 if (c == EOF) {
Guido van Rossum29206bc2001-08-09 18:14:59 +0000968 if (ferror(fp)) {
969 PyErr_SetFromErrno(PyExc_IOError);
970 clearerr(fp);
971 Py_DECREF(v);
972 return NULL;
973 }
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000974 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000975 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000976 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000977 return NULL;
978 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000979 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000980 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000981 /* Must be because buf == end */
982 if (n > 0)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000983 break;
Neil Schemenauer3a204a72002-03-23 19:41:34 +0000984 used_v_size = total_v_size;
985 increment = total_v_size >> 2; /* mild exponential growth */
986 total_v_size += increment;
987 if (total_v_size > INT_MAX) {
Guido van Rossum1187aa42001-01-05 14:43:05 +0000988 PyErr_SetString(PyExc_OverflowError,
989 "line is longer than a Python string can hold");
Tim Peters86821b22001-01-07 21:19:34 +0000990 Py_DECREF(v);
Guido van Rossum1187aa42001-01-05 14:43:05 +0000991 return NULL;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000992 }
Neil Schemenauer3a204a72002-03-23 19:41:34 +0000993 if (_PyString_Resize(&v, total_v_size) < 0)
Guido van Rossum1187aa42001-01-05 14:43:05 +0000994 return NULL;
Neil Schemenauer3a204a72002-03-23 19:41:34 +0000995 buf = BUF(v) + used_v_size;
996 end = BUF(v) + total_v_size;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000997 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000998
Neil Schemenauer3a204a72002-03-23 19:41:34 +0000999 used_v_size = buf - BUF(v);
1000 if (used_v_size != total_v_size)
1001 _PyString_Resize(&v, used_v_size);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001002 return v;
1003}
1004
Guido van Rossum0bd24411991-04-04 15:21:57 +00001005/* External C interface */
1006
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001007PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001008PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +00001009{
Guido van Rossum4ddf0a02001-01-07 20:51:39 +00001010 PyObject *result;
1011
Guido van Rossum3165fe61992-09-25 21:59:05 +00001012 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001013 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +00001014 return NULL;
1015 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +00001016
1017 if (PyFile_Check(f)) {
1018 if (((PyFileObject*)f)->f_fp == NULL)
1019 return err_closed();
1020 result = get_line((PyFileObject *)f, n);
1021 }
1022 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001023 PyObject *reader;
1024 PyObject *args;
Guido van Rossum4ddf0a02001-01-07 20:51:39 +00001025
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001026 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001027 if (reader == NULL)
1028 return NULL;
1029 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001030 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001031 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001032 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001033 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001034 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001035 return NULL;
1036 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001037 result = PyEval_CallObject(reader, args);
1038 Py_DECREF(reader);
1039 Py_DECREF(args);
1040 if (result != NULL && !PyString_Check(result)) {
1041 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001042 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001043 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +00001044 "object.readline() returned non-string");
1045 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +00001046 }
1047
1048 if (n < 0 && result != NULL && PyString_Check(result)) {
1049 char *s = PyString_AS_STRING(result);
1050 int len = PyString_GET_SIZE(result);
1051 if (len == 0) {
1052 Py_DECREF(result);
1053 result = NULL;
1054 PyErr_SetString(PyExc_EOFError,
1055 "EOF when reading a line");
1056 }
1057 else if (s[len-1] == '\n') {
1058 if (result->ob_refcnt == 1)
1059 _PyString_Resize(&result, len-1);
1060 else {
1061 PyObject *v;
1062 v = PyString_FromStringAndSize(s, len-1);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001063 Py_DECREF(result);
Guido van Rossum4ddf0a02001-01-07 20:51:39 +00001064 result = v;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001065 }
1066 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001067 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +00001068 return result;
Guido van Rossum0bd24411991-04-04 15:21:57 +00001069}
1070
1071/* Python method */
1072
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001073static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001074file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +00001075{
Guido van Rossum789a1611997-05-10 22:33:55 +00001076 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +00001077
Guido van Rossumd7297e61992-07-06 14:19:26 +00001078 if (f->f_fp == NULL)
1079 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +00001080 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +00001081 return NULL;
1082 if (n == 0)
1083 return PyString_FromString("");
1084 if (n < 0)
1085 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +00001086 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +00001087}
1088
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001089static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001090file_xreadlines(PyFileObject *f)
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001091{
1092 static PyObject* xreadlines_function = NULL;
Tim Petersf29b64d2001-01-15 06:33:19 +00001093
Neal Norwitz649b7592002-01-01 19:07:13 +00001094 if (f->f_fp == NULL)
1095 return err_closed();
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001096 if (!xreadlines_function) {
1097 PyObject *xreadlines_module =
1098 PyImport_ImportModule("xreadlines");
1099 if(!xreadlines_module)
1100 return NULL;
1101
1102 xreadlines_function = PyObject_GetAttrString(xreadlines_module,
1103 "xreadlines");
1104 Py_DECREF(xreadlines_module);
1105 if(!xreadlines_function)
1106 return NULL;
1107 }
1108 return PyObject_CallFunction(xreadlines_function, "(O)", f);
1109}
1110
1111static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001112file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001113{
Guido van Rossum789a1611997-05-10 22:33:55 +00001114 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001115 PyObject *list;
1116 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +00001117 char small_buffer[SMALLCHUNK];
1118 char *buffer = small_buffer;
1119 size_t buffersize = SMALLCHUNK;
1120 PyObject *big_buffer = NULL;
1121 size_t nfilled = 0;
1122 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +00001123 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +00001124 char *p, *q, *end;
1125 int err;
Guido van Rossum79fd0fc2001-10-12 20:01:53 +00001126 int shortread = 0;
Guido van Rossum0bd24411991-04-04 15:21:57 +00001127
Guido van Rossumd7297e61992-07-06 14:19:26 +00001128 if (f->f_fp == NULL)
1129 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +00001130 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +00001131 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001132 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001133 return NULL;
1134 for (;;) {
Guido van Rossum79fd0fc2001-10-12 20:01:53 +00001135 if (shortread)
1136 nread = 0;
1137 else {
1138 Py_BEGIN_ALLOW_THREADS
1139 errno = 0;
1140 nread = fread(buffer+nfilled, 1,
1141 buffersize-nfilled, f->f_fp);
1142 Py_END_ALLOW_THREADS
1143 shortread = (nread < buffersize-nfilled);
1144 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001145 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +00001146 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +00001147 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +00001148 break;
1149 PyErr_SetFromErrno(PyExc_IOError);
1150 clearerr(f->f_fp);
1151 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001152 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +00001153 list = NULL;
1154 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001155 }
Guido van Rossum789a1611997-05-10 22:33:55 +00001156 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +00001157 p = memchr(buffer+nfilled, '\n', nread);
1158 if (p == NULL) {
1159 /* Need a larger buffer to fit this line */
1160 nfilled += nread;
1161 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +00001162 if (buffersize > INT_MAX) {
1163 PyErr_SetString(PyExc_OverflowError,
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001164 "line is longer than a Python string can hold");
Trent Mickf29f47b2000-08-11 19:02:59 +00001165 goto error;
1166 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001167 if (big_buffer == NULL) {
1168 /* Create the big buffer */
1169 big_buffer = PyString_FromStringAndSize(
1170 NULL, buffersize);
1171 if (big_buffer == NULL)
1172 goto error;
1173 buffer = PyString_AS_STRING(big_buffer);
1174 memcpy(buffer, small_buffer, nfilled);
1175 }
1176 else {
1177 /* Grow the big buffer */
1178 _PyString_Resize(&big_buffer, buffersize);
1179 buffer = PyString_AS_STRING(big_buffer);
1180 }
1181 continue;
1182 }
1183 end = buffer+nfilled+nread;
1184 q = buffer;
1185 do {
1186 /* Process complete lines */
1187 p++;
1188 line = PyString_FromStringAndSize(q, p-q);
1189 if (line == NULL)
1190 goto error;
1191 err = PyList_Append(list, line);
1192 Py_DECREF(line);
1193 if (err != 0)
1194 goto error;
1195 q = p;
1196 p = memchr(q, '\n', end-q);
1197 } while (p != NULL);
1198 /* Move the remaining incomplete line to the start */
1199 nfilled = end-q;
1200 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +00001201 if (sizehint > 0)
1202 if (totalread >= (size_t)sizehint)
1203 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001204 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001205 if (nfilled != 0) {
1206 /* Partial last line */
1207 line = PyString_FromStringAndSize(buffer, nfilled);
1208 if (line == NULL)
1209 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +00001210 if (sizehint > 0) {
1211 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +00001212 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +00001213 if (rest == NULL) {
1214 Py_DECREF(line);
1215 goto error;
1216 }
1217 PyString_Concat(&line, rest);
1218 Py_DECREF(rest);
1219 if (line == NULL)
1220 goto error;
1221 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001222 err = PyList_Append(list, line);
1223 Py_DECREF(line);
1224 if (err != 0)
1225 goto error;
1226 }
1227 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001228 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001229 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001230 }
Guido van Rossumce5ba841991-03-06 13:06:18 +00001231 return list;
1232}
1233
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001234static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001235file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001236{
Guido van Rossumd7297e61992-07-06 14:19:26 +00001237 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001238 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001239 if (f->f_fp == NULL)
1240 return err_closed();
Michael W. Hudsone2ec3eb2001-10-31 18:51:01 +00001241 if (!PyArg_ParseTuple(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001242 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001243 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001244 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001245 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001246 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001247 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001248 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001249 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +00001250 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251 return NULL;
1252 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001253 Py_INCREF(Py_None);
1254 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001255}
1256
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001257static PyObject *
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001258file_writelines(PyFileObject *f, PyObject *seq)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001259{
Guido van Rossumee70ad12000-03-13 16:27:06 +00001260#define CHUNKSIZE 1000
1261 PyObject *list, *line;
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001262 PyObject *it; /* iter(seq) */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001263 PyObject *result;
1264 int i, j, index, len, nwritten, islist;
1265
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001266 assert(seq != NULL);
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001267 if (f->f_fp == NULL)
1268 return err_closed();
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001269
1270 result = NULL;
1271 list = NULL;
1272 islist = PyList_Check(seq);
1273 if (islist)
1274 it = NULL;
1275 else {
1276 it = PyObject_GetIter(seq);
1277 if (it == NULL) {
1278 PyErr_SetString(PyExc_TypeError,
1279 "writelines() requires an iterable argument");
1280 return NULL;
1281 }
1282 /* From here on, fail by going to error, to reclaim "it". */
1283 list = PyList_New(CHUNKSIZE);
1284 if (list == NULL)
1285 goto error;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001286 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001287
1288 /* Strategy: slurp CHUNKSIZE lines into a private list,
1289 checking that they are all strings, then write that list
1290 without holding the interpreter lock, then come back for more. */
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001291 for (index = 0; ; index += CHUNKSIZE) {
Guido van Rossumee70ad12000-03-13 16:27:06 +00001292 if (islist) {
1293 Py_XDECREF(list);
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001294 list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001295 if (list == NULL)
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001296 goto error;
Guido van Rossumee70ad12000-03-13 16:27:06 +00001297 j = PyList_GET_SIZE(list);
1298 }
1299 else {
1300 for (j = 0; j < CHUNKSIZE; j++) {
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001301 line = PyIter_Next(it);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001302 if (line == NULL) {
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001303 if (PyErr_Occurred())
1304 goto error;
1305 break;
Guido van Rossumee70ad12000-03-13 16:27:06 +00001306 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001307 PyList_SetItem(list, j, line);
1308 }
1309 }
1310 if (j == 0)
1311 break;
1312
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001313 /* Check that all entries are indeed strings. If not,
1314 apply the same rules as for file.write() and
1315 convert the results to strings. This is slow, but
1316 seems to be the only way since all conversion APIs
1317 could potentially execute Python code. */
1318 for (i = 0; i < j; i++) {
1319 PyObject *v = PyList_GET_ITEM(list, i);
1320 if (!PyString_Check(v)) {
1321 const char *buffer;
1322 int len;
Tim Peters86821b22001-01-07 21:19:34 +00001323 if (((f->f_binary &&
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001324 PyObject_AsReadBuffer(v,
1325 (const void**)&buffer,
1326 &len)) ||
1327 PyObject_AsCharBuffer(v,
1328 &buffer,
1329 &len))) {
1330 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001331 "writelines() argument must be a sequence of strings");
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001332 goto error;
1333 }
1334 line = PyString_FromStringAndSize(buffer,
1335 len);
1336 if (line == NULL)
1337 goto error;
1338 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001339 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001340 }
1341 }
1342
1343 /* Since we are releasing the global lock, the
1344 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001345 Py_BEGIN_ALLOW_THREADS
1346 f->f_softspace = 0;
1347 errno = 0;
1348 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001349 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001350 len = PyString_GET_SIZE(line);
1351 nwritten = fwrite(PyString_AS_STRING(line),
1352 1, len, f->f_fp);
1353 if (nwritten != len) {
1354 Py_BLOCK_THREADS
1355 PyErr_SetFromErrno(PyExc_IOError);
1356 clearerr(f->f_fp);
1357 goto error;
1358 }
1359 }
1360 Py_END_ALLOW_THREADS
1361
1362 if (j < CHUNKSIZE)
1363 break;
Guido van Rossumee70ad12000-03-13 16:27:06 +00001364 }
1365
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001366 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001367 result = Py_None;
1368 error:
1369 Py_XDECREF(list);
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001370 Py_XDECREF(it);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001371 return result;
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001372#undef CHUNKSIZE
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001373}
1374
Tim Petersefc3a3a2001-09-20 07:55:22 +00001375static char readline_doc[] =
1376"readline([size]) -> next line from the file, as a string.\n"
1377"\n"
1378"Retain newline. A non-negative size argument limits the maximum\n"
1379"number of bytes to return (an incomplete line may be returned then).\n"
1380"Return an empty string at EOF.";
1381
1382static char read_doc[] =
1383"read([size]) -> read at most size bytes, returned as a string.\n"
1384"\n"
1385"If the size argument is negative or omitted, read until EOF is reached.";
1386
1387static char write_doc[] =
1388"write(str) -> None. Write string str to file.\n"
1389"\n"
1390"Note that due to buffering, flush() or close() may be needed before\n"
1391"the file on disk reflects the data written.";
1392
1393static char fileno_doc[] =
1394"fileno() -> integer \"file descriptor\".\n"
1395"\n"
1396"This is needed for lower-level file interfaces, such os.read().";
1397
1398static char seek_doc[] =
1399"seek(offset[, whence]) -> None. Move to new file position.\n"
1400"\n"
1401"Argument offset is a byte count. Optional argument whence defaults to\n"
1402"0 (offset from start of file, offset should be >= 0); other values are 1\n"
1403"(move relative to current position, positive or negative), and 2 (move\n"
1404"relative to end of file, usually negative, although many platforms allow\n"
1405"seeking beyond the end of a file).\n"
1406"\n"
1407"Note that not all file objects are seekable.";
1408
Guido van Rossumd7047b31995-01-02 19:07:15 +00001409#ifdef HAVE_FTRUNCATE
Tim Petersefc3a3a2001-09-20 07:55:22 +00001410static char truncate_doc[] =
1411"truncate([size]) -> None. Truncate the file to at most size bytes.\n"
1412"\n"
1413"Size defaults to the current file position, as returned by tell().";
Guido van Rossumd7047b31995-01-02 19:07:15 +00001414#endif
Tim Petersefc3a3a2001-09-20 07:55:22 +00001415
1416static char tell_doc[] =
1417"tell() -> current file position, an integer (may be a long integer).";
1418
1419static char readinto_doc[] =
1420"readinto() -> Undocumented. Don't use this; it may go away.";
1421
1422static char readlines_doc[] =
1423"readlines([size]) -> list of strings, each a line from the file.\n"
1424"\n"
1425"Call readline() repeatedly and return a list of the lines so read.\n"
1426"The optional size argument, if given, is an approximate bound on the\n"
1427"total number of bytes in the lines returned.";
1428
1429static char xreadlines_doc[] =
1430"xreadlines() -> next line from the file, as a string.\n"
1431"\n"
1432"Equivalent to xreadlines.xreadlines(file). This is like readline(), but\n"
1433"often quicker, due to reading ahead internally.";
1434
1435static char writelines_doc[] =
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001436"writelines(sequence_of_strings) -> None. Write the strings to the file.\n"
Tim Petersefc3a3a2001-09-20 07:55:22 +00001437"\n"
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001438"Note that newlines are not added. The sequence can be any iterable object\n"
1439"producing strings. This is equivalent to calling write() for each string.";
Tim Petersefc3a3a2001-09-20 07:55:22 +00001440
1441static char flush_doc[] =
1442"flush() -> None. Flush the internal I/O buffer.";
1443
1444static char close_doc[] =
1445"close() -> None or (perhaps) an integer. Close the file.\n"
1446"\n"
1447"Sets data attribute .closed to true. A closed file cannot be used for\n"
1448"further I/O operations. close() may be called more than once without\n"
1449"error. Some kinds of file objects (for example, opened by popen())\n"
1450"may return an exit status upon closing.";
1451
1452static char isatty_doc[] =
1453"isatty() -> true or false. True if the file is connected to a tty device.";
1454
1455static PyMethodDef file_methods[] = {
1456 {"readline", (PyCFunction)file_readline, METH_VARARGS, readline_doc},
1457 {"read", (PyCFunction)file_read, METH_VARARGS, read_doc},
Michael W. Hudsone2ec3eb2001-10-31 18:51:01 +00001458 {"write", (PyCFunction)file_write, METH_VARARGS, write_doc},
Tim Petersefc3a3a2001-09-20 07:55:22 +00001459 {"fileno", (PyCFunction)file_fileno, METH_NOARGS, fileno_doc},
1460 {"seek", (PyCFunction)file_seek, METH_VARARGS, seek_doc},
1461#ifdef HAVE_FTRUNCATE
1462 {"truncate", (PyCFunction)file_truncate, METH_VARARGS, truncate_doc},
1463#endif
1464 {"tell", (PyCFunction)file_tell, METH_NOARGS, tell_doc},
1465 {"readinto", (PyCFunction)file_readinto, METH_OLDARGS, readinto_doc},
1466 {"readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc},
1467 {"xreadlines", (PyCFunction)file_xreadlines, METH_NOARGS, xreadlines_doc},
1468 {"writelines", (PyCFunction)file_writelines, METH_O, writelines_doc},
1469 {"flush", (PyCFunction)file_flush, METH_NOARGS, flush_doc},
1470 {"close", (PyCFunction)file_close, METH_NOARGS, close_doc},
1471 {"isatty", (PyCFunction)file_isatty, METH_NOARGS, isatty_doc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001472 {NULL, NULL} /* sentinel */
1473};
1474
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001475#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001476
Guido van Rossum6f799372001-09-20 20:46:19 +00001477static PyMemberDef file_memberlist[] = {
1478 {"softspace", T_INT, OFF(f_softspace), 0,
1479 "flag indicating that a space needs to be printed; used by print"},
1480 {"mode", T_OBJECT, OFF(f_mode), RO,
1481 "file mode ('r', 'w', 'a', possibly with 'b' or '+' added)"},
1482 {"name", T_OBJECT, OFF(f_name), RO,
1483 "file name"},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001484 /* getattr(f, "closed") is implemented without this table */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001485 {NULL} /* Sentinel */
1486};
1487
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001488static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00001489get_closed(PyFileObject *f, void *closure)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001490{
Tim Peters6d6c1a32001-08-02 04:15:00 +00001491 return PyInt_FromLong((long)(f->f_fp == 0));
Guido van Rossumb6775db1994-08-01 11:34:53 +00001492}
1493
Guido van Rossum32d34c82001-09-20 21:45:26 +00001494static PyGetSetDef file_getsetlist[] = {
1495 {"closed", (getter)get_closed, NULL, "flag set if the file is closed"},
Tim Peters6d6c1a32001-08-02 04:15:00 +00001496 {0},
1497};
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001498
Guido van Rossum65967252001-04-21 13:20:18 +00001499static PyObject *
Guido van Rossum5b021842001-05-22 16:48:37 +00001500file_getiter(PyObject *f)
Guido van Rossum65967252001-04-21 13:20:18 +00001501{
Guido van Rossum5b021842001-05-22 16:48:37 +00001502 return PyObject_CallMethod(f, "xreadlines", "");
Guido van Rossum65967252001-04-21 13:20:18 +00001503}
1504
Tim Peters59c9a642001-09-13 05:38:56 +00001505static PyObject *
1506file_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1507{
Tim Peters44410012001-09-14 03:26:08 +00001508 PyObject *self;
1509 static PyObject *not_yet_string;
1510
1511 assert(type != NULL && type->tp_alloc != NULL);
1512
1513 if (not_yet_string == NULL) {
1514 not_yet_string = PyString_FromString("<uninitialized file>");
1515 if (not_yet_string == NULL)
1516 return NULL;
1517 }
1518
1519 self = type->tp_alloc(type, 0);
1520 if (self != NULL) {
1521 /* Always fill in the name and mode, so that nobody else
1522 needs to special-case NULLs there. */
1523 Py_INCREF(not_yet_string);
1524 ((PyFileObject *)self)->f_name = not_yet_string;
1525 Py_INCREF(not_yet_string);
1526 ((PyFileObject *)self)->f_mode = not_yet_string;
1527 }
1528 return self;
1529}
1530
1531static int
1532file_init(PyObject *self, PyObject *args, PyObject *kwds)
1533{
1534 PyFileObject *foself = (PyFileObject *)self;
1535 int ret = 0;
Tim Peters59c9a642001-09-13 05:38:56 +00001536 static char *kwlist[] = {"name", "mode", "buffering", 0};
1537 char *name = NULL;
1538 char *mode = "r";
1539 int bufsize = -1;
Tim Peters44410012001-09-14 03:26:08 +00001540
1541 assert(PyFile_Check(self));
1542 if (foself->f_fp != NULL) {
1543 /* Have to close the existing file first. */
1544 PyObject *closeresult = file_close(foself);
1545 if (closeresult == NULL)
1546 return -1;
1547 Py_DECREF(closeresult);
1548 }
Tim Peters59c9a642001-09-13 05:38:56 +00001549
1550 if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist,
1551 Py_FileSystemDefaultEncoding, &name,
1552 &mode, &bufsize))
Tim Peters44410012001-09-14 03:26:08 +00001553 return -1;
1554 if (fill_file_fields(foself, NULL, name, mode, fclose) == NULL)
1555 goto Error;
1556 if (open_the_file(foself, name, mode) == NULL)
1557 goto Error;
1558 PyFile_SetBufSize(self, bufsize);
1559 goto Done;
1560
1561Error:
1562 ret = -1;
1563 /* fall through */
1564Done:
Tim Peters59c9a642001-09-13 05:38:56 +00001565 PyMem_Free(name); /* free the encoded string */
Tim Peters44410012001-09-14 03:26:08 +00001566 return ret;
Tim Peters59c9a642001-09-13 05:38:56 +00001567}
1568
Tim Peters59c9a642001-09-13 05:38:56 +00001569static char file_doc[] =
1570"file(name[, mode[, buffering]]) -> file object\n"
1571"\n"
1572"Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n"
1573"writing or appending. The file will be created if it doesn't exist\n"
1574"when opened for writing or appending; it will be truncated when\n"
1575"opened for writing. Add a 'b' to the mode for binary files.\n"
1576"Add a '+' to the mode to allow simultaneous reading and writing.\n"
1577"If the buffering argument is given, 0 means unbuffered, 1 means line\n"
Tim Peters742dfd62001-09-13 21:49:44 +00001578"buffered, and larger numbers specify the buffer size.\n"
1579"Note: open() is an alias for file().\n";
Tim Peters59c9a642001-09-13 05:38:56 +00001580
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001581PyTypeObject PyFile_Type = {
1582 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001583 0,
1584 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001585 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001586 0,
Guido van Rossum65967252001-04-21 13:20:18 +00001587 (destructor)file_dealloc, /* tp_dealloc */
1588 0, /* tp_print */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001589 0, /* tp_getattr */
1590 0, /* tp_setattr */
Guido van Rossum65967252001-04-21 13:20:18 +00001591 0, /* tp_compare */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001592 (reprfunc)file_repr, /* tp_repr */
Guido van Rossum65967252001-04-21 13:20:18 +00001593 0, /* tp_as_number */
1594 0, /* tp_as_sequence */
1595 0, /* tp_as_mapping */
1596 0, /* tp_hash */
1597 0, /* tp_call */
1598 0, /* tp_str */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001599 PyObject_GenericGetAttr, /* tp_getattro */
Guido van Rossum65967252001-04-21 13:20:18 +00001600 0, /* tp_setattro */
1601 0, /* tp_as_buffer */
Guido van Rossum9475a232001-10-05 20:51:39 +00001602 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters59c9a642001-09-13 05:38:56 +00001603 file_doc, /* tp_doc */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001604 0, /* tp_traverse */
1605 0, /* tp_clear */
Guido van Rossum65967252001-04-21 13:20:18 +00001606 0, /* tp_richcompare */
1607 0, /* tp_weaklistoffset */
Guido van Rossum5b021842001-05-22 16:48:37 +00001608 file_getiter, /* tp_iter */
Guido van Rossum213c7a62001-04-23 14:08:49 +00001609 0, /* tp_iternext */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001610 file_methods, /* tp_methods */
1611 file_memberlist, /* tp_members */
1612 file_getsetlist, /* tp_getset */
1613 0, /* tp_base */
1614 0, /* tp_dict */
Tim Peters59c9a642001-09-13 05:38:56 +00001615 0, /* tp_descr_get */
1616 0, /* tp_descr_set */
1617 0, /* tp_dictoffset */
Tim Peters44410012001-09-14 03:26:08 +00001618 (initproc)file_init, /* tp_init */
1619 PyType_GenericAlloc, /* tp_alloc */
Tim Peters59c9a642001-09-13 05:38:56 +00001620 file_new, /* tp_new */
Guido van Rossum9475a232001-10-05 20:51:39 +00001621 _PyObject_Del, /* tp_free */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001622};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001623
1624/* Interface for the 'soft space' between print items. */
1625
1626int
Fred Drakefd99de62000-07-09 05:02:18 +00001627PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001628{
1629 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001630 if (f == NULL) {
1631 /* Do nothing */
1632 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001633 else if (PyFile_Check(f)) {
1634 oldflag = ((PyFileObject *)f)->f_softspace;
1635 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001636 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001637 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001638 PyObject *v;
1639 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001640 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001641 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001642 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001643 if (PyInt_Check(v))
1644 oldflag = PyInt_AsLong(v);
1645 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001646 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001647 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001648 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001649 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001650 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001651 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1652 PyErr_Clear();
1653 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001654 }
1655 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001656 return oldflag;
1657}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001658
1659/* Interfaces to write objects/strings to file-like objects */
1660
1661int
Fred Drakefd99de62000-07-09 05:02:18 +00001662PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001663{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001664 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001665 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001666 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001667 return -1;
1668 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001669 else if (PyFile_Check(f)) {
1670 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001671 if (fp == NULL) {
1672 err_closed();
1673 return -1;
1674 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001675 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001676 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001677 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001678 if (writer == NULL)
1679 return -1;
Martin v. Löwis2777c022001-09-19 13:47:32 +00001680 if (flags & Py_PRINT_RAW) {
1681 if (PyUnicode_Check(v)) {
1682 value = v;
1683 Py_INCREF(value);
1684 } else
1685 value = PyObject_Str(v);
1686 }
1687 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001688 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001689 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001690 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001691 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001692 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001693 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001694 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001695 Py_DECREF(value);
1696 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001697 return -1;
1698 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001699 result = PyEval_CallObject(writer, args);
1700 Py_DECREF(args);
1701 Py_DECREF(value);
1702 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001703 if (result == NULL)
1704 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001705 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001706 return 0;
1707}
1708
Guido van Rossum27a60b11997-05-22 22:25:11 +00001709int
Tim Petersc1bbcb82001-11-28 22:13:25 +00001710PyFile_WriteString(const char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001711{
1712 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001713 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001714 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001715 PyErr_SetString(PyExc_SystemError,
1716 "null file for PyFile_WriteString");
1717 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001718 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001719 else if (PyFile_Check(f)) {
1720 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001721 if (fp == NULL) {
1722 err_closed();
1723 return -1;
1724 }
1725 fputs(s, fp);
1726 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001727 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001728 else if (!PyErr_Occurred()) {
1729 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001730 int err;
1731 if (v == NULL)
1732 return -1;
1733 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1734 Py_DECREF(v);
1735 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001736 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001737 else
1738 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001739}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001740
1741/* Try to get a file-descriptor from a Python object. If the object
1742 is an integer or long integer, its value is returned. If not, the
1743 object's fileno() method is called if it exists; the method must return
1744 an integer or long integer, which is returned as the file descriptor value.
1745 -1 is returned on failure.
1746*/
1747
1748int PyObject_AsFileDescriptor(PyObject *o)
1749{
1750 int fd;
1751 PyObject *meth;
1752
1753 if (PyInt_Check(o)) {
1754 fd = PyInt_AsLong(o);
1755 }
1756 else if (PyLong_Check(o)) {
1757 fd = PyLong_AsLong(o);
1758 }
1759 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1760 {
1761 PyObject *fno = PyEval_CallObject(meth, NULL);
1762 Py_DECREF(meth);
1763 if (fno == NULL)
1764 return -1;
Tim Peters86821b22001-01-07 21:19:34 +00001765
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001766 if (PyInt_Check(fno)) {
1767 fd = PyInt_AsLong(fno);
1768 Py_DECREF(fno);
1769 }
1770 else if (PyLong_Check(fno)) {
1771 fd = PyLong_AsLong(fno);
1772 Py_DECREF(fno);
1773 }
1774 else {
1775 PyErr_SetString(PyExc_TypeError,
1776 "fileno() returned a non-integer");
1777 Py_DECREF(fno);
1778 return -1;
1779 }
1780 }
1781 else {
1782 PyErr_SetString(PyExc_TypeError,
1783 "argument must be an int, or have a fileno() method.");
1784 return -1;
1785 }
1786
1787 if (fd < 0) {
1788 PyErr_Format(PyExc_ValueError,
1789 "file descriptor cannot be a negative integer (%i)",
1790 fd);
1791 return -1;
1792 }
1793 return fd;
1794}