blob: c8fb214e2fcbd46ad9671ce23f7044e1c021f18a [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
Tim Peters59c9a642001-09-13 05:38:56 +000059
60static PyObject *
61fill_file_fields(PyFileObject *f, FILE *fp, char *name, char *mode,
62 int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000063{
Tim Peters59c9a642001-09-13 05:38:56 +000064 assert(f != NULL);
65 assert(PyFile_Check(f));
Tim Peters44410012001-09-14 03:26:08 +000066 assert(f->f_fp == NULL);
67
68 Py_DECREF(f->f_name);
69 Py_DECREF(f->f_mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +000070 f->f_name = PyString_FromString(name);
71 f->f_mode = PyString_FromString(mode);
Tim Peters44410012001-09-14 03:26:08 +000072
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000073 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000074 f->f_softspace = 0;
Tim Peters59c9a642001-09-13 05:38:56 +000075 f->f_binary = strchr(mode,'b') != NULL;
Tim Peters44410012001-09-14 03:26:08 +000076
Tim Peters59c9a642001-09-13 05:38:56 +000077 if (f->f_name == NULL || f->f_mode == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000080 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081}
82
Tim Peters59c9a642001-09-13 05:38:56 +000083static PyObject *
84open_the_file(PyFileObject *f, char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085{
Tim Peters59c9a642001-09-13 05:38:56 +000086 assert(f != NULL);
87 assert(PyFile_Check(f));
88 assert(name != NULL);
89 assert(mode != NULL);
Tim Peters44410012001-09-14 03:26:08 +000090 assert(f->f_fp == NULL);
Tim Peters59c9a642001-09-13 05:38:56 +000091
Tim Peters8fa45672001-09-13 21:01:29 +000092 /* rexec.py can't stop a user from getting the file() constructor --
93 all they have to do is get *any* file object f, and then do
94 type(f). Here we prevent them from doing damage with it. */
95 if (PyEval_GetRestricted()) {
96 PyErr_SetString(PyExc_IOError,
97 "file() constructor not accessible in restricted mode");
98 return NULL;
99 }
Tim Petersa27a1502001-11-09 20:59:14 +0000100 errno = 0;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000101#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000102 if (*mode == '*') {
103 FILE *fopenRF();
104 f->f_fp = fopenRF(name, mode+1);
105 }
106 else
107#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000108 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000110 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000111 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000112 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000113 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000114#ifdef NO_FOPEN_ERRNO
Jack Jansenb3be2162001-11-30 14:16:36 +0000115 /* Metroworks only, wich does not always sets errno */
Jeremy Hylton41c83212001-11-09 16:17:24 +0000116 if (errno == 0) {
Jack Jansenb3be2162001-11-30 14:16:36 +0000117 PyObject *v;
118 v = Py_BuildValue("(is)", 0, "Cannot open file");
119 if (v != NULL) {
120 PyErr_SetObject(PyExc_IOError, v);
121 Py_DECREF(v);
122 }
Jack Jansene08dea191995-04-23 22:12:47 +0000123 return NULL;
124 }
125#endif
Jeremy Hylton41c83212001-11-09 16:17:24 +0000126 if (errno == EINVAL)
127 PyErr_Format(PyExc_IOError, "invalid argument: %s",
128 mode);
129 else
130 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Tim Peters59c9a642001-09-13 05:38:56 +0000131 f = NULL;
132 }
133 return (PyObject *)f;
134}
135
136PyObject *
137PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
138{
Tim Peters44410012001-09-14 03:26:08 +0000139 PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type,
140 NULL, NULL);
Tim Peters59c9a642001-09-13 05:38:56 +0000141 if (f != NULL) {
142 if (fill_file_fields(f, fp, name, mode, close) == NULL) {
143 Py_DECREF(f);
144 f = NULL;
145 }
146 }
147 return (PyObject *) f;
148}
149
150PyObject *
151PyFile_FromString(char *name, char *mode)
152{
153 extern int fclose(FILE *);
154 PyFileObject *f;
155
156 f = (PyFileObject *)PyFile_FromFile((FILE *)NULL, name, mode, fclose);
157 if (f != NULL) {
158 if (open_the_file(f, name, mode) == NULL) {
159 Py_DECREF(f);
160 f = NULL;
161 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000163 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164}
165
Guido van Rossumb6775db1994-08-01 11:34:53 +0000166void
Fred Drakefd99de62000-07-09 05:02:18 +0000167PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168{
169 if (bufsize >= 0) {
170#ifdef HAVE_SETVBUF
171 int type;
172 switch (bufsize) {
173 case 0:
174 type = _IONBF;
175 break;
176 case 1:
177 type = _IOLBF;
178 bufsize = BUFSIZ;
179 break;
180 default:
181 type = _IOFBF;
182 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000183 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
184 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000185#else /* !HAVE_SETVBUF */
186 if (bufsize <= 1)
187 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
188#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189 }
190}
191
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000192static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000193err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000194{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000195 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000196 return NULL;
197}
198
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000199/* Methods */
200
201static void
Fred Drakefd99de62000-07-09 05:02:18 +0000202file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000203{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000204 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000206 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000208 }
Tim Peters44410012001-09-14 03:26:08 +0000209 Py_XDECREF(f->f_name);
210 Py_XDECREF(f->f_mode);
Guido van Rossum9475a232001-10-05 20:51:39 +0000211 f->ob_type->tp_free((PyObject *)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212}
213
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000214static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000215file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216{
Barry Warsaw7ce36942001-08-24 18:34:26 +0000217 return PyString_FromFormat("<%s file '%s', mode '%s' at %p>",
218 f->f_fp == NULL ? "closed" : "open",
219 PyString_AsString(f->f_name),
220 PyString_AsString(f->f_mode),
221 f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222}
223
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000225file_close(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000227 int sts = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000229 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000231 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000232 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000234 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 f->f_fp = NULL;
236 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000237 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000238 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000239 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 return PyInt_FromLong((long)sts);
241 Py_INCREF(Py_None);
242 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243}
244
Trent Mickf29f47b2000-08-11 19:02:59 +0000245
Guido van Rossumb8552162001-09-05 14:58:11 +0000246/* Our very own off_t-like type, 64-bit if possible */
247#if !defined(HAVE_LARGEFILE_SUPPORT)
248typedef off_t Py_off_t;
249#elif SIZEOF_OFF_T >= 8
250typedef off_t Py_off_t;
251#elif SIZEOF_FPOS_T >= 8
Guido van Rossum4f53da02001-03-01 18:26:53 +0000252typedef fpos_t Py_off_t;
253#else
Guido van Rossumb8552162001-09-05 14:58:11 +0000254#error "Large file support, but neither off_t nor fpos_t is large enough."
Guido van Rossum4f53da02001-03-01 18:26:53 +0000255#endif
256
257
Trent Mickf29f47b2000-08-11 19:02:59 +0000258/* a portable fseek() function
259 return 0 on success, non-zero on failure (with errno set) */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000260static int
Guido van Rossum4f53da02001-03-01 18:26:53 +0000261_portable_fseek(FILE *fp, Py_off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000262{
Guido van Rossumb8552162001-09-05 14:58:11 +0000263#if !defined(HAVE_LARGEFILE_SUPPORT)
264 return fseek(fp, offset, whence);
265#elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000266 return fseeko(fp, offset, whence);
267#elif defined(HAVE_FSEEK64)
268 return fseek64(fp, offset, whence);
Fred Drakedb810ac2000-10-06 20:42:33 +0000269#elif defined(__BEOS__)
270 return _fseek(fp, offset, whence);
Guido van Rossumb8552162001-09-05 14:58:11 +0000271#elif SIZEOF_FPOS_T >= 8
Guido van Rossume54e0be2001-01-16 20:53:31 +0000272 /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
273 and fgetpos() to implement fseek()*/
Trent Mickf29f47b2000-08-11 19:02:59 +0000274 fpos_t pos;
275 switch (whence) {
Guido van Rossume54e0be2001-01-16 20:53:31 +0000276 case SEEK_END:
Guido van Rossum8b4e43e2001-09-10 20:43:35 +0000277#ifdef MS_WINDOWS
278 fflush(fp);
279 if (_lseeki64(fileno(fp), 0, 2) == -1)
280 return -1;
281#else
Guido van Rossume54e0be2001-01-16 20:53:31 +0000282 if (fseek(fp, 0, SEEK_END) != 0)
283 return -1;
Guido van Rossum8b4e43e2001-09-10 20:43:35 +0000284#endif
Guido van Rossume54e0be2001-01-16 20:53:31 +0000285 /* fall through */
286 case SEEK_CUR:
287 if (fgetpos(fp, &pos) != 0)
288 return -1;
289 offset += pos;
290 break;
291 /* case SEEK_SET: break; */
Trent Mickf29f47b2000-08-11 19:02:59 +0000292 }
293 return fsetpos(fp, &offset);
294#else
Guido van Rossumb8552162001-09-05 14:58:11 +0000295#error "Large file support, but no way to fseek."
Trent Mickf29f47b2000-08-11 19:02:59 +0000296#endif
297}
298
299
300/* a portable ftell() function
301 Return -1 on failure with errno set appropriately, current file
302 position on success */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000303static Py_off_t
Fred Drake8ce159a2000-08-31 05:18:54 +0000304_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000305{
Guido van Rossumb8552162001-09-05 14:58:11 +0000306#if !defined(HAVE_LARGEFILE_SUPPORT)
307 return ftell(fp);
308#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8
309 return ftello(fp);
310#elif defined(HAVE_FTELL64)
311 return ftell64(fp);
312#elif SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000313 fpos_t pos;
314 if (fgetpos(fp, &pos) != 0)
315 return -1;
316 return pos;
317#else
Guido van Rossumb8552162001-09-05 14:58:11 +0000318#error "Large file support, but no way to ftell."
Trent Mickf29f47b2000-08-11 19:02:59 +0000319#endif
320}
321
322
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000324file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000326 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000327 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000328 Py_off_t offset;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000329 PyObject *offobj;
Tim Peters86821b22001-01-07 21:19:34 +0000330
Guido van Rossumd7297e61992-07-06 14:19:26 +0000331 if (f->f_fp == NULL)
332 return err_closed();
333 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000334 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000335 return NULL;
336#if !defined(HAVE_LARGEFILE_SUPPORT)
337 offset = PyInt_AsLong(offobj);
338#else
339 offset = PyLong_Check(offobj) ?
340 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
341#endif
342 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000343 return NULL;
Tim Peters86821b22001-01-07 21:19:34 +0000344
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000345 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000346 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000347 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000348 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000349
Guido van Rossumff4949e1992-08-05 19:58:53 +0000350 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000352 clearerr(f->f_fp);
353 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000354 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 Py_INCREF(Py_None);
356 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000357}
358
Trent Mickf29f47b2000-08-11 19:02:59 +0000359
Guido van Rossumd7047b31995-01-02 19:07:15 +0000360#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000361static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000362file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000363{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000364 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000365 Py_off_t newsize;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000366 PyObject *newsizeobj;
Tim Peters86821b22001-01-07 21:19:34 +0000367
Guido van Rossumd7047b31995-01-02 19:07:15 +0000368 if (f->f_fp == NULL)
369 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000370 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000371 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000372 return NULL;
Tim Petersfb05db22002-03-11 00:24:00 +0000373
374 /* Set newsize to current postion if newsizeobj NULL, else to the
375 specified value. */
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000376 if (newsizeobj != NULL) {
377#if !defined(HAVE_LARGEFILE_SUPPORT)
378 newsize = PyInt_AsLong(newsizeobj);
379#else
380 newsize = PyLong_Check(newsizeobj) ?
381 PyLong_AsLongLong(newsizeobj) :
382 PyInt_AsLong(newsizeobj);
383#endif
384 if (PyErr_Occurred())
385 return NULL;
Tim Petersfb05db22002-03-11 00:24:00 +0000386 }
387 else {
388 /* Default to current position. */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000390 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000391 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 Py_END_ALLOW_THREADS
Tim Petersfb05db22002-03-11 00:24:00 +0000393 if (newsize == -1)
394 goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000395 }
Tim Petersfb05db22002-03-11 00:24:00 +0000396
397 /* Flush the file. */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000398 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000399 errno = 0;
400 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401 Py_END_ALLOW_THREADS
Tim Petersfb05db22002-03-11 00:24:00 +0000402 if (ret != 0)
403 goto onioerror;
Trent Mickf29f47b2000-08-11 19:02:59 +0000404
405#ifdef MS_WIN32
Tim Petersfb05db22002-03-11 00:24:00 +0000406 /* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
Tim Peters8f01b682002-03-12 03:04:44 +0000407 so don't even try using it. */
Tim Petersfb05db22002-03-11 00:24:00 +0000408 {
Tim Peters8f01b682002-03-12 03:04:44 +0000409 Py_off_t current; /* current file position */
Tim Petersfb05db22002-03-11 00:24:00 +0000410 HANDLE hFile;
411 int error;
412
Tim Peters8f01b682002-03-12 03:04:44 +0000413 /* current <- current file postion. */
414 if (newsizeobj == NULL)
415 current = newsize;
416 else {
Tim Petersfb05db22002-03-11 00:24:00 +0000417 Py_BEGIN_ALLOW_THREADS
418 errno = 0;
Tim Peters8f01b682002-03-12 03:04:44 +0000419 current = _portable_ftell(f->f_fp);
420 Py_END_ALLOW_THREADS
421 if (current == -1)
422 goto onioerror;
423 }
424
425 /* Move to newsize. */
426 if (current != newsize) {
427 Py_BEGIN_ALLOW_THREADS
428 errno = 0;
429 error = _portable_fseek(f->f_fp, newsize, SEEK_SET)
430 != 0;
Tim Petersfb05db22002-03-11 00:24:00 +0000431 Py_END_ALLOW_THREADS
432 if (error)
433 goto onioerror;
434 }
435
Tim Peters8f01b682002-03-12 03:04:44 +0000436 /* Truncate. Note that this may grow the file! */
437 Py_BEGIN_ALLOW_THREADS
438 errno = 0;
439 hFile = (HANDLE)_get_osfhandle(fileno(f->f_fp));
440 error = hFile == (HANDLE)-1;
441 if (!error) {
442 error = SetEndOfFile(hFile) == 0;
443 if (error)
444 errno = EACCES;
445 }
446 Py_END_ALLOW_THREADS
447 if (error)
448 goto onioerror;
449
450 /* Restore original file position. */
451 if (current != newsize) {
452 Py_BEGIN_ALLOW_THREADS
453 errno = 0;
454 error = _portable_fseek(f->f_fp, current, SEEK_SET)
455 != 0;
456 Py_END_ALLOW_THREADS
457 if (error)
458 goto onioerror;
459 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000460 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000461#else
462 Py_BEGIN_ALLOW_THREADS
463 errno = 0;
464 ret = ftruncate(fileno(f->f_fp), newsize);
465 Py_END_ALLOW_THREADS
466 if (ret != 0) goto onioerror;
467#endif /* !MS_WIN32 */
Tim Peters86821b22001-01-07 21:19:34 +0000468
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000469 Py_INCREF(Py_None);
470 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000471
472onioerror:
473 PyErr_SetFromErrno(PyExc_IOError);
474 clearerr(f->f_fp);
475 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000476}
477#endif /* HAVE_FTRUNCATE */
478
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000479static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000480file_tell(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000481{
Guido van Rossum4f53da02001-03-01 18:26:53 +0000482 Py_off_t pos;
Trent Mickf29f47b2000-08-11 19:02:59 +0000483
Guido van Rossumd7297e61992-07-06 14:19:26 +0000484 if (f->f_fp == NULL)
485 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000486 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000487 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000488 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000490 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000491 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000492 clearerr(f->f_fp);
493 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000494 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000495#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000496 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000497#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000498 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000499#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000500}
501
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000503file_fileno(PyFileObject *f)
Guido van Rossumed233a51992-06-23 09:07:03 +0000504{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000505 if (f->f_fp == NULL)
506 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000507 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000508}
509
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000510static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000511file_flush(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000512{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000513 int res;
Tim Peters86821b22001-01-07 21:19:34 +0000514
Guido van Rossumd7297e61992-07-06 14:19:26 +0000515 if (f->f_fp == NULL)
516 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000517 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000518 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000519 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000520 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000521 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000522 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000523 clearerr(f->f_fp);
524 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000525 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000526 Py_INCREF(Py_None);
527 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000528}
529
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000530static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000531file_isatty(PyFileObject *f)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000532{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000533 long res;
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 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000537 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000538 Py_END_ALLOW_THREADS
539 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000540}
541
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000542
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000543#if BUFSIZ < 8192
544#define SMALLCHUNK 8192
545#else
546#define SMALLCHUNK BUFSIZ
547#endif
548
Guido van Rossum3c259041999-01-14 19:00:14 +0000549#if SIZEOF_INT < 4
550#define BIGCHUNK (512 * 32)
551#else
552#define BIGCHUNK (512 * 1024)
553#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000554
555static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000556new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000557{
558#ifdef HAVE_FSTAT
Fred Drake1bc8fab2001-07-19 21:49:38 +0000559 off_t pos, end;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000560 struct stat st;
561 if (fstat(fileno(f->f_fp), &st) == 0) {
562 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000563 /* The following is not a bug: we really need to call lseek()
564 *and* ftell(). The reason is that some stdio libraries
565 mistakenly flush their buffer when ftell() is called and
566 the lseek() call it makes fails, thereby throwing away
567 data that cannot be recovered in any way. To avoid this,
568 we first test lseek(), and only call ftell() if lseek()
569 works. We can't use the lseek() value either, because we
570 need to take the amount of buffered data into account.
571 (Yet another reason why stdio stinks. :-) */
Jack Jansen2771b5b2001-10-10 22:03:27 +0000572#ifdef USE_GUSI2
573 pos = lseek(fileno(f->f_fp), 1L, SEEK_CUR);
574 pos = lseek(fileno(f->f_fp), -1L, SEEK_CUR);
575#else
Guido van Rossum91aaa921998-05-05 22:21:35 +0000576 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
Jack Jansen2771b5b2001-10-10 22:03:27 +0000577#endif
578 if (pos >= 0) {
Guido van Rossum91aaa921998-05-05 22:21:35 +0000579 pos = ftell(f->f_fp);
Jack Jansen2771b5b2001-10-10 22:03:27 +0000580 }
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000581 if (pos < 0)
582 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000583 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000584 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000585 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000586 }
587#endif
588 if (currentsize > SMALLCHUNK) {
589 /* Keep doubling until we reach BIGCHUNK;
590 then keep adding BIGCHUNK. */
591 if (currentsize <= BIGCHUNK)
592 return currentsize + currentsize;
593 else
594 return currentsize + BIGCHUNK;
595 }
596 return currentsize + SMALLCHUNK;
597}
598
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000599static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000600file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000601{
Guido van Rossum789a1611997-05-10 22:33:55 +0000602 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000603 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 PyObject *v;
Tim Peters86821b22001-01-07 21:19:34 +0000605
Guido van Rossumd7297e61992-07-06 14:19:26 +0000606 if (f->f_fp == NULL)
607 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000608 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000609 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000610 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000611 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000612 else
613 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000614 if (buffersize > INT_MAX) {
615 PyErr_SetString(PyExc_OverflowError,
616 "requested number of bytes is more than a Python string can hold");
617 return NULL;
618 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000619 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000620 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000621 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000622 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000623 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000624 Py_BEGIN_ALLOW_THREADS
625 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000626 chunksize = fread(BUF(v) + bytesread, 1,
627 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000628 Py_END_ALLOW_THREADS
629 if (chunksize == 0) {
630 if (!ferror(f->f_fp))
631 break;
632 PyErr_SetFromErrno(PyExc_IOError);
633 clearerr(f->f_fp);
634 Py_DECREF(v);
635 return NULL;
636 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000637 bytesread += chunksize;
638 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000639 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000640 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000641 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000642 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000643 return NULL;
644 }
645 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000646 if (bytesread != buffersize)
647 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000648 return v;
649}
650
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000651static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000652file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000653{
654 char *ptr;
Guido van Rossum00ebd462001-10-23 21:25:24 +0000655 int ntodo;
656 size_t ndone, nnow;
Tim Peters86821b22001-01-07 21:19:34 +0000657
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000658 if (f->f_fp == NULL)
659 return err_closed();
660 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
661 return NULL;
662 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000663 while (ntodo > 0) {
664 Py_BEGIN_ALLOW_THREADS
665 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000666 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000667 Py_END_ALLOW_THREADS
668 if (nnow == 0) {
669 if (!ferror(f->f_fp))
670 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000671 PyErr_SetFromErrno(PyExc_IOError);
672 clearerr(f->f_fp);
673 return NULL;
674 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000675 ndone += nnow;
676 ntodo -= nnow;
677 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000678 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000679}
680
Tim Peters86821b22001-01-07 21:19:34 +0000681/**************************************************************************
Tim Petersf29b64d2001-01-15 06:33:19 +0000682Routine to get next line using platform fgets().
Tim Peters86821b22001-01-07 21:19:34 +0000683
684Under MSVC 6:
685
Tim Peters1c733232001-01-08 04:02:07 +0000686+ MS threadsafe getc is very slow (multiple layers of function calls before+
687 after each character, to lock+unlock the stream).
688+ The stream-locking functions are MS-internal -- can't access them from user
689 code.
690+ There's nothing Tim could find in the MS C or platform SDK libraries that
691 can worm around this.
Tim Peters86821b22001-01-07 21:19:34 +0000692+ MS fgets locks/unlocks only once per line; it's the only hook we have.
693
694So we use fgets for speed(!), despite that it's painful.
695
696MS realloc is also slow.
697
Tim Petersf29b64d2001-01-15 06:33:19 +0000698Reports from other platforms on this method vs getc_unlocked (which MS doesn't
699have):
700 Linux a wash
701 Solaris a wash
702 Tru64 Unix getline_via_fgets significantly faster
Tim Peters86821b22001-01-07 21:19:34 +0000703
Tim Petersf29b64d2001-01-15 06:33:19 +0000704CAUTION: The C std isn't clear about this: in those cases where fgets
705writes something into the buffer, can it write into any position beyond the
706required trailing null byte? MSVC 6 fgets does not, and no platform is (yet)
707known on which it does; and it would be a strange way to code fgets. Still,
708getline_via_fgets may not work correctly if it does. The std test
709test_bufio.py should fail if platform fgets() routinely writes beyond the
710trailing null byte. #define DONT_USE_FGETS_IN_GETLINE to disable this code.
Tim Peters86821b22001-01-07 21:19:34 +0000711**************************************************************************/
712
Tim Petersf29b64d2001-01-15 06:33:19 +0000713/* Use this routine if told to, or by default on non-get_unlocked()
714 * platforms unless told not to. Yikes! Let's spell that out:
715 * On a platform with getc_unlocked():
716 * By default, use getc_unlocked().
717 * If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
718 * On a platform without getc_unlocked():
719 * By default, use fgets().
720 * If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
721 */
722#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
723#define USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000724#endif
725
Tim Petersf29b64d2001-01-15 06:33:19 +0000726#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
727#undef USE_FGETS_IN_GETLINE
728#endif
729
730#ifdef USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000731static PyObject*
Tim Petersf29b64d2001-01-15 06:33:19 +0000732getline_via_fgets(FILE *fp)
Tim Peters86821b22001-01-07 21:19:34 +0000733{
Tim Peters15b83852001-01-08 00:53:12 +0000734/* INITBUFSIZE is the maximum line length that lets us get away with the fast
Tim Peters142297a2001-01-15 10:36:56 +0000735 * no-realloc, one-fgets()-call path. Boosting it isn't free, because we have
736 * to fill this much of the buffer with a known value in order to figure out
737 * how much of the buffer fgets() overwrites. So if INITBUFSIZE is larger
738 * than "most" lines, we waste time filling unused buffer slots. 100 is
739 * surely adequate for most peoples' email archives, chewing over source code,
740 * etc -- "regular old text files".
741 * MAXBUFSIZE is the maximum line length that lets us get away with the less
742 * fast (but still zippy) no-realloc, two-fgets()-call path. See above for
743 * cautions about boosting that. 300 was chosen because the worst real-life
744 * text-crunching job reported on Python-Dev was a mail-log crawler where over
745 * half the lines were 254 chars.
746 * INCBUFSIZE is the amount by which we grow the buffer, if MAXBUFSIZE isn't
747 * enough. It doesn't much matter what this is set to: we only get here for
748 * absurdly long lines anyway.
Tim Peters15b83852001-01-08 00:53:12 +0000749 */
Tim Peters142297a2001-01-15 10:36:56 +0000750#define INITBUFSIZE 100
751#define MAXBUFSIZE 300
Tim Peters86821b22001-01-07 21:19:34 +0000752#define INCBUFSIZE 1000
Tim Peters142297a2001-01-15 10:36:56 +0000753 char* p; /* temp */
754 char buf[MAXBUFSIZE];
Tim Peters86821b22001-01-07 21:19:34 +0000755 PyObject* v; /* the string object result */
Tim Peters86821b22001-01-07 21:19:34 +0000756 char* pvfree; /* address of next free slot */
757 char* pvend; /* address one beyond last free slot */
Tim Peters142297a2001-01-15 10:36:56 +0000758 size_t nfree; /* # of free buffer slots; pvend-pvfree */
759 size_t total_v_size; /* total # of slots in buffer */
Tim Peters86821b22001-01-07 21:19:34 +0000760
Tim Peters15b83852001-01-08 00:53:12 +0000761 /* Optimize for normal case: avoid _PyString_Resize if at all
Tim Peters142297a2001-01-15 10:36:56 +0000762 * possible via first reading into stack buffer "buf".
Tim Peters15b83852001-01-08 00:53:12 +0000763 */
Tim Peters142297a2001-01-15 10:36:56 +0000764 total_v_size = INITBUFSIZE; /* start small and pray */
765 pvfree = buf;
766 for (;;) {
767 Py_BEGIN_ALLOW_THREADS
768 pvend = buf + total_v_size;
769 nfree = pvend - pvfree;
770 memset(pvfree, '\n', nfree);
771 p = fgets(pvfree, nfree, fp);
772 Py_END_ALLOW_THREADS
Tim Peters15b83852001-01-08 00:53:12 +0000773
Tim Peters142297a2001-01-15 10:36:56 +0000774 if (p == NULL) {
775 clearerr(fp);
776 if (PyErr_CheckSignals())
777 return NULL;
778 v = PyString_FromStringAndSize(buf, pvfree - buf);
Tim Peters86821b22001-01-07 21:19:34 +0000779 return v;
780 }
Tim Peters142297a2001-01-15 10:36:56 +0000781 /* fgets read *something* */
782 p = memchr(pvfree, '\n', nfree);
783 if (p != NULL) {
784 /* Did the \n come from fgets or from us?
785 * Since fgets stops at the first \n, and then writes
786 * \0, if it's from fgets a \0 must be next. But if
787 * that's so, it could not have come from us, since
788 * the \n's we filled the buffer with have only more
789 * \n's to the right.
790 */
791 if (p+1 < pvend && *(p+1) == '\0') {
792 /* It's from fgets: we win! In particular,
793 * we haven't done any mallocs yet, and can
794 * build the final result on the first try.
795 */
796 ++p; /* include \n from fgets */
797 }
798 else {
799 /* Must be from us: fgets didn't fill the
800 * buffer and didn't find a newline, so it
801 * must be the last and newline-free line of
802 * the file.
803 */
804 assert(p > pvfree && *(p-1) == '\0');
805 --p; /* don't include \0 from fgets */
806 }
807 v = PyString_FromStringAndSize(buf, p - buf);
808 return v;
809 }
810 /* yuck: fgets overwrote all the newlines, i.e. the entire
811 * buffer. So this line isn't over yet, or maybe it is but
812 * we're exactly at EOF. If we haven't already, try using the
813 * rest of the stack buffer.
Tim Peters86821b22001-01-07 21:19:34 +0000814 */
Tim Peters142297a2001-01-15 10:36:56 +0000815 assert(*(pvend-1) == '\0');
816 if (pvfree == buf) {
817 pvfree = pvend - 1; /* overwrite trailing null */
818 total_v_size = MAXBUFSIZE;
819 }
820 else
821 break;
Tim Peters86821b22001-01-07 21:19:34 +0000822 }
Tim Peters142297a2001-01-15 10:36:56 +0000823
824 /* The stack buffer isn't big enough; malloc a string object and read
825 * into its buffer.
Tim Peters15b83852001-01-08 00:53:12 +0000826 */
Tim Peters142297a2001-01-15 10:36:56 +0000827 total_v_size = MAXBUFSIZE + INCBUFSIZE;
Tim Peters1c733232001-01-08 04:02:07 +0000828 v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
Tim Peters15b83852001-01-08 00:53:12 +0000829 if (v == NULL)
830 return v;
831 /* copy over everything except the last null byte */
Tim Peters142297a2001-01-15 10:36:56 +0000832 memcpy(BUF(v), buf, MAXBUFSIZE-1);
833 pvfree = BUF(v) + MAXBUFSIZE - 1;
Tim Peters86821b22001-01-07 21:19:34 +0000834
835 /* Keep reading stuff into v; if it ever ends successfully, break
Tim Peters15b83852001-01-08 00:53:12 +0000836 * after setting p one beyond the end of the line. The code here is
837 * very much like the code above, except reads into v's buffer; see
838 * the code above for detailed comments about the logic.
Tim Peters86821b22001-01-07 21:19:34 +0000839 */
840 for (;;) {
Tim Peters86821b22001-01-07 21:19:34 +0000841 Py_BEGIN_ALLOW_THREADS
842 pvend = BUF(v) + total_v_size;
843 nfree = pvend - pvfree;
844 memset(pvfree, '\n', nfree);
845 p = fgets(pvfree, nfree, fp);
846 Py_END_ALLOW_THREADS
847
848 if (p == NULL) {
849 clearerr(fp);
850 if (PyErr_CheckSignals()) {
851 Py_DECREF(v);
852 return NULL;
853 }
854 p = pvfree;
855 break;
856 }
Tim Peters86821b22001-01-07 21:19:34 +0000857 p = memchr(pvfree, '\n', nfree);
858 if (p != NULL) {
859 if (p+1 < pvend && *(p+1) == '\0') {
860 /* \n came from fgets */
861 ++p;
862 break;
863 }
864 /* \n came from us; last line of file, no newline */
865 assert(p > pvfree && *(p-1) == '\0');
866 --p;
867 break;
868 }
869 /* expand buffer and try again */
870 assert(*(pvend-1) == '\0');
871 total_v_size += INCBUFSIZE;
872 if (total_v_size > INT_MAX) {
873 PyErr_SetString(PyExc_OverflowError,
874 "line is longer than a Python string can hold");
875 Py_DECREF(v);
876 return NULL;
877 }
878 if (_PyString_Resize(&v, (int)total_v_size) < 0)
879 return NULL;
880 /* overwrite the trailing null byte */
881 pvfree = BUF(v) + (total_v_size - INCBUFSIZE - 1);
882 }
883 if (BUF(v) + total_v_size != p)
884 _PyString_Resize(&v, p - BUF(v));
885 return v;
886#undef INITBUFSIZE
Tim Peters142297a2001-01-15 10:36:56 +0000887#undef MAXBUFSIZE
Tim Peters86821b22001-01-07 21:19:34 +0000888#undef INCBUFSIZE
889}
Tim Petersf29b64d2001-01-15 06:33:19 +0000890#endif /* ifdef USE_FGETS_IN_GETLINE */
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000891
Guido van Rossum0bd24411991-04-04 15:21:57 +0000892/* Internal routine to get a line.
893 Size argument interpretation:
894 > 0: max length;
Guido van Rossum86282062001-01-08 01:26:47 +0000895 <= 0: read arbitrary line
Guido van Rossumce5ba841991-03-06 13:06:18 +0000896*/
897
Guido van Rossum1187aa42001-01-05 14:43:05 +0000898#ifdef HAVE_GETC_UNLOCKED
899#define GETC(f) getc_unlocked(f)
900#define FLOCKFILE(f) flockfile(f)
901#define FUNLOCKFILE(f) funlockfile(f)
902#else
903#define GETC(f) getc(f)
904#define FLOCKFILE(f)
905#define FUNLOCKFILE(f)
906#endif
907
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000909get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000910{
Guido van Rossum1187aa42001-01-05 14:43:05 +0000911 FILE *fp = f->f_fp;
912 int c;
Andrew M. Kuchling4b2b4452000-11-29 02:53:22 +0000913 char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000914 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000915 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000916
Tim Petersf29b64d2001-01-15 06:33:19 +0000917#ifdef USE_FGETS_IN_GETLINE
Guido van Rossum86282062001-01-08 01:26:47 +0000918 if (n <= 0)
Tim Petersf29b64d2001-01-15 06:33:19 +0000919 return getline_via_fgets(fp);
Tim Peters86821b22001-01-07 21:19:34 +0000920#endif
Guido van Rossum0bd24411991-04-04 15:21:57 +0000921 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000922 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000923 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000924 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000925 buf = BUF(v);
926 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000927
Guido van Rossumce5ba841991-03-06 13:06:18 +0000928 for (;;) {
Guido van Rossum1187aa42001-01-05 14:43:05 +0000929 Py_BEGIN_ALLOW_THREADS
930 FLOCKFILE(fp);
931 while ((c = GETC(fp)) != EOF &&
932 (*buf++ = c) != '\n' &&
933 buf != end)
934 ;
935 FUNLOCKFILE(fp);
936 Py_END_ALLOW_THREADS
937 if (c == '\n')
938 break;
939 if (c == EOF) {
Guido van Rossum29206bc2001-08-09 18:14:59 +0000940 if (ferror(fp)) {
941 PyErr_SetFromErrno(PyExc_IOError);
942 clearerr(fp);
943 Py_DECREF(v);
944 return NULL;
945 }
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000946 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000947 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000948 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000949 return NULL;
950 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000951 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000952 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000953 /* Must be because buf == end */
954 if (n > 0)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000955 break;
Guido van Rossum1187aa42001-01-05 14:43:05 +0000956 n1 = n2;
957 n2 += 1000;
958 if (n2 > INT_MAX) {
959 PyErr_SetString(PyExc_OverflowError,
960 "line is longer than a Python string can hold");
Tim Peters86821b22001-01-07 21:19:34 +0000961 Py_DECREF(v);
Guido van Rossum1187aa42001-01-05 14:43:05 +0000962 return NULL;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000963 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000964 if (_PyString_Resize(&v, n2) < 0)
965 return NULL;
966 buf = BUF(v) + n1;
967 end = BUF(v) + n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000968 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000969
Guido van Rossumce5ba841991-03-06 13:06:18 +0000970 n1 = buf - BUF(v);
971 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000972 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000973 return v;
974}
975
Guido van Rossum0bd24411991-04-04 15:21:57 +0000976/* External C interface */
977
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000978PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000979PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000980{
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000981 PyObject *result;
982
Guido van Rossum3165fe61992-09-25 21:59:05 +0000983 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000984 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000985 return NULL;
986 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000987
988 if (PyFile_Check(f)) {
989 if (((PyFileObject*)f)->f_fp == NULL)
990 return err_closed();
991 result = get_line((PyFileObject *)f, n);
992 }
993 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000994 PyObject *reader;
995 PyObject *args;
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000996
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000997 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000998 if (reader == NULL)
999 return NULL;
1000 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001001 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001002 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001003 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001004 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001005 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001006 return NULL;
1007 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001008 result = PyEval_CallObject(reader, args);
1009 Py_DECREF(reader);
1010 Py_DECREF(args);
1011 if (result != NULL && !PyString_Check(result)) {
1012 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001013 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001014 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +00001015 "object.readline() returned non-string");
1016 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +00001017 }
1018
1019 if (n < 0 && result != NULL && PyString_Check(result)) {
1020 char *s = PyString_AS_STRING(result);
1021 int len = PyString_GET_SIZE(result);
1022 if (len == 0) {
1023 Py_DECREF(result);
1024 result = NULL;
1025 PyErr_SetString(PyExc_EOFError,
1026 "EOF when reading a line");
1027 }
1028 else if (s[len-1] == '\n') {
1029 if (result->ob_refcnt == 1)
1030 _PyString_Resize(&result, len-1);
1031 else {
1032 PyObject *v;
1033 v = PyString_FromStringAndSize(s, len-1);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001034 Py_DECREF(result);
Guido van Rossum4ddf0a02001-01-07 20:51:39 +00001035 result = v;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001036 }
1037 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001038 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +00001039 return result;
Guido van Rossum0bd24411991-04-04 15:21:57 +00001040}
1041
1042/* Python method */
1043
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001044static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001045file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +00001046{
Guido van Rossum789a1611997-05-10 22:33:55 +00001047 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +00001048
Guido van Rossumd7297e61992-07-06 14:19:26 +00001049 if (f->f_fp == NULL)
1050 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +00001051 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +00001052 return NULL;
1053 if (n == 0)
1054 return PyString_FromString("");
1055 if (n < 0)
1056 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +00001057 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +00001058}
1059
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001060static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001061file_xreadlines(PyFileObject *f)
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001062{
1063 static PyObject* xreadlines_function = NULL;
Tim Petersf29b64d2001-01-15 06:33:19 +00001064
Neal Norwitz649b7592002-01-01 19:07:13 +00001065 if (f->f_fp == NULL)
1066 return err_closed();
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001067 if (!xreadlines_function) {
1068 PyObject *xreadlines_module =
1069 PyImport_ImportModule("xreadlines");
1070 if(!xreadlines_module)
1071 return NULL;
1072
1073 xreadlines_function = PyObject_GetAttrString(xreadlines_module,
1074 "xreadlines");
1075 Py_DECREF(xreadlines_module);
1076 if(!xreadlines_function)
1077 return NULL;
1078 }
1079 return PyObject_CallFunction(xreadlines_function, "(O)", f);
1080}
1081
1082static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001083file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001084{
Guido van Rossum789a1611997-05-10 22:33:55 +00001085 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001086 PyObject *list;
1087 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +00001088 char small_buffer[SMALLCHUNK];
1089 char *buffer = small_buffer;
1090 size_t buffersize = SMALLCHUNK;
1091 PyObject *big_buffer = NULL;
1092 size_t nfilled = 0;
1093 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +00001094 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +00001095 char *p, *q, *end;
1096 int err;
Guido van Rossum79fd0fc2001-10-12 20:01:53 +00001097 int shortread = 0;
Guido van Rossum0bd24411991-04-04 15:21:57 +00001098
Guido van Rossumd7297e61992-07-06 14:19:26 +00001099 if (f->f_fp == NULL)
1100 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +00001101 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +00001102 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001103 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001104 return NULL;
1105 for (;;) {
Guido van Rossum79fd0fc2001-10-12 20:01:53 +00001106 if (shortread)
1107 nread = 0;
1108 else {
1109 Py_BEGIN_ALLOW_THREADS
1110 errno = 0;
1111 nread = fread(buffer+nfilled, 1,
1112 buffersize-nfilled, f->f_fp);
1113 Py_END_ALLOW_THREADS
1114 shortread = (nread < buffersize-nfilled);
1115 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001116 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +00001117 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +00001118 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +00001119 break;
1120 PyErr_SetFromErrno(PyExc_IOError);
1121 clearerr(f->f_fp);
1122 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001123 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +00001124 list = NULL;
1125 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001126 }
Guido van Rossum789a1611997-05-10 22:33:55 +00001127 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +00001128 p = memchr(buffer+nfilled, '\n', nread);
1129 if (p == NULL) {
1130 /* Need a larger buffer to fit this line */
1131 nfilled += nread;
1132 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +00001133 if (buffersize > INT_MAX) {
1134 PyErr_SetString(PyExc_OverflowError,
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001135 "line is longer than a Python string can hold");
Trent Mickf29f47b2000-08-11 19:02:59 +00001136 goto error;
1137 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001138 if (big_buffer == NULL) {
1139 /* Create the big buffer */
1140 big_buffer = PyString_FromStringAndSize(
1141 NULL, buffersize);
1142 if (big_buffer == NULL)
1143 goto error;
1144 buffer = PyString_AS_STRING(big_buffer);
1145 memcpy(buffer, small_buffer, nfilled);
1146 }
1147 else {
1148 /* Grow the big buffer */
1149 _PyString_Resize(&big_buffer, buffersize);
1150 buffer = PyString_AS_STRING(big_buffer);
1151 }
1152 continue;
1153 }
1154 end = buffer+nfilled+nread;
1155 q = buffer;
1156 do {
1157 /* Process complete lines */
1158 p++;
1159 line = PyString_FromStringAndSize(q, p-q);
1160 if (line == NULL)
1161 goto error;
1162 err = PyList_Append(list, line);
1163 Py_DECREF(line);
1164 if (err != 0)
1165 goto error;
1166 q = p;
1167 p = memchr(q, '\n', end-q);
1168 } while (p != NULL);
1169 /* Move the remaining incomplete line to the start */
1170 nfilled = end-q;
1171 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +00001172 if (sizehint > 0)
1173 if (totalread >= (size_t)sizehint)
1174 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001175 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001176 if (nfilled != 0) {
1177 /* Partial last line */
1178 line = PyString_FromStringAndSize(buffer, nfilled);
1179 if (line == NULL)
1180 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +00001181 if (sizehint > 0) {
1182 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +00001183 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +00001184 if (rest == NULL) {
1185 Py_DECREF(line);
1186 goto error;
1187 }
1188 PyString_Concat(&line, rest);
1189 Py_DECREF(rest);
1190 if (line == NULL)
1191 goto error;
1192 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001193 err = PyList_Append(list, line);
1194 Py_DECREF(line);
1195 if (err != 0)
1196 goto error;
1197 }
1198 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001199 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001200 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001201 }
Guido van Rossumce5ba841991-03-06 13:06:18 +00001202 return list;
1203}
1204
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001205static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001206file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001207{
Guido van Rossumd7297e61992-07-06 14:19:26 +00001208 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001209 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001210 if (f->f_fp == NULL)
1211 return err_closed();
Michael W. Hudsone2ec3eb2001-10-31 18:51:01 +00001212 if (!PyArg_ParseTuple(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001214 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001215 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001216 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001217 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001218 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001219 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001220 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +00001221 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001222 return NULL;
1223 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001224 Py_INCREF(Py_None);
1225 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226}
1227
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001228static PyObject *
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001229file_writelines(PyFileObject *f, PyObject *seq)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001230{
Guido van Rossumee70ad12000-03-13 16:27:06 +00001231#define CHUNKSIZE 1000
1232 PyObject *list, *line;
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001233 PyObject *it; /* iter(seq) */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001234 PyObject *result;
1235 int i, j, index, len, nwritten, islist;
1236
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001237 assert(seq != NULL);
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001238 if (f->f_fp == NULL)
1239 return err_closed();
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001240
1241 result = NULL;
1242 list = NULL;
1243 islist = PyList_Check(seq);
1244 if (islist)
1245 it = NULL;
1246 else {
1247 it = PyObject_GetIter(seq);
1248 if (it == NULL) {
1249 PyErr_SetString(PyExc_TypeError,
1250 "writelines() requires an iterable argument");
1251 return NULL;
1252 }
1253 /* From here on, fail by going to error, to reclaim "it". */
1254 list = PyList_New(CHUNKSIZE);
1255 if (list == NULL)
1256 goto error;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001257 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001258
1259 /* Strategy: slurp CHUNKSIZE lines into a private list,
1260 checking that they are all strings, then write that list
1261 without holding the interpreter lock, then come back for more. */
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001262 for (index = 0; ; index += CHUNKSIZE) {
Guido van Rossumee70ad12000-03-13 16:27:06 +00001263 if (islist) {
1264 Py_XDECREF(list);
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001265 list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001266 if (list == NULL)
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001267 goto error;
Guido van Rossumee70ad12000-03-13 16:27:06 +00001268 j = PyList_GET_SIZE(list);
1269 }
1270 else {
1271 for (j = 0; j < CHUNKSIZE; j++) {
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001272 line = PyIter_Next(it);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001273 if (line == NULL) {
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001274 if (PyErr_Occurred())
1275 goto error;
1276 break;
Guido van Rossumee70ad12000-03-13 16:27:06 +00001277 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001278 PyList_SetItem(list, j, line);
1279 }
1280 }
1281 if (j == 0)
1282 break;
1283
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001284 /* Check that all entries are indeed strings. If not,
1285 apply the same rules as for file.write() and
1286 convert the results to strings. This is slow, but
1287 seems to be the only way since all conversion APIs
1288 could potentially execute Python code. */
1289 for (i = 0; i < j; i++) {
1290 PyObject *v = PyList_GET_ITEM(list, i);
1291 if (!PyString_Check(v)) {
1292 const char *buffer;
1293 int len;
Tim Peters86821b22001-01-07 21:19:34 +00001294 if (((f->f_binary &&
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001295 PyObject_AsReadBuffer(v,
1296 (const void**)&buffer,
1297 &len)) ||
1298 PyObject_AsCharBuffer(v,
1299 &buffer,
1300 &len))) {
1301 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001302 "writelines() argument must be a sequence of strings");
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001303 goto error;
1304 }
1305 line = PyString_FromStringAndSize(buffer,
1306 len);
1307 if (line == NULL)
1308 goto error;
1309 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001310 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001311 }
1312 }
1313
1314 /* Since we are releasing the global lock, the
1315 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001316 Py_BEGIN_ALLOW_THREADS
1317 f->f_softspace = 0;
1318 errno = 0;
1319 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001320 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001321 len = PyString_GET_SIZE(line);
1322 nwritten = fwrite(PyString_AS_STRING(line),
1323 1, len, f->f_fp);
1324 if (nwritten != len) {
1325 Py_BLOCK_THREADS
1326 PyErr_SetFromErrno(PyExc_IOError);
1327 clearerr(f->f_fp);
1328 goto error;
1329 }
1330 }
1331 Py_END_ALLOW_THREADS
1332
1333 if (j < CHUNKSIZE)
1334 break;
Guido van Rossumee70ad12000-03-13 16:27:06 +00001335 }
1336
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001337 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001338 result = Py_None;
1339 error:
1340 Py_XDECREF(list);
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001341 Py_XDECREF(it);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001342 return result;
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001343#undef CHUNKSIZE
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001344}
1345
Tim Petersefc3a3a2001-09-20 07:55:22 +00001346static char readline_doc[] =
1347"readline([size]) -> next line from the file, as a string.\n"
1348"\n"
1349"Retain newline. A non-negative size argument limits the maximum\n"
1350"number of bytes to return (an incomplete line may be returned then).\n"
1351"Return an empty string at EOF.";
1352
1353static char read_doc[] =
1354"read([size]) -> read at most size bytes, returned as a string.\n"
1355"\n"
1356"If the size argument is negative or omitted, read until EOF is reached.";
1357
1358static char write_doc[] =
1359"write(str) -> None. Write string str to file.\n"
1360"\n"
1361"Note that due to buffering, flush() or close() may be needed before\n"
1362"the file on disk reflects the data written.";
1363
1364static char fileno_doc[] =
1365"fileno() -> integer \"file descriptor\".\n"
1366"\n"
1367"This is needed for lower-level file interfaces, such os.read().";
1368
1369static char seek_doc[] =
1370"seek(offset[, whence]) -> None. Move to new file position.\n"
1371"\n"
1372"Argument offset is a byte count. Optional argument whence defaults to\n"
1373"0 (offset from start of file, offset should be >= 0); other values are 1\n"
1374"(move relative to current position, positive or negative), and 2 (move\n"
1375"relative to end of file, usually negative, although many platforms allow\n"
1376"seeking beyond the end of a file).\n"
1377"\n"
1378"Note that not all file objects are seekable.";
1379
Guido van Rossumd7047b31995-01-02 19:07:15 +00001380#ifdef HAVE_FTRUNCATE
Tim Petersefc3a3a2001-09-20 07:55:22 +00001381static char truncate_doc[] =
1382"truncate([size]) -> None. Truncate the file to at most size bytes.\n"
1383"\n"
1384"Size defaults to the current file position, as returned by tell().";
Guido van Rossumd7047b31995-01-02 19:07:15 +00001385#endif
Tim Petersefc3a3a2001-09-20 07:55:22 +00001386
1387static char tell_doc[] =
1388"tell() -> current file position, an integer (may be a long integer).";
1389
1390static char readinto_doc[] =
1391"readinto() -> Undocumented. Don't use this; it may go away.";
1392
1393static char readlines_doc[] =
1394"readlines([size]) -> list of strings, each a line from the file.\n"
1395"\n"
1396"Call readline() repeatedly and return a list of the lines so read.\n"
1397"The optional size argument, if given, is an approximate bound on the\n"
1398"total number of bytes in the lines returned.";
1399
1400static char xreadlines_doc[] =
1401"xreadlines() -> next line from the file, as a string.\n"
1402"\n"
1403"Equivalent to xreadlines.xreadlines(file). This is like readline(), but\n"
1404"often quicker, due to reading ahead internally.";
1405
1406static char writelines_doc[] =
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001407"writelines(sequence_of_strings) -> None. Write the strings to the file.\n"
Tim Petersefc3a3a2001-09-20 07:55:22 +00001408"\n"
Tim Peters2c9aa5e2001-09-23 04:06:05 +00001409"Note that newlines are not added. The sequence can be any iterable object\n"
1410"producing strings. This is equivalent to calling write() for each string.";
Tim Petersefc3a3a2001-09-20 07:55:22 +00001411
1412static char flush_doc[] =
1413"flush() -> None. Flush the internal I/O buffer.";
1414
1415static char close_doc[] =
1416"close() -> None or (perhaps) an integer. Close the file.\n"
1417"\n"
1418"Sets data attribute .closed to true. A closed file cannot be used for\n"
1419"further I/O operations. close() may be called more than once without\n"
1420"error. Some kinds of file objects (for example, opened by popen())\n"
1421"may return an exit status upon closing.";
1422
1423static char isatty_doc[] =
1424"isatty() -> true or false. True if the file is connected to a tty device.";
1425
1426static PyMethodDef file_methods[] = {
1427 {"readline", (PyCFunction)file_readline, METH_VARARGS, readline_doc},
1428 {"read", (PyCFunction)file_read, METH_VARARGS, read_doc},
Michael W. Hudsone2ec3eb2001-10-31 18:51:01 +00001429 {"write", (PyCFunction)file_write, METH_VARARGS, write_doc},
Tim Petersefc3a3a2001-09-20 07:55:22 +00001430 {"fileno", (PyCFunction)file_fileno, METH_NOARGS, fileno_doc},
1431 {"seek", (PyCFunction)file_seek, METH_VARARGS, seek_doc},
1432#ifdef HAVE_FTRUNCATE
1433 {"truncate", (PyCFunction)file_truncate, METH_VARARGS, truncate_doc},
1434#endif
1435 {"tell", (PyCFunction)file_tell, METH_NOARGS, tell_doc},
1436 {"readinto", (PyCFunction)file_readinto, METH_OLDARGS, readinto_doc},
1437 {"readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc},
1438 {"xreadlines", (PyCFunction)file_xreadlines, METH_NOARGS, xreadlines_doc},
1439 {"writelines", (PyCFunction)file_writelines, METH_O, writelines_doc},
1440 {"flush", (PyCFunction)file_flush, METH_NOARGS, flush_doc},
1441 {"close", (PyCFunction)file_close, METH_NOARGS, close_doc},
1442 {"isatty", (PyCFunction)file_isatty, METH_NOARGS, isatty_doc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001443 {NULL, NULL} /* sentinel */
1444};
1445
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001446#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001447
Guido van Rossum6f799372001-09-20 20:46:19 +00001448static PyMemberDef file_memberlist[] = {
1449 {"softspace", T_INT, OFF(f_softspace), 0,
1450 "flag indicating that a space needs to be printed; used by print"},
1451 {"mode", T_OBJECT, OFF(f_mode), RO,
1452 "file mode ('r', 'w', 'a', possibly with 'b' or '+' added)"},
1453 {"name", T_OBJECT, OFF(f_name), RO,
1454 "file name"},
Guido van Rossumb6775db1994-08-01 11:34:53 +00001455 /* getattr(f, "closed") is implemented without this table */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001456 {NULL} /* Sentinel */
1457};
1458
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001459static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00001460get_closed(PyFileObject *f, void *closure)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001461{
Tim Peters6d6c1a32001-08-02 04:15:00 +00001462 return PyInt_FromLong((long)(f->f_fp == 0));
Guido van Rossumb6775db1994-08-01 11:34:53 +00001463}
1464
Guido van Rossum32d34c82001-09-20 21:45:26 +00001465static PyGetSetDef file_getsetlist[] = {
1466 {"closed", (getter)get_closed, NULL, "flag set if the file is closed"},
Tim Peters6d6c1a32001-08-02 04:15:00 +00001467 {0},
1468};
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001469
Guido van Rossum65967252001-04-21 13:20:18 +00001470static PyObject *
Guido van Rossum5b021842001-05-22 16:48:37 +00001471file_getiter(PyObject *f)
Guido van Rossum65967252001-04-21 13:20:18 +00001472{
Guido van Rossum5b021842001-05-22 16:48:37 +00001473 return PyObject_CallMethod(f, "xreadlines", "");
Guido van Rossum65967252001-04-21 13:20:18 +00001474}
1475
Tim Peters59c9a642001-09-13 05:38:56 +00001476static PyObject *
1477file_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1478{
Tim Peters44410012001-09-14 03:26:08 +00001479 PyObject *self;
1480 static PyObject *not_yet_string;
1481
1482 assert(type != NULL && type->tp_alloc != NULL);
1483
1484 if (not_yet_string == NULL) {
1485 not_yet_string = PyString_FromString("<uninitialized file>");
1486 if (not_yet_string == NULL)
1487 return NULL;
1488 }
1489
1490 self = type->tp_alloc(type, 0);
1491 if (self != NULL) {
1492 /* Always fill in the name and mode, so that nobody else
1493 needs to special-case NULLs there. */
1494 Py_INCREF(not_yet_string);
1495 ((PyFileObject *)self)->f_name = not_yet_string;
1496 Py_INCREF(not_yet_string);
1497 ((PyFileObject *)self)->f_mode = not_yet_string;
1498 }
1499 return self;
1500}
1501
1502static int
1503file_init(PyObject *self, PyObject *args, PyObject *kwds)
1504{
1505 PyFileObject *foself = (PyFileObject *)self;
1506 int ret = 0;
Tim Peters59c9a642001-09-13 05:38:56 +00001507 static char *kwlist[] = {"name", "mode", "buffering", 0};
1508 char *name = NULL;
1509 char *mode = "r";
1510 int bufsize = -1;
Tim Peters44410012001-09-14 03:26:08 +00001511
1512 assert(PyFile_Check(self));
1513 if (foself->f_fp != NULL) {
1514 /* Have to close the existing file first. */
1515 PyObject *closeresult = file_close(foself);
1516 if (closeresult == NULL)
1517 return -1;
1518 Py_DECREF(closeresult);
1519 }
Tim Peters59c9a642001-09-13 05:38:56 +00001520
1521 if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist,
1522 Py_FileSystemDefaultEncoding, &name,
1523 &mode, &bufsize))
Tim Peters44410012001-09-14 03:26:08 +00001524 return -1;
1525 if (fill_file_fields(foself, NULL, name, mode, fclose) == NULL)
1526 goto Error;
1527 if (open_the_file(foself, name, mode) == NULL)
1528 goto Error;
1529 PyFile_SetBufSize(self, bufsize);
1530 goto Done;
1531
1532Error:
1533 ret = -1;
1534 /* fall through */
1535Done:
Tim Peters59c9a642001-09-13 05:38:56 +00001536 PyMem_Free(name); /* free the encoded string */
Tim Peters44410012001-09-14 03:26:08 +00001537 return ret;
Tim Peters59c9a642001-09-13 05:38:56 +00001538}
1539
Tim Peters59c9a642001-09-13 05:38:56 +00001540static char file_doc[] =
1541"file(name[, mode[, buffering]]) -> file object\n"
1542"\n"
1543"Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n"
1544"writing or appending. The file will be created if it doesn't exist\n"
1545"when opened for writing or appending; it will be truncated when\n"
1546"opened for writing. Add a 'b' to the mode for binary files.\n"
1547"Add a '+' to the mode to allow simultaneous reading and writing.\n"
1548"If the buffering argument is given, 0 means unbuffered, 1 means line\n"
Tim Peters742dfd62001-09-13 21:49:44 +00001549"buffered, and larger numbers specify the buffer size.\n"
1550"Note: open() is an alias for file().\n";
Tim Peters59c9a642001-09-13 05:38:56 +00001551
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001552PyTypeObject PyFile_Type = {
1553 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001554 0,
1555 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001556 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001557 0,
Guido van Rossum65967252001-04-21 13:20:18 +00001558 (destructor)file_dealloc, /* tp_dealloc */
1559 0, /* tp_print */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001560 0, /* tp_getattr */
1561 0, /* tp_setattr */
Guido van Rossum65967252001-04-21 13:20:18 +00001562 0, /* tp_compare */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001563 (reprfunc)file_repr, /* tp_repr */
Guido van Rossum65967252001-04-21 13:20:18 +00001564 0, /* tp_as_number */
1565 0, /* tp_as_sequence */
1566 0, /* tp_as_mapping */
1567 0, /* tp_hash */
1568 0, /* tp_call */
1569 0, /* tp_str */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001570 PyObject_GenericGetAttr, /* tp_getattro */
Guido van Rossum65967252001-04-21 13:20:18 +00001571 0, /* tp_setattro */
1572 0, /* tp_as_buffer */
Guido van Rossum9475a232001-10-05 20:51:39 +00001573 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters59c9a642001-09-13 05:38:56 +00001574 file_doc, /* tp_doc */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001575 0, /* tp_traverse */
1576 0, /* tp_clear */
Guido van Rossum65967252001-04-21 13:20:18 +00001577 0, /* tp_richcompare */
1578 0, /* tp_weaklistoffset */
Guido van Rossum5b021842001-05-22 16:48:37 +00001579 file_getiter, /* tp_iter */
Guido van Rossum213c7a62001-04-23 14:08:49 +00001580 0, /* tp_iternext */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001581 file_methods, /* tp_methods */
1582 file_memberlist, /* tp_members */
1583 file_getsetlist, /* tp_getset */
1584 0, /* tp_base */
1585 0, /* tp_dict */
Tim Peters59c9a642001-09-13 05:38:56 +00001586 0, /* tp_descr_get */
1587 0, /* tp_descr_set */
1588 0, /* tp_dictoffset */
Tim Peters44410012001-09-14 03:26:08 +00001589 (initproc)file_init, /* tp_init */
1590 PyType_GenericAlloc, /* tp_alloc */
Tim Peters59c9a642001-09-13 05:38:56 +00001591 file_new, /* tp_new */
Guido van Rossum9475a232001-10-05 20:51:39 +00001592 _PyObject_Del, /* tp_free */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001593};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001594
1595/* Interface for the 'soft space' between print items. */
1596
1597int
Fred Drakefd99de62000-07-09 05:02:18 +00001598PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001599{
1600 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001601 if (f == NULL) {
1602 /* Do nothing */
1603 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001604 else if (PyFile_Check(f)) {
1605 oldflag = ((PyFileObject *)f)->f_softspace;
1606 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001607 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001608 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001609 PyObject *v;
1610 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001611 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001612 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001613 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001614 if (PyInt_Check(v))
1615 oldflag = PyInt_AsLong(v);
1616 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001617 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001618 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001619 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001620 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001621 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001622 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1623 PyErr_Clear();
1624 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001625 }
1626 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001627 return oldflag;
1628}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001629
1630/* Interfaces to write objects/strings to file-like objects */
1631
1632int
Fred Drakefd99de62000-07-09 05:02:18 +00001633PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001634{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001635 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001636 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001637 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001638 return -1;
1639 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001640 else if (PyFile_Check(f)) {
1641 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001642 if (fp == NULL) {
1643 err_closed();
1644 return -1;
1645 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001646 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001647 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001648 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001649 if (writer == NULL)
1650 return -1;
Martin v. Löwis2777c022001-09-19 13:47:32 +00001651 if (flags & Py_PRINT_RAW) {
1652 if (PyUnicode_Check(v)) {
1653 value = v;
1654 Py_INCREF(value);
1655 } else
1656 value = PyObject_Str(v);
1657 }
1658 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001659 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001660 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001661 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001662 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001663 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001664 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001665 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001666 Py_DECREF(value);
1667 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001668 return -1;
1669 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001670 result = PyEval_CallObject(writer, args);
1671 Py_DECREF(args);
1672 Py_DECREF(value);
1673 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001674 if (result == NULL)
1675 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001676 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001677 return 0;
1678}
1679
Guido van Rossum27a60b11997-05-22 22:25:11 +00001680int
Tim Petersc1bbcb82001-11-28 22:13:25 +00001681PyFile_WriteString(const char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001682{
1683 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001684 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001685 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001686 PyErr_SetString(PyExc_SystemError,
1687 "null file for PyFile_WriteString");
1688 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001689 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001690 else if (PyFile_Check(f)) {
1691 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001692 if (fp == NULL) {
1693 err_closed();
1694 return -1;
1695 }
1696 fputs(s, fp);
1697 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001698 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001699 else if (!PyErr_Occurred()) {
1700 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001701 int err;
1702 if (v == NULL)
1703 return -1;
1704 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1705 Py_DECREF(v);
1706 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001707 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001708 else
1709 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001710}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001711
1712/* Try to get a file-descriptor from a Python object. If the object
1713 is an integer or long integer, its value is returned. If not, the
1714 object's fileno() method is called if it exists; the method must return
1715 an integer or long integer, which is returned as the file descriptor value.
1716 -1 is returned on failure.
1717*/
1718
1719int PyObject_AsFileDescriptor(PyObject *o)
1720{
1721 int fd;
1722 PyObject *meth;
1723
1724 if (PyInt_Check(o)) {
1725 fd = PyInt_AsLong(o);
1726 }
1727 else if (PyLong_Check(o)) {
1728 fd = PyLong_AsLong(o);
1729 }
1730 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1731 {
1732 PyObject *fno = PyEval_CallObject(meth, NULL);
1733 Py_DECREF(meth);
1734 if (fno == NULL)
1735 return -1;
Tim Peters86821b22001-01-07 21:19:34 +00001736
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001737 if (PyInt_Check(fno)) {
1738 fd = PyInt_AsLong(fno);
1739 Py_DECREF(fno);
1740 }
1741 else if (PyLong_Check(fno)) {
1742 fd = PyLong_AsLong(fno);
1743 Py_DECREF(fno);
1744 }
1745 else {
1746 PyErr_SetString(PyExc_TypeError,
1747 "fileno() returned a non-integer");
1748 Py_DECREF(fno);
1749 return -1;
1750 }
1751 }
1752 else {
1753 PyErr_SetString(PyExc_TypeError,
1754 "argument must be an int, or have a fileno() method.");
1755 return -1;
1756 }
1757
1758 if (fd < 0) {
1759 PyErr_Format(PyExc_ValueError,
1760 "file descriptor cannot be a negative integer (%i)",
1761 fd);
1762 return -1;
1763 }
1764 return fd;
1765}