blob: 385d1881ffb1404822919c64cce9757b6e6f2c0d [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 Rossumeceebb82000-06-28 20:57:07 +000011/* We expect that fstat exists on most systems.
12 It's confirmed on Unix, Mac and Windows.
13 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
14#ifndef DONT_HAVE_FSTAT
15#define HAVE_FSTAT
16
17#ifndef DONT_HAVE_SYS_TYPES_H
18#include <sys/types.h>
19#endif
20
21#ifndef DONT_HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#else
24#ifdef HAVE_STAT_H
25#include <stat.h>
26#endif
27#endif
28
29#endif /* DONT_HAVE_FSTAT */
30
Guido van Rossum685a38e1996-12-05 21:54:17 +000031#ifdef HAVE_UNISTD_H
32#include <unistd.h>
33#endif
34
Guido van Rossumb8199141997-05-06 15:23:24 +000035#ifdef MS_WIN32
Guido van Rossumb8199141997-05-06 15:23:24 +000036#define fileno _fileno
Trent Mickf29f47b2000-08-11 19:02:59 +000037/* can (almost fully) duplicate with _chsize, see file_truncate */
Guido van Rossumb8199141997-05-06 15:23:24 +000038#define HAVE_FTRUNCATE
39#endif
40
Guido van Rossumf2044e11998-04-28 16:05:59 +000041#ifdef macintosh
42#ifdef USE_GUSI
43#define HAVE_FTRUNCATE
44#endif
45#endif
46
Jack Jansene08dea191995-04-23 22:12:47 +000047#ifdef __MWERKS__
48/* Mwerks fopen() doesn't always set errno */
49#define NO_FOPEN_ERRNO
50#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000051
Guido van Rossumc0b618a1997-05-02 03:12:38 +000052#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000053
Guido van Rossumff7e83d1999-08-27 20:39:37 +000054#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000055#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000056#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057
Trent Mickf29f47b2000-08-11 19:02:59 +000058
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000060 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000062 PyObject *f_name;
63 PyObject *f_mode;
Tim Petersdbd9ba62000-07-09 03:09:57 +000064 int (*f_close)(FILE *);
Guido van Rossumeb183da1991-04-04 10:44:06 +000065 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000066 int f_binary; /* Flag which indicates whether the file is open
67 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000068} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069
70FILE *
Fred Drakefd99de62000-07-09 05:02:18 +000071PyFile_AsFile(PyObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000072{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000073 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000075 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000076 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077}
78
Guido van Rossumc0b618a1997-05-02 03:12:38 +000079PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000080PyFile_Name(PyObject *f)
Guido van Rossumdb3165e1993-10-18 17:06:59 +000081{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000083 return NULL;
84 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000085 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000086}
87
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000089PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 if (f == NULL)
93 return NULL;
94 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000095 f->f_name = PyString_FromString(name);
96 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000097 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000098 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +000099 if (strchr(mode,'b') != NULL)
100 f->f_binary = 1;
101 else
102 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000104 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105 return NULL;
106 }
107 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000108 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109}
110
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000111PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000112PyFile_FromString(char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113{
Tim Petersdbd9ba62000-07-09 03:09:57 +0000114 extern int fclose(FILE *);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115 PyFileObject *f;
116 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117 if (f == NULL)
118 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000119#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000120 if (*mode == '*') {
121 FILE *fopenRF();
122 f->f_fp = fopenRF(name, mode+1);
123 }
124 else
125#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000126 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000127 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000128 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000129 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000130 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000131 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000132#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000133 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000134 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000135 PyErr_SetString(PyExc_IOError, "Cannot open file");
136 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000137 return NULL;
138 }
139#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000140 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000141 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000142 return NULL;
143 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000144 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145}
146
Guido van Rossumb6775db1994-08-01 11:34:53 +0000147void
Fred Drakefd99de62000-07-09 05:02:18 +0000148PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000149{
150 if (bufsize >= 0) {
151#ifdef HAVE_SETVBUF
152 int type;
153 switch (bufsize) {
154 case 0:
155 type = _IONBF;
156 break;
157 case 1:
158 type = _IOLBF;
159 bufsize = BUFSIZ;
160 break;
161 default:
162 type = _IOFBF;
163 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000164 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
165 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000166#else /* !HAVE_SETVBUF */
167 if (bufsize <= 1)
168 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
169#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000170 }
171}
172
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000173static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000174err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000175{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000176 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000177 return NULL;
178}
179
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180/* Methods */
181
182static void
Fred Drakefd99de62000-07-09 05:02:18 +0000183file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000185 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000186 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000187 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000188 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000189 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000190 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000191 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000192 }
193 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000194 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000195 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000196 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197}
198
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000199static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000200file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201{
202 char buf[300];
Fred Drakea44d3532000-06-30 15:01:00 +0000203 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205 PyString_AsString(f->f_name),
206 PyString_AsString(f->f_mode),
Fred Drakea44d3532000-06-30 15:01:00 +0000207 f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000208 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209}
210
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000211static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000212file_close(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000214 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000215 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000218 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000219 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000220 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000221 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000222 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000223 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000224 f->f_fp = NULL;
225 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000226 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000227 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000228 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000229 return PyInt_FromLong((long)sts);
230 Py_INCREF(Py_None);
231 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232}
233
Trent Mickf29f47b2000-08-11 19:02:59 +0000234
235/* a portable fseek() function
236 return 0 on success, non-zero on failure (with errno set) */
237int
Tim Peters86821b22001-01-07 21:19:34 +0000238#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Fred Drake8ce159a2000-08-31 05:18:54 +0000239_portable_fseek(FILE *fp, fpos_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000240#else
Fred Drake8ce159a2000-08-31 05:18:54 +0000241_portable_fseek(FILE *fp, off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000242#endif
Trent Mickf29f47b2000-08-11 19:02:59 +0000243{
244#if defined(HAVE_FSEEKO)
245 return fseeko(fp, offset, whence);
246#elif defined(HAVE_FSEEK64)
247 return fseek64(fp, offset, whence);
Fred Drakedb810ac2000-10-06 20:42:33 +0000248#elif defined(__BEOS__)
249 return _fseek(fp, offset, whence);
Tim Peters86821b22001-01-07 21:19:34 +0000250#elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
Guido van Rossume54e0be2001-01-16 20:53:31 +0000251 /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
252 and fgetpos() to implement fseek()*/
Trent Mickf29f47b2000-08-11 19:02:59 +0000253 fpos_t pos;
254 switch (whence) {
Guido van Rossume54e0be2001-01-16 20:53:31 +0000255 case SEEK_END:
256 if (fseek(fp, 0, SEEK_END) != 0)
257 return -1;
258 /* fall through */
259 case SEEK_CUR:
260 if (fgetpos(fp, &pos) != 0)
261 return -1;
262 offset += pos;
263 break;
264 /* case SEEK_SET: break; */
Trent Mickf29f47b2000-08-11 19:02:59 +0000265 }
266 return fsetpos(fp, &offset);
267#else
268 return fseek(fp, offset, whence);
269#endif
270}
271
272
273/* a portable ftell() function
274 Return -1 on failure with errno set appropriately, current file
275 position on success */
Tim Peters86821b22001-01-07 21:19:34 +0000276#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000277fpos_t
278#else
279off_t
280#endif
Fred Drake8ce159a2000-08-31 05:18:54 +0000281_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000282{
283#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
284 return ftello(fp);
285#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
286 return ftell64(fp);
287#elif SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT)
288 fpos_t pos;
289 if (fgetpos(fp, &pos) != 0)
290 return -1;
291 return pos;
292#else
293 return ftell(fp);
294#endif
295}
296
297
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000298static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000299file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000301 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000302 int ret;
Tim Peters86821b22001-01-07 21:19:34 +0000303#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000304 fpos_t offset, pos;
305#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000306 off_t offset;
Trent Mickf29f47b2000-08-11 19:02:59 +0000307#endif /* !MS_WIN64 */
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000308 PyObject *offobj;
Tim Peters86821b22001-01-07 21:19:34 +0000309
Guido van Rossumd7297e61992-07-06 14:19:26 +0000310 if (f->f_fp == NULL)
311 return err_closed();
312 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000313 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000314 return NULL;
315#if !defined(HAVE_LARGEFILE_SUPPORT)
316 offset = PyInt_AsLong(offobj);
317#else
318 offset = PyLong_Check(offobj) ?
319 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
320#endif
321 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000322 return NULL;
Tim Peters86821b22001-01-07 21:19:34 +0000323
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000324 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000325 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000326 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000327 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000328
Guido van Rossumff4949e1992-08-05 19:58:53 +0000329 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000330 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000331 clearerr(f->f_fp);
332 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000333 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000334 Py_INCREF(Py_None);
335 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000336}
337
Trent Mickf29f47b2000-08-11 19:02:59 +0000338
Guido van Rossumd7047b31995-01-02 19:07:15 +0000339#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000341file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000342{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000343 int ret;
Tim Peters86821b22001-01-07 21:19:34 +0000344#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000345 fpos_t newsize;
346#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000347 off_t newsize;
Trent Mickf29f47b2000-08-11 19:02:59 +0000348#endif
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000349 PyObject *newsizeobj;
Tim Peters86821b22001-01-07 21:19:34 +0000350
Guido van Rossumd7047b31995-01-02 19:07:15 +0000351 if (f->f_fp == NULL)
352 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000353 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000354 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000355 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000356 if (newsizeobj != NULL) {
357#if !defined(HAVE_LARGEFILE_SUPPORT)
358 newsize = PyInt_AsLong(newsizeobj);
359#else
360 newsize = PyLong_Check(newsizeobj) ?
361 PyLong_AsLongLong(newsizeobj) :
362 PyInt_AsLong(newsizeobj);
363#endif
364 if (PyErr_Occurred())
365 return NULL;
366 } else {
367 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000368 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000369 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000370 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000371 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000372 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000374 clearerr(f->f_fp);
375 return NULL;
376 }
377 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000378 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000379 errno = 0;
380 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000381 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000382 if (ret != 0) goto onioerror;
383
384#ifdef MS_WIN32
385 /* can use _chsize; if, however, the newsize overflows 32-bits then
386 _chsize is *not* adequate; in this case, an OverflowError is raised */
387 if (newsize > LONG_MAX) {
388 PyErr_SetString(PyExc_OverflowError,
389 "the new size is too long for _chsize (it is limited to 32-bit values)");
Guido van Rossumd7047b31995-01-02 19:07:15 +0000390 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000391 } else {
392 Py_BEGIN_ALLOW_THREADS
393 errno = 0;
394 ret = _chsize(fileno(f->f_fp), newsize);
395 Py_END_ALLOW_THREADS
396 if (ret != 0) goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000397 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000398#else
399 Py_BEGIN_ALLOW_THREADS
400 errno = 0;
401 ret = ftruncate(fileno(f->f_fp), newsize);
402 Py_END_ALLOW_THREADS
403 if (ret != 0) goto onioerror;
404#endif /* !MS_WIN32 */
Tim Peters86821b22001-01-07 21:19:34 +0000405
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000406 Py_INCREF(Py_None);
407 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000408
409onioerror:
410 PyErr_SetFromErrno(PyExc_IOError);
411 clearerr(f->f_fp);
412 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000413}
414#endif /* HAVE_FTRUNCATE */
415
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000416static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000417file_tell(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000418{
Tim Peters86821b22001-01-07 21:19:34 +0000419#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Trent Mickf29f47b2000-08-11 19:02:59 +0000420 fpos_t pos;
421#else
422 off_t pos;
423#endif
424
Guido van Rossumd7297e61992-07-06 14:19:26 +0000425 if (f->f_fp == NULL)
426 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000427 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000428 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000429 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000430 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000431 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000433 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000435 clearerr(f->f_fp);
436 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000437 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000438#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000439 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000440#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000441 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000442#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000443}
444
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000445static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000446file_fileno(PyFileObject *f, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000447{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000448 if (f->f_fp == NULL)
449 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000450 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000451 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000453}
454
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000455static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000456file_flush(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000457{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000458 int res;
Tim Peters86821b22001-01-07 21:19:34 +0000459
Guido van Rossumd7297e61992-07-06 14:19:26 +0000460 if (f->f_fp == NULL)
461 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000462 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000463 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000464 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000465 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000466 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000467 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000468 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000469 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000470 clearerr(f->f_fp);
471 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000472 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000473 Py_INCREF(Py_None);
474 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000475}
476
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000477static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000478file_isatty(PyFileObject *f, PyObject *args)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000479{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000480 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000481 if (f->f_fp == NULL)
482 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000483 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000484 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000486 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000487 Py_END_ALLOW_THREADS
488 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000489}
490
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000491
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000492#if BUFSIZ < 8192
493#define SMALLCHUNK 8192
494#else
495#define SMALLCHUNK BUFSIZ
496#endif
497
Guido van Rossum3c259041999-01-14 19:00:14 +0000498#if SIZEOF_INT < 4
499#define BIGCHUNK (512 * 32)
500#else
501#define BIGCHUNK (512 * 1024)
502#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000503
504static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000505new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000506{
507#ifdef HAVE_FSTAT
508 long pos, end;
509 struct stat st;
510 if (fstat(fileno(f->f_fp), &st) == 0) {
511 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000512 /* The following is not a bug: we really need to call lseek()
513 *and* ftell(). The reason is that some stdio libraries
514 mistakenly flush their buffer when ftell() is called and
515 the lseek() call it makes fails, thereby throwing away
516 data that cannot be recovered in any way. To avoid this,
517 we first test lseek(), and only call ftell() if lseek()
518 works. We can't use the lseek() value either, because we
519 need to take the amount of buffered data into account.
520 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000521 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
522 if (pos >= 0)
523 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000524 if (pos < 0)
525 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000526 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000527 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000528 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000529 }
530#endif
531 if (currentsize > SMALLCHUNK) {
532 /* Keep doubling until we reach BIGCHUNK;
533 then keep adding BIGCHUNK. */
534 if (currentsize <= BIGCHUNK)
535 return currentsize + currentsize;
536 else
537 return currentsize + BIGCHUNK;
538 }
539 return currentsize + SMALLCHUNK;
540}
541
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000542static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000543file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000544{
Guido van Rossum789a1611997-05-10 22:33:55 +0000545 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000546 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000547 PyObject *v;
Tim Peters86821b22001-01-07 21:19:34 +0000548
Guido van Rossumd7297e61992-07-06 14:19:26 +0000549 if (f->f_fp == NULL)
550 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000551 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000552 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000553 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000554 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000555 else
556 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000557 if (buffersize > INT_MAX) {
558 PyErr_SetString(PyExc_OverflowError,
559 "requested number of bytes is more than a Python string can hold");
560 return NULL;
561 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000562 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000563 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000564 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000565 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000566 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000567 Py_BEGIN_ALLOW_THREADS
568 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000569 chunksize = fread(BUF(v) + bytesread, 1,
570 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000571 Py_END_ALLOW_THREADS
572 if (chunksize == 0) {
573 if (!ferror(f->f_fp))
574 break;
575 PyErr_SetFromErrno(PyExc_IOError);
576 clearerr(f->f_fp);
577 Py_DECREF(v);
578 return NULL;
579 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000580 bytesread += chunksize;
581 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000582 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000583 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000584 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000585 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000586 return NULL;
587 }
588 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000589 if (bytesread != buffersize)
590 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000591 return v;
592}
593
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000594static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000595file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000596{
597 char *ptr;
Trent Mickf29f47b2000-08-11 19:02:59 +0000598 size_t ntodo, ndone, nnow;
Tim Peters86821b22001-01-07 21:19:34 +0000599
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000600 if (f->f_fp == NULL)
601 return err_closed();
602 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
603 return NULL;
604 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000605 while (ntodo > 0) {
606 Py_BEGIN_ALLOW_THREADS
607 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000608 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000609 Py_END_ALLOW_THREADS
610 if (nnow == 0) {
611 if (!ferror(f->f_fp))
612 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000613 PyErr_SetFromErrno(PyExc_IOError);
614 clearerr(f->f_fp);
615 return NULL;
616 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000617 ndone += nnow;
618 ntodo -= nnow;
619 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000620 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000621}
622
Tim Peters86821b22001-01-07 21:19:34 +0000623/**************************************************************************
Tim Petersf29b64d2001-01-15 06:33:19 +0000624Routine to get next line using platform fgets().
Tim Peters86821b22001-01-07 21:19:34 +0000625
626Under MSVC 6:
627
Tim Peters1c733232001-01-08 04:02:07 +0000628+ MS threadsafe getc is very slow (multiple layers of function calls before+
629 after each character, to lock+unlock the stream).
630+ The stream-locking functions are MS-internal -- can't access them from user
631 code.
632+ There's nothing Tim could find in the MS C or platform SDK libraries that
633 can worm around this.
Tim Peters86821b22001-01-07 21:19:34 +0000634+ MS fgets locks/unlocks only once per line; it's the only hook we have.
635
636So we use fgets for speed(!), despite that it's painful.
637
638MS realloc is also slow.
639
Tim Petersf29b64d2001-01-15 06:33:19 +0000640Reports from other platforms on this method vs getc_unlocked (which MS doesn't
641have):
642 Linux a wash
643 Solaris a wash
644 Tru64 Unix getline_via_fgets significantly faster
Tim Peters86821b22001-01-07 21:19:34 +0000645
Tim Petersf29b64d2001-01-15 06:33:19 +0000646CAUTION: The C std isn't clear about this: in those cases where fgets
647writes something into the buffer, can it write into any position beyond the
648required trailing null byte? MSVC 6 fgets does not, and no platform is (yet)
649known on which it does; and it would be a strange way to code fgets. Still,
650getline_via_fgets may not work correctly if it does. The std test
651test_bufio.py should fail if platform fgets() routinely writes beyond the
652trailing null byte. #define DONT_USE_FGETS_IN_GETLINE to disable this code.
Tim Peters86821b22001-01-07 21:19:34 +0000653**************************************************************************/
654
Tim Petersf29b64d2001-01-15 06:33:19 +0000655/* Use this routine if told to, or by default on non-get_unlocked()
656 * platforms unless told not to. Yikes! Let's spell that out:
657 * On a platform with getc_unlocked():
658 * By default, use getc_unlocked().
659 * If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
660 * On a platform without getc_unlocked():
661 * By default, use fgets().
662 * If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
663 */
664#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
665#define USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000666#endif
667
Tim Petersf29b64d2001-01-15 06:33:19 +0000668#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
669#undef USE_FGETS_IN_GETLINE
670#endif
671
672#ifdef USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000673static PyObject*
Tim Petersf29b64d2001-01-15 06:33:19 +0000674getline_via_fgets(FILE *fp)
Tim Peters86821b22001-01-07 21:19:34 +0000675{
Tim Peters15b83852001-01-08 00:53:12 +0000676/* INITBUFSIZE is the maximum line length that lets us get away with the fast
Tim Peters142297a2001-01-15 10:36:56 +0000677 * no-realloc, one-fgets()-call path. Boosting it isn't free, because we have
678 * to fill this much of the buffer with a known value in order to figure out
679 * how much of the buffer fgets() overwrites. So if INITBUFSIZE is larger
680 * than "most" lines, we waste time filling unused buffer slots. 100 is
681 * surely adequate for most peoples' email archives, chewing over source code,
682 * etc -- "regular old text files".
683 * MAXBUFSIZE is the maximum line length that lets us get away with the less
684 * fast (but still zippy) no-realloc, two-fgets()-call path. See above for
685 * cautions about boosting that. 300 was chosen because the worst real-life
686 * text-crunching job reported on Python-Dev was a mail-log crawler where over
687 * half the lines were 254 chars.
688 * INCBUFSIZE is the amount by which we grow the buffer, if MAXBUFSIZE isn't
689 * enough. It doesn't much matter what this is set to: we only get here for
690 * absurdly long lines anyway.
Tim Peters15b83852001-01-08 00:53:12 +0000691 */
Tim Peters142297a2001-01-15 10:36:56 +0000692#define INITBUFSIZE 100
693#define MAXBUFSIZE 300
Tim Peters86821b22001-01-07 21:19:34 +0000694#define INCBUFSIZE 1000
Tim Peters142297a2001-01-15 10:36:56 +0000695 char* p; /* temp */
696 char buf[MAXBUFSIZE];
Tim Peters86821b22001-01-07 21:19:34 +0000697 PyObject* v; /* the string object result */
Tim Peters86821b22001-01-07 21:19:34 +0000698 char* pvfree; /* address of next free slot */
699 char* pvend; /* address one beyond last free slot */
Tim Peters142297a2001-01-15 10:36:56 +0000700 size_t nfree; /* # of free buffer slots; pvend-pvfree */
701 size_t total_v_size; /* total # of slots in buffer */
Tim Peters86821b22001-01-07 21:19:34 +0000702
Tim Peters15b83852001-01-08 00:53:12 +0000703 /* Optimize for normal case: avoid _PyString_Resize if at all
Tim Peters142297a2001-01-15 10:36:56 +0000704 * possible via first reading into stack buffer "buf".
Tim Peters15b83852001-01-08 00:53:12 +0000705 */
Tim Peters142297a2001-01-15 10:36:56 +0000706 total_v_size = INITBUFSIZE; /* start small and pray */
707 pvfree = buf;
708 for (;;) {
709 Py_BEGIN_ALLOW_THREADS
710 pvend = buf + total_v_size;
711 nfree = pvend - pvfree;
712 memset(pvfree, '\n', nfree);
713 p = fgets(pvfree, nfree, fp);
714 Py_END_ALLOW_THREADS
Tim Peters15b83852001-01-08 00:53:12 +0000715
Tim Peters142297a2001-01-15 10:36:56 +0000716 if (p == NULL) {
717 clearerr(fp);
718 if (PyErr_CheckSignals())
719 return NULL;
720 v = PyString_FromStringAndSize(buf, pvfree - buf);
Tim Peters86821b22001-01-07 21:19:34 +0000721 return v;
722 }
Tim Peters142297a2001-01-15 10:36:56 +0000723 /* fgets read *something* */
724 p = memchr(pvfree, '\n', nfree);
725 if (p != NULL) {
726 /* Did the \n come from fgets or from us?
727 * Since fgets stops at the first \n, and then writes
728 * \0, if it's from fgets a \0 must be next. But if
729 * that's so, it could not have come from us, since
730 * the \n's we filled the buffer with have only more
731 * \n's to the right.
732 */
733 if (p+1 < pvend && *(p+1) == '\0') {
734 /* It's from fgets: we win! In particular,
735 * we haven't done any mallocs yet, and can
736 * build the final result on the first try.
737 */
738 ++p; /* include \n from fgets */
739 }
740 else {
741 /* Must be from us: fgets didn't fill the
742 * buffer and didn't find a newline, so it
743 * must be the last and newline-free line of
744 * the file.
745 */
746 assert(p > pvfree && *(p-1) == '\0');
747 --p; /* don't include \0 from fgets */
748 }
749 v = PyString_FromStringAndSize(buf, p - buf);
750 return v;
751 }
752 /* yuck: fgets overwrote all the newlines, i.e. the entire
753 * buffer. So this line isn't over yet, or maybe it is but
754 * we're exactly at EOF. If we haven't already, try using the
755 * rest of the stack buffer.
Tim Peters86821b22001-01-07 21:19:34 +0000756 */
Tim Peters142297a2001-01-15 10:36:56 +0000757 assert(*(pvend-1) == '\0');
758 if (pvfree == buf) {
759 pvfree = pvend - 1; /* overwrite trailing null */
760 total_v_size = MAXBUFSIZE;
761 }
762 else
763 break;
Tim Peters86821b22001-01-07 21:19:34 +0000764 }
Tim Peters142297a2001-01-15 10:36:56 +0000765
766 /* The stack buffer isn't big enough; malloc a string object and read
767 * into its buffer.
Tim Peters15b83852001-01-08 00:53:12 +0000768 */
Tim Peters142297a2001-01-15 10:36:56 +0000769 total_v_size = MAXBUFSIZE + INCBUFSIZE;
Tim Peters1c733232001-01-08 04:02:07 +0000770 v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
Tim Peters15b83852001-01-08 00:53:12 +0000771 if (v == NULL)
772 return v;
773 /* copy over everything except the last null byte */
Tim Peters142297a2001-01-15 10:36:56 +0000774 memcpy(BUF(v), buf, MAXBUFSIZE-1);
775 pvfree = BUF(v) + MAXBUFSIZE - 1;
Tim Peters86821b22001-01-07 21:19:34 +0000776
777 /* Keep reading stuff into v; if it ever ends successfully, break
Tim Peters15b83852001-01-08 00:53:12 +0000778 * after setting p one beyond the end of the line. The code here is
779 * very much like the code above, except reads into v's buffer; see
780 * the code above for detailed comments about the logic.
Tim Peters86821b22001-01-07 21:19:34 +0000781 */
782 for (;;) {
Tim Peters86821b22001-01-07 21:19:34 +0000783 Py_BEGIN_ALLOW_THREADS
784 pvend = BUF(v) + total_v_size;
785 nfree = pvend - pvfree;
786 memset(pvfree, '\n', nfree);
787 p = fgets(pvfree, nfree, fp);
788 Py_END_ALLOW_THREADS
789
790 if (p == NULL) {
791 clearerr(fp);
792 if (PyErr_CheckSignals()) {
793 Py_DECREF(v);
794 return NULL;
795 }
796 p = pvfree;
797 break;
798 }
Tim Peters86821b22001-01-07 21:19:34 +0000799 p = memchr(pvfree, '\n', nfree);
800 if (p != NULL) {
801 if (p+1 < pvend && *(p+1) == '\0') {
802 /* \n came from fgets */
803 ++p;
804 break;
805 }
806 /* \n came from us; last line of file, no newline */
807 assert(p > pvfree && *(p-1) == '\0');
808 --p;
809 break;
810 }
811 /* expand buffer and try again */
812 assert(*(pvend-1) == '\0');
813 total_v_size += INCBUFSIZE;
814 if (total_v_size > INT_MAX) {
815 PyErr_SetString(PyExc_OverflowError,
816 "line is longer than a Python string can hold");
817 Py_DECREF(v);
818 return NULL;
819 }
820 if (_PyString_Resize(&v, (int)total_v_size) < 0)
821 return NULL;
822 /* overwrite the trailing null byte */
823 pvfree = BUF(v) + (total_v_size - INCBUFSIZE - 1);
824 }
825 if (BUF(v) + total_v_size != p)
826 _PyString_Resize(&v, p - BUF(v));
827 return v;
828#undef INITBUFSIZE
Tim Peters142297a2001-01-15 10:36:56 +0000829#undef MAXBUFSIZE
Tim Peters86821b22001-01-07 21:19:34 +0000830#undef INCBUFSIZE
831}
Tim Petersf29b64d2001-01-15 06:33:19 +0000832#endif /* ifdef USE_FGETS_IN_GETLINE */
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000833
Guido van Rossum0bd24411991-04-04 15:21:57 +0000834/* Internal routine to get a line.
835 Size argument interpretation:
836 > 0: max length;
Guido van Rossum86282062001-01-08 01:26:47 +0000837 <= 0: read arbitrary line
Guido van Rossumce5ba841991-03-06 13:06:18 +0000838*/
839
Guido van Rossum1187aa42001-01-05 14:43:05 +0000840#ifdef HAVE_GETC_UNLOCKED
841#define GETC(f) getc_unlocked(f)
842#define FLOCKFILE(f) flockfile(f)
843#define FUNLOCKFILE(f) funlockfile(f)
844#else
845#define GETC(f) getc(f)
846#define FLOCKFILE(f)
847#define FUNLOCKFILE(f)
848#endif
849
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000850static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000851get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000852{
Guido van Rossum1187aa42001-01-05 14:43:05 +0000853 FILE *fp = f->f_fp;
854 int c;
Andrew M. Kuchling4b2b4452000-11-29 02:53:22 +0000855 char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000856 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000857 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000858
Tim Petersf29b64d2001-01-15 06:33:19 +0000859#ifdef USE_FGETS_IN_GETLINE
Guido van Rossum86282062001-01-08 01:26:47 +0000860 if (n <= 0)
Tim Petersf29b64d2001-01-15 06:33:19 +0000861 return getline_via_fgets(fp);
Tim Peters86821b22001-01-07 21:19:34 +0000862#endif
Guido van Rossum0bd24411991-04-04 15:21:57 +0000863 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000864 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000865 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000866 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000867 buf = BUF(v);
868 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000869
Guido van Rossumce5ba841991-03-06 13:06:18 +0000870 for (;;) {
Guido van Rossum1187aa42001-01-05 14:43:05 +0000871 Py_BEGIN_ALLOW_THREADS
872 FLOCKFILE(fp);
873 while ((c = GETC(fp)) != EOF &&
874 (*buf++ = c) != '\n' &&
875 buf != end)
876 ;
877 FUNLOCKFILE(fp);
878 Py_END_ALLOW_THREADS
879 if (c == '\n')
880 break;
881 if (c == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000882 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000883 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000884 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000885 return NULL;
886 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000887 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000888 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000889 /* Must be because buf == end */
890 if (n > 0)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000891 break;
Guido van Rossum1187aa42001-01-05 14:43:05 +0000892 n1 = n2;
893 n2 += 1000;
894 if (n2 > INT_MAX) {
895 PyErr_SetString(PyExc_OverflowError,
896 "line is longer than a Python string can hold");
Tim Peters86821b22001-01-07 21:19:34 +0000897 Py_DECREF(v);
Guido van Rossum1187aa42001-01-05 14:43:05 +0000898 return NULL;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000899 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000900 if (_PyString_Resize(&v, n2) < 0)
901 return NULL;
902 buf = BUF(v) + n1;
903 end = BUF(v) + n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000904 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000905
Guido van Rossumce5ba841991-03-06 13:06:18 +0000906 n1 = buf - BUF(v);
907 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000909 return v;
910}
911
Guido van Rossum0bd24411991-04-04 15:21:57 +0000912/* External C interface */
913
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000914PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000915PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000916{
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000917 PyObject *result;
918
Guido van Rossum3165fe61992-09-25 21:59:05 +0000919 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000920 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000921 return NULL;
922 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000923
924 if (PyFile_Check(f)) {
925 if (((PyFileObject*)f)->f_fp == NULL)
926 return err_closed();
927 result = get_line((PyFileObject *)f, n);
928 }
929 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000930 PyObject *reader;
931 PyObject *args;
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000932
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000933 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000934 if (reader == NULL)
935 return NULL;
936 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000937 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000938 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000939 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000940 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000941 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000942 return NULL;
943 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000944 result = PyEval_CallObject(reader, args);
945 Py_DECREF(reader);
946 Py_DECREF(args);
947 if (result != NULL && !PyString_Check(result)) {
948 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000949 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000950 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000951 "object.readline() returned non-string");
952 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000953 }
954
955 if (n < 0 && result != NULL && PyString_Check(result)) {
956 char *s = PyString_AS_STRING(result);
957 int len = PyString_GET_SIZE(result);
958 if (len == 0) {
959 Py_DECREF(result);
960 result = NULL;
961 PyErr_SetString(PyExc_EOFError,
962 "EOF when reading a line");
963 }
964 else if (s[len-1] == '\n') {
965 if (result->ob_refcnt == 1)
966 _PyString_Resize(&result, len-1);
967 else {
968 PyObject *v;
969 v = PyString_FromStringAndSize(s, len-1);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000970 Py_DECREF(result);
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000971 result = v;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000972 }
973 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000974 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000975 return result;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000976}
977
978/* Python method */
979
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000980static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000981file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000982{
Guido van Rossum789a1611997-05-10 22:33:55 +0000983 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000984
Guido van Rossumd7297e61992-07-06 14:19:26 +0000985 if (f->f_fp == NULL)
986 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000987 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000988 return NULL;
989 if (n == 0)
990 return PyString_FromString("");
991 if (n < 0)
992 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000993 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000994}
995
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000996static PyObject *
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000997file_xreadlines(PyFileObject *f, PyObject *args)
998{
999 static PyObject* xreadlines_function = NULL;
Tim Petersf29b64d2001-01-15 06:33:19 +00001000
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001001 if (!PyArg_ParseTuple(args, ":xreadlines"))
1002 return NULL;
Tim Petersf29b64d2001-01-15 06:33:19 +00001003
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001004 if (!xreadlines_function) {
1005 PyObject *xreadlines_module =
1006 PyImport_ImportModule("xreadlines");
1007 if(!xreadlines_module)
1008 return NULL;
1009
1010 xreadlines_function = PyObject_GetAttrString(xreadlines_module,
1011 "xreadlines");
1012 Py_DECREF(xreadlines_module);
1013 if(!xreadlines_function)
1014 return NULL;
1015 }
1016 return PyObject_CallFunction(xreadlines_function, "(O)", f);
1017}
1018
1019static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001020file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001021{
Guido van Rossum789a1611997-05-10 22:33:55 +00001022 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001023 PyObject *list;
1024 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +00001025 char small_buffer[SMALLCHUNK];
1026 char *buffer = small_buffer;
1027 size_t buffersize = SMALLCHUNK;
1028 PyObject *big_buffer = NULL;
1029 size_t nfilled = 0;
1030 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +00001031 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +00001032 char *p, *q, *end;
1033 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +00001034
Guido van Rossumd7297e61992-07-06 14:19:26 +00001035 if (f->f_fp == NULL)
1036 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +00001037 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +00001038 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001039 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +00001040 return NULL;
1041 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001042 Py_BEGIN_ALLOW_THREADS
1043 errno = 0;
1044 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
1045 Py_END_ALLOW_THREADS
1046 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +00001047 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +00001048 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +00001049 break;
1050 PyErr_SetFromErrno(PyExc_IOError);
1051 clearerr(f->f_fp);
1052 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001053 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +00001054 list = NULL;
1055 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001056 }
Guido van Rossum789a1611997-05-10 22:33:55 +00001057 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +00001058 p = memchr(buffer+nfilled, '\n', nread);
1059 if (p == NULL) {
1060 /* Need a larger buffer to fit this line */
1061 nfilled += nread;
1062 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +00001063 if (buffersize > INT_MAX) {
1064 PyErr_SetString(PyExc_OverflowError,
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001065 "line is longer than a Python string can hold");
Trent Mickf29f47b2000-08-11 19:02:59 +00001066 goto error;
1067 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001068 if (big_buffer == NULL) {
1069 /* Create the big buffer */
1070 big_buffer = PyString_FromStringAndSize(
1071 NULL, buffersize);
1072 if (big_buffer == NULL)
1073 goto error;
1074 buffer = PyString_AS_STRING(big_buffer);
1075 memcpy(buffer, small_buffer, nfilled);
1076 }
1077 else {
1078 /* Grow the big buffer */
1079 _PyString_Resize(&big_buffer, buffersize);
1080 buffer = PyString_AS_STRING(big_buffer);
1081 }
1082 continue;
1083 }
1084 end = buffer+nfilled+nread;
1085 q = buffer;
1086 do {
1087 /* Process complete lines */
1088 p++;
1089 line = PyString_FromStringAndSize(q, p-q);
1090 if (line == NULL)
1091 goto error;
1092 err = PyList_Append(list, line);
1093 Py_DECREF(line);
1094 if (err != 0)
1095 goto error;
1096 q = p;
1097 p = memchr(q, '\n', end-q);
1098 } while (p != NULL);
1099 /* Move the remaining incomplete line to the start */
1100 nfilled = end-q;
1101 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +00001102 if (sizehint > 0)
1103 if (totalread >= (size_t)sizehint)
1104 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001105 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001106 if (nfilled != 0) {
1107 /* Partial last line */
1108 line = PyString_FromStringAndSize(buffer, nfilled);
1109 if (line == NULL)
1110 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +00001111 if (sizehint > 0) {
1112 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +00001113 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +00001114 if (rest == NULL) {
1115 Py_DECREF(line);
1116 goto error;
1117 }
1118 PyString_Concat(&line, rest);
1119 Py_DECREF(rest);
1120 if (line == NULL)
1121 goto error;
1122 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001123 err = PyList_Append(list, line);
1124 Py_DECREF(line);
1125 if (err != 0)
1126 goto error;
1127 }
1128 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001129 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001130 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001131 }
Guido van Rossumce5ba841991-03-06 13:06:18 +00001132 return list;
1133}
1134
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001135static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001136file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137{
Guido van Rossumd7297e61992-07-06 14:19:26 +00001138 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001139 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001140 if (f->f_fp == NULL)
1141 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +00001142 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001143 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001144 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001145 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001146 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001147 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001148 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001149 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001150 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +00001151 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001152 return NULL;
1153 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001154 Py_INCREF(Py_None);
1155 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001156}
1157
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001158static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001159file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001160{
Guido van Rossumee70ad12000-03-13 16:27:06 +00001161#define CHUNKSIZE 1000
1162 PyObject *list, *line;
1163 PyObject *result;
1164 int i, j, index, len, nwritten, islist;
1165
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001166 if (f->f_fp == NULL)
1167 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +00001168 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001169 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001170 "writelines() argument must be a sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001171 return NULL;
1172 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001173 islist = PyList_Check(args);
1174
1175 /* Strategy: slurp CHUNKSIZE lines into a private list,
1176 checking that they are all strings, then write that list
1177 without holding the interpreter lock, then come back for more. */
1178 index = 0;
1179 if (islist)
1180 list = NULL;
1181 else {
1182 list = PyList_New(CHUNKSIZE);
1183 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001184 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001185 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001186 result = NULL;
1187
1188 for (;;) {
1189 if (islist) {
1190 Py_XDECREF(list);
1191 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
1192 if (list == NULL)
1193 return NULL;
1194 j = PyList_GET_SIZE(list);
1195 }
1196 else {
1197 for (j = 0; j < CHUNKSIZE; j++) {
1198 line = PySequence_GetItem(args, index+j);
1199 if (line == NULL) {
1200 if (PyErr_ExceptionMatches(
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001201 PyExc_IndexError)) {
Guido van Rossumee70ad12000-03-13 16:27:06 +00001202 PyErr_Clear();
1203 break;
1204 }
1205 /* Some other error occurred.
1206 XXX We may lose some output. */
1207 goto error;
1208 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001209 PyList_SetItem(list, j, line);
1210 }
1211 }
1212 if (j == 0)
1213 break;
1214
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001215 /* Check that all entries are indeed strings. If not,
1216 apply the same rules as for file.write() and
1217 convert the results to strings. This is slow, but
1218 seems to be the only way since all conversion APIs
1219 could potentially execute Python code. */
1220 for (i = 0; i < j; i++) {
1221 PyObject *v = PyList_GET_ITEM(list, i);
1222 if (!PyString_Check(v)) {
1223 const char *buffer;
1224 int len;
Tim Peters86821b22001-01-07 21:19:34 +00001225 if (((f->f_binary &&
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001226 PyObject_AsReadBuffer(v,
1227 (const void**)&buffer,
1228 &len)) ||
1229 PyObject_AsCharBuffer(v,
1230 &buffer,
1231 &len))) {
1232 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001233 "writelines() argument must be a sequence of strings");
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001234 goto error;
1235 }
1236 line = PyString_FromStringAndSize(buffer,
1237 len);
1238 if (line == NULL)
1239 goto error;
1240 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001241 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001242 }
1243 }
1244
1245 /* Since we are releasing the global lock, the
1246 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001247 Py_BEGIN_ALLOW_THREADS
1248 f->f_softspace = 0;
1249 errno = 0;
1250 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001251 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001252 len = PyString_GET_SIZE(line);
1253 nwritten = fwrite(PyString_AS_STRING(line),
1254 1, len, f->f_fp);
1255 if (nwritten != len) {
1256 Py_BLOCK_THREADS
1257 PyErr_SetFromErrno(PyExc_IOError);
1258 clearerr(f->f_fp);
1259 goto error;
1260 }
1261 }
1262 Py_END_ALLOW_THREADS
1263
1264 if (j < CHUNKSIZE)
1265 break;
1266 index += CHUNKSIZE;
1267 }
1268
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001269 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001270 result = Py_None;
1271 error:
1272 Py_XDECREF(list);
1273 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001274}
1275
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001276static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +00001277 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001278 {"read", (PyCFunction)file_read, 1},
1279 {"write", (PyCFunction)file_write, 0},
1280 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +00001281 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001282#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +00001283 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001284#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001285 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001286 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001287 {"readlines", (PyCFunction)file_readlines, 1},
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001288 {"xreadlines", (PyCFunction)file_xreadlines, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001289 {"writelines", (PyCFunction)file_writelines, 0},
1290 {"flush", (PyCFunction)file_flush, 0},
1291 {"close", (PyCFunction)file_close, 0},
1292 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001293 {NULL, NULL} /* sentinel */
1294};
1295
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001296#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001297
1298static struct memberlist file_memberlist[] = {
1299 {"softspace", T_INT, OFF(f_softspace)},
1300 {"mode", T_OBJECT, OFF(f_mode), RO},
1301 {"name", T_OBJECT, OFF(f_name), RO},
1302 /* getattr(f, "closed") is implemented without this table */
1303 {"closed", T_INT, 0, RO},
1304 {NULL} /* Sentinel */
1305};
1306
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001307static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001308file_getattr(PyFileObject *f, char *name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001309{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001310 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001311
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001312 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001313 if (res != NULL)
1314 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001315 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001316 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001317 return PyInt_FromLong((long)(f->f_fp == 0));
1318 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001319}
1320
1321static int
Fred Drakefd99de62000-07-09 05:02:18 +00001322file_setattr(PyFileObject *f, char *name, PyObject *v)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001323{
1324 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001325 PyErr_SetString(PyExc_AttributeError,
1326 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001327 return -1;
1328 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001329 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001330}
1331
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001332PyTypeObject PyFile_Type = {
1333 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001334 0,
1335 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001336 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001337 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001338 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001339 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001340 (getattrfunc)file_getattr, /*tp_getattr*/
1341 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001343 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001345
1346/* Interface for the 'soft space' between print items. */
1347
1348int
Fred Drakefd99de62000-07-09 05:02:18 +00001349PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001350{
1351 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001352 if (f == NULL) {
1353 /* Do nothing */
1354 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001355 else if (PyFile_Check(f)) {
1356 oldflag = ((PyFileObject *)f)->f_softspace;
1357 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001358 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001359 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001360 PyObject *v;
1361 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001362 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001363 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001364 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001365 if (PyInt_Check(v))
1366 oldflag = PyInt_AsLong(v);
1367 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001368 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001369 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001370 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001371 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001372 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001373 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1374 PyErr_Clear();
1375 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001376 }
1377 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001378 return oldflag;
1379}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001380
1381/* Interfaces to write objects/strings to file-like objects */
1382
1383int
Fred Drakefd99de62000-07-09 05:02:18 +00001384PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001385{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001386 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001387 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001388 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001389 return -1;
1390 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001391 else if (PyFile_Check(f)) {
1392 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001393 if (fp == NULL) {
1394 err_closed();
1395 return -1;
1396 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001397 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001398 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001399 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001400 if (writer == NULL)
1401 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001402 if (flags & Py_PRINT_RAW)
1403 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001404 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001405 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001406 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001407 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001408 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001409 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001410 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001411 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001412 Py_DECREF(value);
1413 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001414 return -1;
1415 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001416 result = PyEval_CallObject(writer, args);
1417 Py_DECREF(args);
1418 Py_DECREF(value);
1419 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001420 if (result == NULL)
1421 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001422 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001423 return 0;
1424}
1425
Guido van Rossum27a60b11997-05-22 22:25:11 +00001426int
Fred Drakefd99de62000-07-09 05:02:18 +00001427PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001428{
1429 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001430 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001431 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001432 PyErr_SetString(PyExc_SystemError,
1433 "null file for PyFile_WriteString");
1434 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001435 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001436 else if (PyFile_Check(f)) {
1437 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001438 if (fp == NULL) {
1439 err_closed();
1440 return -1;
1441 }
1442 fputs(s, fp);
1443 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001444 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001445 else if (!PyErr_Occurred()) {
1446 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001447 int err;
1448 if (v == NULL)
1449 return -1;
1450 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1451 Py_DECREF(v);
1452 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001453 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001454 else
1455 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001456}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001457
1458/* Try to get a file-descriptor from a Python object. If the object
1459 is an integer or long integer, its value is returned. If not, the
1460 object's fileno() method is called if it exists; the method must return
1461 an integer or long integer, which is returned as the file descriptor value.
1462 -1 is returned on failure.
1463*/
1464
1465int PyObject_AsFileDescriptor(PyObject *o)
1466{
1467 int fd;
1468 PyObject *meth;
1469
1470 if (PyInt_Check(o)) {
1471 fd = PyInt_AsLong(o);
1472 }
1473 else if (PyLong_Check(o)) {
1474 fd = PyLong_AsLong(o);
1475 }
1476 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1477 {
1478 PyObject *fno = PyEval_CallObject(meth, NULL);
1479 Py_DECREF(meth);
1480 if (fno == NULL)
1481 return -1;
Tim Peters86821b22001-01-07 21:19:34 +00001482
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001483 if (PyInt_Check(fno)) {
1484 fd = PyInt_AsLong(fno);
1485 Py_DECREF(fno);
1486 }
1487 else if (PyLong_Check(fno)) {
1488 fd = PyLong_AsLong(fno);
1489 Py_DECREF(fno);
1490 }
1491 else {
1492 PyErr_SetString(PyExc_TypeError,
1493 "fileno() returned a non-integer");
1494 Py_DECREF(fno);
1495 return -1;
1496 }
1497 }
1498 else {
1499 PyErr_SetString(PyExc_TypeError,
1500 "argument must be an int, or have a fileno() method.");
1501 return -1;
1502 }
1503
1504 if (fd < 0) {
1505 PyErr_Format(PyExc_ValueError,
1506 "file descriptor cannot be a negative integer (%i)",
1507 fd);
1508 return -1;
1509 }
1510 return fd;
1511}
1512
1513
1514