blob: e18e2a2387b14b0c7c1d71dc5df16992f1879690 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* File object implementation */
3
Guido van Rossumc0b618a1997-05-02 03:12:38 +00004#include "Python.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +00005#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006
Guido van Rossumff7e83d1999-08-27 20:39:37 +00007#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum41498431999-01-07 22:09:51 +00008#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +00009#endif /* DONT_HAVE_SYS_TYPES_H */
Guido van Rossum41498431999-01-07 22:09:51 +000010
Guido van Rossum685a38e1996-12-05 21:54:17 +000011#ifdef HAVE_UNISTD_H
12#include <unistd.h>
13#endif
14
Guido van Rossumb8199141997-05-06 15:23:24 +000015#ifdef MS_WIN32
Guido van Rossumb8199141997-05-06 15:23:24 +000016#define fileno _fileno
Trent Mickf29f47b2000-08-11 19:02:59 +000017/* can (almost fully) duplicate with _chsize, see file_truncate */
Guido van Rossumb8199141997-05-06 15:23:24 +000018#define HAVE_FTRUNCATE
19#endif
20
Guido van Rossumf2044e11998-04-28 16:05:59 +000021#ifdef macintosh
22#ifdef USE_GUSI
23#define HAVE_FTRUNCATE
24#endif
25#endif
26
Jack Jansene08dea191995-04-23 22:12:47 +000027#ifdef __MWERKS__
28/* Mwerks fopen() doesn't always set errno */
29#define NO_FOPEN_ERRNO
30#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000031
Guido van Rossumc0b618a1997-05-02 03:12:38 +000032#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000033
Guido van Rossumff7e83d1999-08-27 20:39:37 +000034#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000035#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000036#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000037
Trent Mickf29f47b2000-08-11 19:02:59 +000038
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000040 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000042 PyObject *f_name;
43 PyObject *f_mode;
Tim Petersdbd9ba62000-07-09 03:09:57 +000044 int (*f_close)(FILE *);
Guido van Rossumeb183da1991-04-04 10:44:06 +000045 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000046 int f_binary; /* Flag which indicates whether the file is open
47 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000048} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000049
50FILE *
Fred Drakefd99de62000-07-09 05:02:18 +000051PyFile_AsFile(PyObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000053 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000055 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000056 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057}
58
Guido van Rossumc0b618a1997-05-02 03:12:38 +000059PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000060PyFile_Name(PyObject *f)
Guido van Rossumdb3165e1993-10-18 17:06:59 +000061{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000062 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000063 return NULL;
64 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000065 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000066}
67
Guido van Rossumc0b618a1997-05-02 03:12:38 +000068PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000069PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000071 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000072 if (f == NULL)
73 return NULL;
74 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000075 f->f_name = PyString_FromString(name);
76 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000077 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000078 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +000079 if (strchr(mode,'b') != NULL)
80 f->f_binary = 1;
81 else
82 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000084 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085 return NULL;
86 }
87 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089}
90
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000092PyFile_FromString(char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000093{
Tim Petersdbd9ba62000-07-09 03:09:57 +000094 extern int fclose(FILE *);
Guido van Rossumc0b618a1997-05-02 03:12:38 +000095 PyFileObject *f;
96 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 if (f == NULL)
98 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +000099#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000100 if (*mode == '*') {
101 FILE *fopenRF();
102 f->f_fp = fopenRF(name, mode+1);
103 }
104 else
105#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000106 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000107 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000108 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000110 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000111 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000112#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000113 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000114 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115 PyErr_SetString(PyExc_IOError, "Cannot open file");
116 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000117 return NULL;
118 }
119#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000120 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000121 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122 return NULL;
123 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000124 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125}
126
Guido van Rossumb6775db1994-08-01 11:34:53 +0000127void
Fred Drakefd99de62000-07-09 05:02:18 +0000128PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000129{
130 if (bufsize >= 0) {
131#ifdef HAVE_SETVBUF
132 int type;
133 switch (bufsize) {
134 case 0:
135 type = _IONBF;
136 break;
137 case 1:
138 type = _IOLBF;
139 bufsize = BUFSIZ;
140 break;
141 default:
142 type = _IOFBF;
143 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000144 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
145 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000146#else /* !HAVE_SETVBUF */
147 if (bufsize <= 1)
148 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
149#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000150 }
151}
152
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000153static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000154err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000155{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000156 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000157 return NULL;
158}
159
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160/* Methods */
161
162static void
Fred Drakefd99de62000-07-09 05:02:18 +0000163file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000165 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000166 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000167 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000168 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000169 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000170 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000171 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000172 }
173 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000174 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000175 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000176 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177}
178
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000179static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000180file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181{
Barry Warsaw7ce36942001-08-24 18:34:26 +0000182 return PyString_FromFormat("<%s file '%s', mode '%s' at %p>",
183 f->f_fp == NULL ? "closed" : "open",
184 PyString_AsString(f->f_name),
185 PyString_AsString(f->f_mode),
186 f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187}
188
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000189static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000190file_close(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000192 int sts = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000194 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000195 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000196 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000197 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000198 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000199 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 f->f_fp = NULL;
201 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000202 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000203 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000204 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205 return PyInt_FromLong((long)sts);
206 Py_INCREF(Py_None);
207 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208}
209
Trent Mickf29f47b2000-08-11 19:02:59 +0000210
Guido van Rossum4f53da02001-03-01 18:26:53 +0000211/* An 8-byte off_t-like type */
212#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
213typedef fpos_t Py_off_t;
214#else
215typedef off_t Py_off_t;
216#endif
217
218
Trent Mickf29f47b2000-08-11 19:02:59 +0000219/* a portable fseek() function
220 return 0 on success, non-zero on failure (with errno set) */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000221static int
Guido van Rossum4f53da02001-03-01 18:26:53 +0000222_portable_fseek(FILE *fp, Py_off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000223{
224#if defined(HAVE_FSEEKO)
225 return fseeko(fp, offset, whence);
226#elif defined(HAVE_FSEEK64)
227 return fseek64(fp, offset, whence);
Fred Drakedb810ac2000-10-06 20:42:33 +0000228#elif defined(__BEOS__)
229 return _fseek(fp, offset, whence);
Tim Peters86821b22001-01-07 21:19:34 +0000230#elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
Guido van Rossume54e0be2001-01-16 20:53:31 +0000231 /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
232 and fgetpos() to implement fseek()*/
Trent Mickf29f47b2000-08-11 19:02:59 +0000233 fpos_t pos;
234 switch (whence) {
Guido van Rossume54e0be2001-01-16 20:53:31 +0000235 case SEEK_END:
236 if (fseek(fp, 0, SEEK_END) != 0)
237 return -1;
238 /* fall through */
239 case SEEK_CUR:
240 if (fgetpos(fp, &pos) != 0)
241 return -1;
242 offset += pos;
243 break;
244 /* case SEEK_SET: break; */
Trent Mickf29f47b2000-08-11 19:02:59 +0000245 }
246 return fsetpos(fp, &offset);
247#else
248 return fseek(fp, offset, whence);
249#endif
250}
251
252
253/* a portable ftell() function
254 Return -1 on failure with errno set appropriately, current file
255 position on success */
Guido van Rossumf68d8e52001-04-14 17:55:09 +0000256static Py_off_t
Fred Drake8ce159a2000-08-31 05:18:54 +0000257_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000258{
Guido van Rossum4f53da02001-03-01 18:26:53 +0000259#if SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000260 fpos_t pos;
261 if (fgetpos(fp, &pos) != 0)
262 return -1;
263 return pos;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000264#elif defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
265 return ftello(fp);
266#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
267 return ftell64(fp);
Trent Mickf29f47b2000-08-11 19:02:59 +0000268#else
269 return ftell(fp);
270#endif
271}
272
273
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000274static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000275file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000277 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000278 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000279 Py_off_t offset;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000280 PyObject *offobj;
Tim Peters86821b22001-01-07 21:19:34 +0000281
Guido van Rossumd7297e61992-07-06 14:19:26 +0000282 if (f->f_fp == NULL)
283 return err_closed();
284 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000285 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000286 return NULL;
287#if !defined(HAVE_LARGEFILE_SUPPORT)
288 offset = PyInt_AsLong(offobj);
289#else
290 offset = PyLong_Check(offobj) ?
291 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
292#endif
293 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000294 return NULL;
Tim Peters86821b22001-01-07 21:19:34 +0000295
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000296 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000297 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000298 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000299 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000300
Guido van Rossumff4949e1992-08-05 19:58:53 +0000301 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000302 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000303 clearerr(f->f_fp);
304 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000305 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 Py_INCREF(Py_None);
307 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000308}
309
Trent Mickf29f47b2000-08-11 19:02:59 +0000310
Guido van Rossumd7047b31995-01-02 19:07:15 +0000311#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000312static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000313file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000314{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000315 int ret;
Guido van Rossum4f53da02001-03-01 18:26:53 +0000316 Py_off_t newsize;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000317 PyObject *newsizeobj;
Tim Peters86821b22001-01-07 21:19:34 +0000318
Guido van Rossumd7047b31995-01-02 19:07:15 +0000319 if (f->f_fp == NULL)
320 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000321 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000322 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000323 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000324 if (newsizeobj != NULL) {
325#if !defined(HAVE_LARGEFILE_SUPPORT)
326 newsize = PyInt_AsLong(newsizeobj);
327#else
328 newsize = PyLong_Check(newsizeobj) ?
329 PyLong_AsLongLong(newsizeobj) :
330 PyInt_AsLong(newsizeobj);
331#endif
332 if (PyErr_Occurred())
333 return NULL;
334 } else {
335 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000336 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000337 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000338 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000339 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000340 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000341 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000342 clearerr(f->f_fp);
343 return NULL;
344 }
345 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000347 errno = 0;
348 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000350 if (ret != 0) goto onioerror;
351
352#ifdef MS_WIN32
353 /* can use _chsize; if, however, the newsize overflows 32-bits then
354 _chsize is *not* adequate; in this case, an OverflowError is raised */
355 if (newsize > LONG_MAX) {
356 PyErr_SetString(PyExc_OverflowError,
357 "the new size is too long for _chsize (it is limited to 32-bit values)");
Guido van Rossumd7047b31995-01-02 19:07:15 +0000358 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000359 } else {
360 Py_BEGIN_ALLOW_THREADS
361 errno = 0;
362 ret = _chsize(fileno(f->f_fp), newsize);
363 Py_END_ALLOW_THREADS
364 if (ret != 0) goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000365 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000366#else
367 Py_BEGIN_ALLOW_THREADS
368 errno = 0;
369 ret = ftruncate(fileno(f->f_fp), newsize);
370 Py_END_ALLOW_THREADS
371 if (ret != 0) goto onioerror;
372#endif /* !MS_WIN32 */
Tim Peters86821b22001-01-07 21:19:34 +0000373
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000374 Py_INCREF(Py_None);
375 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000376
377onioerror:
378 PyErr_SetFromErrno(PyExc_IOError);
379 clearerr(f->f_fp);
380 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000381}
382#endif /* HAVE_FTRUNCATE */
383
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000384static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000385file_tell(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000386{
Guido van Rossum4f53da02001-03-01 18:26:53 +0000387 Py_off_t pos;
Trent Mickf29f47b2000-08-11 19:02:59 +0000388
Guido van Rossumd7297e61992-07-06 14:19:26 +0000389 if (f->f_fp == NULL)
390 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000391 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000392 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000393 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000394 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000395 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000396 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000397 clearerr(f->f_fp);
398 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000399 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000400#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000401 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000402#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000403 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000404#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000405}
406
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000407static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000408file_fileno(PyFileObject *f)
Guido van Rossumed233a51992-06-23 09:07:03 +0000409{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000410 if (f->f_fp == NULL)
411 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000412 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000413}
414
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000416file_flush(PyFileObject *f)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000417{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000418 int res;
Tim Peters86821b22001-01-07 21:19:34 +0000419
Guido van Rossumd7297e61992-07-06 14:19:26 +0000420 if (f->f_fp == NULL)
421 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000423 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000424 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000425 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000426 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000427 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000428 clearerr(f->f_fp);
429 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000430 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000431 Py_INCREF(Py_None);
432 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000433}
434
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000435static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000436file_isatty(PyFileObject *f)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000437{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000438 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000439 if (f->f_fp == NULL)
440 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000441 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000442 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000443 Py_END_ALLOW_THREADS
444 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000445}
446
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000447
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000448#if BUFSIZ < 8192
449#define SMALLCHUNK 8192
450#else
451#define SMALLCHUNK BUFSIZ
452#endif
453
Guido van Rossum3c259041999-01-14 19:00:14 +0000454#if SIZEOF_INT < 4
455#define BIGCHUNK (512 * 32)
456#else
457#define BIGCHUNK (512 * 1024)
458#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000459
460static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000461new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000462{
463#ifdef HAVE_FSTAT
Fred Drake1bc8fab2001-07-19 21:49:38 +0000464 off_t pos, end;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000465 struct stat st;
466 if (fstat(fileno(f->f_fp), &st) == 0) {
467 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000468 /* The following is not a bug: we really need to call lseek()
469 *and* ftell(). The reason is that some stdio libraries
470 mistakenly flush their buffer when ftell() is called and
471 the lseek() call it makes fails, thereby throwing away
472 data that cannot be recovered in any way. To avoid this,
473 we first test lseek(), and only call ftell() if lseek()
474 works. We can't use the lseek() value either, because we
475 need to take the amount of buffered data into account.
476 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000477 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
478 if (pos >= 0)
479 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000480 if (pos < 0)
481 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000482 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000483 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000484 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000485 }
486#endif
487 if (currentsize > SMALLCHUNK) {
488 /* Keep doubling until we reach BIGCHUNK;
489 then keep adding BIGCHUNK. */
490 if (currentsize <= BIGCHUNK)
491 return currentsize + currentsize;
492 else
493 return currentsize + BIGCHUNK;
494 }
495 return currentsize + SMALLCHUNK;
496}
497
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000498static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000499file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000500{
Guido van Rossum789a1611997-05-10 22:33:55 +0000501 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000502 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000503 PyObject *v;
Tim Peters86821b22001-01-07 21:19:34 +0000504
Guido van Rossumd7297e61992-07-06 14:19:26 +0000505 if (f->f_fp == NULL)
506 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000507 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000508 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000509 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000510 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000511 else
512 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000513 if (buffersize > INT_MAX) {
514 PyErr_SetString(PyExc_OverflowError,
515 "requested number of bytes is more than a Python string can hold");
516 return NULL;
517 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000518 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000519 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000520 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000521 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000522 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000523 Py_BEGIN_ALLOW_THREADS
524 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000525 chunksize = fread(BUF(v) + bytesread, 1,
526 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000527 Py_END_ALLOW_THREADS
528 if (chunksize == 0) {
529 if (!ferror(f->f_fp))
530 break;
531 PyErr_SetFromErrno(PyExc_IOError);
532 clearerr(f->f_fp);
533 Py_DECREF(v);
534 return NULL;
535 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000536 bytesread += chunksize;
537 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000538 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000539 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000540 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000541 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000542 return NULL;
543 }
544 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000545 if (bytesread != buffersize)
546 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000547 return v;
548}
549
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000550static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000551file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000552{
553 char *ptr;
Trent Mickf29f47b2000-08-11 19:02:59 +0000554 size_t ntodo, ndone, nnow;
Tim Peters86821b22001-01-07 21:19:34 +0000555
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000556 if (f->f_fp == NULL)
557 return err_closed();
558 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
559 return NULL;
560 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000561 while (ntodo > 0) {
562 Py_BEGIN_ALLOW_THREADS
563 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000564 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000565 Py_END_ALLOW_THREADS
566 if (nnow == 0) {
567 if (!ferror(f->f_fp))
568 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000569 PyErr_SetFromErrno(PyExc_IOError);
570 clearerr(f->f_fp);
571 return NULL;
572 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000573 ndone += nnow;
574 ntodo -= nnow;
575 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000576 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000577}
578
Tim Peters86821b22001-01-07 21:19:34 +0000579/**************************************************************************
Tim Petersf29b64d2001-01-15 06:33:19 +0000580Routine to get next line using platform fgets().
Tim Peters86821b22001-01-07 21:19:34 +0000581
582Under MSVC 6:
583
Tim Peters1c733232001-01-08 04:02:07 +0000584+ MS threadsafe getc is very slow (multiple layers of function calls before+
585 after each character, to lock+unlock the stream).
586+ The stream-locking functions are MS-internal -- can't access them from user
587 code.
588+ There's nothing Tim could find in the MS C or platform SDK libraries that
589 can worm around this.
Tim Peters86821b22001-01-07 21:19:34 +0000590+ MS fgets locks/unlocks only once per line; it's the only hook we have.
591
592So we use fgets for speed(!), despite that it's painful.
593
594MS realloc is also slow.
595
Tim Petersf29b64d2001-01-15 06:33:19 +0000596Reports from other platforms on this method vs getc_unlocked (which MS doesn't
597have):
598 Linux a wash
599 Solaris a wash
600 Tru64 Unix getline_via_fgets significantly faster
Tim Peters86821b22001-01-07 21:19:34 +0000601
Tim Petersf29b64d2001-01-15 06:33:19 +0000602CAUTION: The C std isn't clear about this: in those cases where fgets
603writes something into the buffer, can it write into any position beyond the
604required trailing null byte? MSVC 6 fgets does not, and no platform is (yet)
605known on which it does; and it would be a strange way to code fgets. Still,
606getline_via_fgets may not work correctly if it does. The std test
607test_bufio.py should fail if platform fgets() routinely writes beyond the
608trailing null byte. #define DONT_USE_FGETS_IN_GETLINE to disable this code.
Tim Peters86821b22001-01-07 21:19:34 +0000609**************************************************************************/
610
Tim Petersf29b64d2001-01-15 06:33:19 +0000611/* Use this routine if told to, or by default on non-get_unlocked()
612 * platforms unless told not to. Yikes! Let's spell that out:
613 * On a platform with getc_unlocked():
614 * By default, use getc_unlocked().
615 * If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
616 * On a platform without getc_unlocked():
617 * By default, use fgets().
618 * If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
619 */
620#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
621#define USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000622#endif
623
Tim Petersf29b64d2001-01-15 06:33:19 +0000624#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
625#undef USE_FGETS_IN_GETLINE
626#endif
627
628#ifdef USE_FGETS_IN_GETLINE
Tim Peters86821b22001-01-07 21:19:34 +0000629static PyObject*
Tim Petersf29b64d2001-01-15 06:33:19 +0000630getline_via_fgets(FILE *fp)
Tim Peters86821b22001-01-07 21:19:34 +0000631{
Tim Peters15b83852001-01-08 00:53:12 +0000632/* INITBUFSIZE is the maximum line length that lets us get away with the fast
Tim Peters142297a2001-01-15 10:36:56 +0000633 * no-realloc, one-fgets()-call path. Boosting it isn't free, because we have
634 * to fill this much of the buffer with a known value in order to figure out
635 * how much of the buffer fgets() overwrites. So if INITBUFSIZE is larger
636 * than "most" lines, we waste time filling unused buffer slots. 100 is
637 * surely adequate for most peoples' email archives, chewing over source code,
638 * etc -- "regular old text files".
639 * MAXBUFSIZE is the maximum line length that lets us get away with the less
640 * fast (but still zippy) no-realloc, two-fgets()-call path. See above for
641 * cautions about boosting that. 300 was chosen because the worst real-life
642 * text-crunching job reported on Python-Dev was a mail-log crawler where over
643 * half the lines were 254 chars.
644 * INCBUFSIZE is the amount by which we grow the buffer, if MAXBUFSIZE isn't
645 * enough. It doesn't much matter what this is set to: we only get here for
646 * absurdly long lines anyway.
Tim Peters15b83852001-01-08 00:53:12 +0000647 */
Tim Peters142297a2001-01-15 10:36:56 +0000648#define INITBUFSIZE 100
649#define MAXBUFSIZE 300
Tim Peters86821b22001-01-07 21:19:34 +0000650#define INCBUFSIZE 1000
Tim Peters142297a2001-01-15 10:36:56 +0000651 char* p; /* temp */
652 char buf[MAXBUFSIZE];
Tim Peters86821b22001-01-07 21:19:34 +0000653 PyObject* v; /* the string object result */
Tim Peters86821b22001-01-07 21:19:34 +0000654 char* pvfree; /* address of next free slot */
655 char* pvend; /* address one beyond last free slot */
Tim Peters142297a2001-01-15 10:36:56 +0000656 size_t nfree; /* # of free buffer slots; pvend-pvfree */
657 size_t total_v_size; /* total # of slots in buffer */
Tim Peters86821b22001-01-07 21:19:34 +0000658
Tim Peters15b83852001-01-08 00:53:12 +0000659 /* Optimize for normal case: avoid _PyString_Resize if at all
Tim Peters142297a2001-01-15 10:36:56 +0000660 * possible via first reading into stack buffer "buf".
Tim Peters15b83852001-01-08 00:53:12 +0000661 */
Tim Peters142297a2001-01-15 10:36:56 +0000662 total_v_size = INITBUFSIZE; /* start small and pray */
663 pvfree = buf;
664 for (;;) {
665 Py_BEGIN_ALLOW_THREADS
666 pvend = buf + total_v_size;
667 nfree = pvend - pvfree;
668 memset(pvfree, '\n', nfree);
669 p = fgets(pvfree, nfree, fp);
670 Py_END_ALLOW_THREADS
Tim Peters15b83852001-01-08 00:53:12 +0000671
Tim Peters142297a2001-01-15 10:36:56 +0000672 if (p == NULL) {
673 clearerr(fp);
674 if (PyErr_CheckSignals())
675 return NULL;
676 v = PyString_FromStringAndSize(buf, pvfree - buf);
Tim Peters86821b22001-01-07 21:19:34 +0000677 return v;
678 }
Tim Peters142297a2001-01-15 10:36:56 +0000679 /* fgets read *something* */
680 p = memchr(pvfree, '\n', nfree);
681 if (p != NULL) {
682 /* Did the \n come from fgets or from us?
683 * Since fgets stops at the first \n, and then writes
684 * \0, if it's from fgets a \0 must be next. But if
685 * that's so, it could not have come from us, since
686 * the \n's we filled the buffer with have only more
687 * \n's to the right.
688 */
689 if (p+1 < pvend && *(p+1) == '\0') {
690 /* It's from fgets: we win! In particular,
691 * we haven't done any mallocs yet, and can
692 * build the final result on the first try.
693 */
694 ++p; /* include \n from fgets */
695 }
696 else {
697 /* Must be from us: fgets didn't fill the
698 * buffer and didn't find a newline, so it
699 * must be the last and newline-free line of
700 * the file.
701 */
702 assert(p > pvfree && *(p-1) == '\0');
703 --p; /* don't include \0 from fgets */
704 }
705 v = PyString_FromStringAndSize(buf, p - buf);
706 return v;
707 }
708 /* yuck: fgets overwrote all the newlines, i.e. the entire
709 * buffer. So this line isn't over yet, or maybe it is but
710 * we're exactly at EOF. If we haven't already, try using the
711 * rest of the stack buffer.
Tim Peters86821b22001-01-07 21:19:34 +0000712 */
Tim Peters142297a2001-01-15 10:36:56 +0000713 assert(*(pvend-1) == '\0');
714 if (pvfree == buf) {
715 pvfree = pvend - 1; /* overwrite trailing null */
716 total_v_size = MAXBUFSIZE;
717 }
718 else
719 break;
Tim Peters86821b22001-01-07 21:19:34 +0000720 }
Tim Peters142297a2001-01-15 10:36:56 +0000721
722 /* The stack buffer isn't big enough; malloc a string object and read
723 * into its buffer.
Tim Peters15b83852001-01-08 00:53:12 +0000724 */
Tim Peters142297a2001-01-15 10:36:56 +0000725 total_v_size = MAXBUFSIZE + INCBUFSIZE;
Tim Peters1c733232001-01-08 04:02:07 +0000726 v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
Tim Peters15b83852001-01-08 00:53:12 +0000727 if (v == NULL)
728 return v;
729 /* copy over everything except the last null byte */
Tim Peters142297a2001-01-15 10:36:56 +0000730 memcpy(BUF(v), buf, MAXBUFSIZE-1);
731 pvfree = BUF(v) + MAXBUFSIZE - 1;
Tim Peters86821b22001-01-07 21:19:34 +0000732
733 /* Keep reading stuff into v; if it ever ends successfully, break
Tim Peters15b83852001-01-08 00:53:12 +0000734 * after setting p one beyond the end of the line. The code here is
735 * very much like the code above, except reads into v's buffer; see
736 * the code above for detailed comments about the logic.
Tim Peters86821b22001-01-07 21:19:34 +0000737 */
738 for (;;) {
Tim Peters86821b22001-01-07 21:19:34 +0000739 Py_BEGIN_ALLOW_THREADS
740 pvend = BUF(v) + total_v_size;
741 nfree = pvend - pvfree;
742 memset(pvfree, '\n', nfree);
743 p = fgets(pvfree, nfree, fp);
744 Py_END_ALLOW_THREADS
745
746 if (p == NULL) {
747 clearerr(fp);
748 if (PyErr_CheckSignals()) {
749 Py_DECREF(v);
750 return NULL;
751 }
752 p = pvfree;
753 break;
754 }
Tim Peters86821b22001-01-07 21:19:34 +0000755 p = memchr(pvfree, '\n', nfree);
756 if (p != NULL) {
757 if (p+1 < pvend && *(p+1) == '\0') {
758 /* \n came from fgets */
759 ++p;
760 break;
761 }
762 /* \n came from us; last line of file, no newline */
763 assert(p > pvfree && *(p-1) == '\0');
764 --p;
765 break;
766 }
767 /* expand buffer and try again */
768 assert(*(pvend-1) == '\0');
769 total_v_size += INCBUFSIZE;
770 if (total_v_size > INT_MAX) {
771 PyErr_SetString(PyExc_OverflowError,
772 "line is longer than a Python string can hold");
773 Py_DECREF(v);
774 return NULL;
775 }
776 if (_PyString_Resize(&v, (int)total_v_size) < 0)
777 return NULL;
778 /* overwrite the trailing null byte */
779 pvfree = BUF(v) + (total_v_size - INCBUFSIZE - 1);
780 }
781 if (BUF(v) + total_v_size != p)
782 _PyString_Resize(&v, p - BUF(v));
783 return v;
784#undef INITBUFSIZE
Tim Peters142297a2001-01-15 10:36:56 +0000785#undef MAXBUFSIZE
Tim Peters86821b22001-01-07 21:19:34 +0000786#undef INCBUFSIZE
787}
Tim Petersf29b64d2001-01-15 06:33:19 +0000788#endif /* ifdef USE_FGETS_IN_GETLINE */
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000789
Guido van Rossum0bd24411991-04-04 15:21:57 +0000790/* Internal routine to get a line.
791 Size argument interpretation:
792 > 0: max length;
Guido van Rossum86282062001-01-08 01:26:47 +0000793 <= 0: read arbitrary line
Guido van Rossumce5ba841991-03-06 13:06:18 +0000794*/
795
Guido van Rossum1187aa42001-01-05 14:43:05 +0000796#ifdef HAVE_GETC_UNLOCKED
797#define GETC(f) getc_unlocked(f)
798#define FLOCKFILE(f) flockfile(f)
799#define FUNLOCKFILE(f) funlockfile(f)
800#else
801#define GETC(f) getc(f)
802#define FLOCKFILE(f)
803#define FUNLOCKFILE(f)
804#endif
805
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000806static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000807get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000808{
Guido van Rossum1187aa42001-01-05 14:43:05 +0000809 FILE *fp = f->f_fp;
810 int c;
Andrew M. Kuchling4b2b4452000-11-29 02:53:22 +0000811 char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000812 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000813 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000814
Tim Petersf29b64d2001-01-15 06:33:19 +0000815#ifdef USE_FGETS_IN_GETLINE
Guido van Rossum86282062001-01-08 01:26:47 +0000816 if (n <= 0)
Tim Petersf29b64d2001-01-15 06:33:19 +0000817 return getline_via_fgets(fp);
Tim Peters86821b22001-01-07 21:19:34 +0000818#endif
Guido van Rossum0bd24411991-04-04 15:21:57 +0000819 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000820 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000821 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000822 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000823 buf = BUF(v);
824 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000825
Guido van Rossumce5ba841991-03-06 13:06:18 +0000826 for (;;) {
Guido van Rossum1187aa42001-01-05 14:43:05 +0000827 Py_BEGIN_ALLOW_THREADS
828 FLOCKFILE(fp);
829 while ((c = GETC(fp)) != EOF &&
830 (*buf++ = c) != '\n' &&
831 buf != end)
832 ;
833 FUNLOCKFILE(fp);
834 Py_END_ALLOW_THREADS
835 if (c == '\n')
836 break;
837 if (c == EOF) {
Guido van Rossum29206bc2001-08-09 18:14:59 +0000838 if (ferror(fp)) {
839 PyErr_SetFromErrno(PyExc_IOError);
840 clearerr(fp);
841 Py_DECREF(v);
842 return NULL;
843 }
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000844 clearerr(fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000845 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000846 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000847 return NULL;
848 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000849 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000850 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000851 /* Must be because buf == end */
852 if (n > 0)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000853 break;
Guido van Rossum1187aa42001-01-05 14:43:05 +0000854 n1 = n2;
855 n2 += 1000;
856 if (n2 > INT_MAX) {
857 PyErr_SetString(PyExc_OverflowError,
858 "line is longer than a Python string can hold");
Tim Peters86821b22001-01-07 21:19:34 +0000859 Py_DECREF(v);
Guido van Rossum1187aa42001-01-05 14:43:05 +0000860 return NULL;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000861 }
Guido van Rossum1187aa42001-01-05 14:43:05 +0000862 if (_PyString_Resize(&v, n2) < 0)
863 return NULL;
864 buf = BUF(v) + n1;
865 end = BUF(v) + n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000866 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000867
Guido van Rossumce5ba841991-03-06 13:06:18 +0000868 n1 = buf - BUF(v);
869 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000870 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000871 return v;
872}
873
Guido van Rossum0bd24411991-04-04 15:21:57 +0000874/* External C interface */
875
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000876PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000877PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000878{
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000879 PyObject *result;
880
Guido van Rossum3165fe61992-09-25 21:59:05 +0000881 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000882 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000883 return NULL;
884 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000885
886 if (PyFile_Check(f)) {
887 if (((PyFileObject*)f)->f_fp == NULL)
888 return err_closed();
889 result = get_line((PyFileObject *)f, n);
890 }
891 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000892 PyObject *reader;
893 PyObject *args;
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000894
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000895 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000896 if (reader == NULL)
897 return NULL;
898 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000899 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000900 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000901 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000902 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000903 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000904 return NULL;
905 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000906 result = PyEval_CallObject(reader, args);
907 Py_DECREF(reader);
908 Py_DECREF(args);
909 if (result != NULL && !PyString_Check(result)) {
910 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000911 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000912 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000913 "object.readline() returned non-string");
914 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000915 }
916
917 if (n < 0 && result != NULL && PyString_Check(result)) {
918 char *s = PyString_AS_STRING(result);
919 int len = PyString_GET_SIZE(result);
920 if (len == 0) {
921 Py_DECREF(result);
922 result = NULL;
923 PyErr_SetString(PyExc_EOFError,
924 "EOF when reading a line");
925 }
926 else if (s[len-1] == '\n') {
927 if (result->ob_refcnt == 1)
928 _PyString_Resize(&result, len-1);
929 else {
930 PyObject *v;
931 v = PyString_FromStringAndSize(s, len-1);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000932 Py_DECREF(result);
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000933 result = v;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000934 }
935 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000936 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +0000937 return result;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000938}
939
940/* Python method */
941
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000942static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000943file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000944{
Guido van Rossum789a1611997-05-10 22:33:55 +0000945 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000946
Guido van Rossumd7297e61992-07-06 14:19:26 +0000947 if (f->f_fp == NULL)
948 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000949 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000950 return NULL;
951 if (n == 0)
952 return PyString_FromString("");
953 if (n < 0)
954 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000955 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000956}
957
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000958static PyObject *
Martin v. Löwise3eb1f22001-08-16 13:15:00 +0000959file_xreadlines(PyFileObject *f)
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000960{
961 static PyObject* xreadlines_function = NULL;
Tim Petersf29b64d2001-01-15 06:33:19 +0000962
Guido van Rossume07d5cf2001-01-09 21:50:24 +0000963 if (!xreadlines_function) {
964 PyObject *xreadlines_module =
965 PyImport_ImportModule("xreadlines");
966 if(!xreadlines_module)
967 return NULL;
968
969 xreadlines_function = PyObject_GetAttrString(xreadlines_module,
970 "xreadlines");
971 Py_DECREF(xreadlines_module);
972 if(!xreadlines_function)
973 return NULL;
974 }
975 return PyObject_CallFunction(xreadlines_function, "(O)", f);
976}
977
978static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000979file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000980{
Guido van Rossum789a1611997-05-10 22:33:55 +0000981 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000982 PyObject *list;
983 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000984 char small_buffer[SMALLCHUNK];
985 char *buffer = small_buffer;
986 size_t buffersize = SMALLCHUNK;
987 PyObject *big_buffer = NULL;
988 size_t nfilled = 0;
989 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000990 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000991 char *p, *q, *end;
992 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000993
Guido van Rossumd7297e61992-07-06 14:19:26 +0000994 if (f->f_fp == NULL)
995 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000996 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000997 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000998 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000999 return NULL;
1000 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001001 Py_BEGIN_ALLOW_THREADS
1002 errno = 0;
1003 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
1004 Py_END_ALLOW_THREADS
1005 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +00001006 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +00001007 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +00001008 break;
1009 PyErr_SetFromErrno(PyExc_IOError);
1010 clearerr(f->f_fp);
1011 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001012 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +00001013 list = NULL;
1014 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001015 }
Guido van Rossum789a1611997-05-10 22:33:55 +00001016 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +00001017 p = memchr(buffer+nfilled, '\n', nread);
1018 if (p == NULL) {
1019 /* Need a larger buffer to fit this line */
1020 nfilled += nread;
1021 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +00001022 if (buffersize > INT_MAX) {
1023 PyErr_SetString(PyExc_OverflowError,
Guido van Rossume07d5cf2001-01-09 21:50:24 +00001024 "line is longer than a Python string can hold");
Trent Mickf29f47b2000-08-11 19:02:59 +00001025 goto error;
1026 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001027 if (big_buffer == NULL) {
1028 /* Create the big buffer */
1029 big_buffer = PyString_FromStringAndSize(
1030 NULL, buffersize);
1031 if (big_buffer == NULL)
1032 goto error;
1033 buffer = PyString_AS_STRING(big_buffer);
1034 memcpy(buffer, small_buffer, nfilled);
1035 }
1036 else {
1037 /* Grow the big buffer */
1038 _PyString_Resize(&big_buffer, buffersize);
1039 buffer = PyString_AS_STRING(big_buffer);
1040 }
1041 continue;
1042 }
1043 end = buffer+nfilled+nread;
1044 q = buffer;
1045 do {
1046 /* Process complete lines */
1047 p++;
1048 line = PyString_FromStringAndSize(q, p-q);
1049 if (line == NULL)
1050 goto error;
1051 err = PyList_Append(list, line);
1052 Py_DECREF(line);
1053 if (err != 0)
1054 goto error;
1055 q = p;
1056 p = memchr(q, '\n', end-q);
1057 } while (p != NULL);
1058 /* Move the remaining incomplete line to the start */
1059 nfilled = end-q;
1060 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +00001061 if (sizehint > 0)
1062 if (totalread >= (size_t)sizehint)
1063 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +00001064 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001065 if (nfilled != 0) {
1066 /* Partial last line */
1067 line = PyString_FromStringAndSize(buffer, nfilled);
1068 if (line == NULL)
1069 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +00001070 if (sizehint > 0) {
1071 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +00001072 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +00001073 if (rest == NULL) {
1074 Py_DECREF(line);
1075 goto error;
1076 }
1077 PyString_Concat(&line, rest);
1078 Py_DECREF(rest);
1079 if (line == NULL)
1080 goto error;
1081 }
Guido van Rossum6263d541997-05-10 22:07:25 +00001082 err = PyList_Append(list, line);
1083 Py_DECREF(line);
1084 if (err != 0)
1085 goto error;
1086 }
1087 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001088 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +00001089 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +00001090 }
Guido van Rossumce5ba841991-03-06 13:06:18 +00001091 return list;
1092}
1093
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001094static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001095file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001096{
Guido van Rossumd7297e61992-07-06 14:19:26 +00001097 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001098 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001099 if (f->f_fp == NULL)
1100 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +00001101 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001102 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001103 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001104 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001105 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +00001106 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001107 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001108 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001109 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +00001110 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001111 return NULL;
1112 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001113 Py_INCREF(Py_None);
1114 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001115}
1116
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001117static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001118file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001119{
Guido van Rossumee70ad12000-03-13 16:27:06 +00001120#define CHUNKSIZE 1000
1121 PyObject *list, *line;
1122 PyObject *result;
1123 int i, j, index, len, nwritten, islist;
1124
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001125 if (f->f_fp == NULL)
1126 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +00001127 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001128 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001129 "writelines() argument must be a sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001130 return NULL;
1131 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001132 islist = PyList_Check(args);
1133
1134 /* Strategy: slurp CHUNKSIZE lines into a private list,
1135 checking that they are all strings, then write that list
1136 without holding the interpreter lock, then come back for more. */
1137 index = 0;
1138 if (islist)
1139 list = NULL;
1140 else {
1141 list = PyList_New(CHUNKSIZE);
1142 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001143 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001144 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001145 result = NULL;
1146
1147 for (;;) {
1148 if (islist) {
1149 Py_XDECREF(list);
1150 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
1151 if (list == NULL)
1152 return NULL;
1153 j = PyList_GET_SIZE(list);
1154 }
1155 else {
1156 for (j = 0; j < CHUNKSIZE; j++) {
1157 line = PySequence_GetItem(args, index+j);
1158 if (line == NULL) {
1159 if (PyErr_ExceptionMatches(
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001160 PyExc_IndexError)) {
Guido van Rossumee70ad12000-03-13 16:27:06 +00001161 PyErr_Clear();
1162 break;
1163 }
1164 /* Some other error occurred.
1165 XXX We may lose some output. */
1166 goto error;
1167 }
Guido van Rossumee70ad12000-03-13 16:27:06 +00001168 PyList_SetItem(list, j, line);
1169 }
1170 }
1171 if (j == 0)
1172 break;
1173
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001174 /* Check that all entries are indeed strings. If not,
1175 apply the same rules as for file.write() and
1176 convert the results to strings. This is slow, but
1177 seems to be the only way since all conversion APIs
1178 could potentially execute Python code. */
1179 for (i = 0; i < j; i++) {
1180 PyObject *v = PyList_GET_ITEM(list, i);
1181 if (!PyString_Check(v)) {
1182 const char *buffer;
1183 int len;
Tim Peters86821b22001-01-07 21:19:34 +00001184 if (((f->f_binary &&
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001185 PyObject_AsReadBuffer(v,
1186 (const void**)&buffer,
1187 &len)) ||
1188 PyObject_AsCharBuffer(v,
1189 &buffer,
1190 &len))) {
1191 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001192 "writelines() argument must be a sequence of strings");
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001193 goto error;
1194 }
1195 line = PyString_FromStringAndSize(buffer,
1196 len);
1197 if (line == NULL)
1198 goto error;
1199 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001200 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001201 }
1202 }
1203
1204 /* Since we are releasing the global lock, the
1205 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001206 Py_BEGIN_ALLOW_THREADS
1207 f->f_softspace = 0;
1208 errno = 0;
1209 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001210 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001211 len = PyString_GET_SIZE(line);
1212 nwritten = fwrite(PyString_AS_STRING(line),
1213 1, len, f->f_fp);
1214 if (nwritten != len) {
1215 Py_BLOCK_THREADS
1216 PyErr_SetFromErrno(PyExc_IOError);
1217 clearerr(f->f_fp);
1218 goto error;
1219 }
1220 }
1221 Py_END_ALLOW_THREADS
1222
1223 if (j < CHUNKSIZE)
1224 break;
1225 index += CHUNKSIZE;
1226 }
1227
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001228 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001229 result = Py_None;
1230 error:
1231 Py_XDECREF(list);
1232 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001233}
1234
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001235static PyMethodDef file_methods[] = {
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001236 {"readline", (PyCFunction)file_readline, METH_VARARGS},
1237 {"read", (PyCFunction)file_read, METH_VARARGS},
1238 {"write", (PyCFunction)file_write, METH_OLDARGS},
1239 {"fileno", (PyCFunction)file_fileno, METH_NOARGS},
1240 {"seek", (PyCFunction)file_seek, METH_VARARGS},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001241#ifdef HAVE_FTRUNCATE
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001242 {"truncate", (PyCFunction)file_truncate, METH_VARARGS},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001243#endif
Martin v. Löwise3eb1f22001-08-16 13:15:00 +00001244 {"tell", (PyCFunction)file_tell, METH_NOARGS},
1245 {"readinto", (PyCFunction)file_readinto, METH_OLDARGS},
1246 {"readlines", (PyCFunction)file_readlines, METH_VARARGS},
1247 {"xreadlines", (PyCFunction)file_xreadlines, METH_NOARGS},
1248 {"writelines", (PyCFunction)file_writelines, METH_O},
1249 {"flush", (PyCFunction)file_flush, METH_NOARGS},
1250 {"close", (PyCFunction)file_close, METH_NOARGS},
1251 {"isatty", (PyCFunction)file_isatty, METH_NOARGS},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252 {NULL, NULL} /* sentinel */
1253};
1254
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001255#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001256
1257static struct memberlist file_memberlist[] = {
1258 {"softspace", T_INT, OFF(f_softspace)},
1259 {"mode", T_OBJECT, OFF(f_mode), RO},
1260 {"name", T_OBJECT, OFF(f_name), RO},
1261 /* getattr(f, "closed") is implemented without this table */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001262 {NULL} /* Sentinel */
1263};
1264
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001265static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00001266get_closed(PyFileObject *f, void *closure)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267{
Tim Peters6d6c1a32001-08-02 04:15:00 +00001268 return PyInt_FromLong((long)(f->f_fp == 0));
Guido van Rossumb6775db1994-08-01 11:34:53 +00001269}
1270
Tim Peters6d6c1a32001-08-02 04:15:00 +00001271static struct getsetlist file_getsetlist[] = {
1272 {"closed", (getter)get_closed, NULL, NULL},
1273 {0},
1274};
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275
Guido van Rossum65967252001-04-21 13:20:18 +00001276static PyObject *
Guido van Rossum5b021842001-05-22 16:48:37 +00001277file_getiter(PyObject *f)
Guido van Rossum65967252001-04-21 13:20:18 +00001278{
Guido van Rossum5b021842001-05-22 16:48:37 +00001279 return PyObject_CallMethod(f, "xreadlines", "");
Guido van Rossum65967252001-04-21 13:20:18 +00001280}
1281
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001282PyTypeObject PyFile_Type = {
1283 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001284 0,
1285 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001286 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001287 0,
Guido van Rossum65967252001-04-21 13:20:18 +00001288 (destructor)file_dealloc, /* tp_dealloc */
1289 0, /* tp_print */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001290 0, /* tp_getattr */
1291 0, /* tp_setattr */
Guido van Rossum65967252001-04-21 13:20:18 +00001292 0, /* tp_compare */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001293 (reprfunc)file_repr, /* tp_repr */
Guido van Rossum65967252001-04-21 13:20:18 +00001294 0, /* tp_as_number */
1295 0, /* tp_as_sequence */
1296 0, /* tp_as_mapping */
1297 0, /* tp_hash */
1298 0, /* tp_call */
1299 0, /* tp_str */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001300 PyObject_GenericGetAttr, /* tp_getattro */
Guido van Rossum65967252001-04-21 13:20:18 +00001301 0, /* tp_setattro */
1302 0, /* tp_as_buffer */
1303 Py_TPFLAGS_DEFAULT, /* tp_flags */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001304 0, /* tp_doc */
1305 0, /* tp_traverse */
1306 0, /* tp_clear */
Guido van Rossum65967252001-04-21 13:20:18 +00001307 0, /* tp_richcompare */
1308 0, /* tp_weaklistoffset */
Guido van Rossum5b021842001-05-22 16:48:37 +00001309 file_getiter, /* tp_iter */
Guido van Rossum213c7a62001-04-23 14:08:49 +00001310 0, /* tp_iternext */
Tim Peters6d6c1a32001-08-02 04:15:00 +00001311 file_methods, /* tp_methods */
1312 file_memberlist, /* tp_members */
1313 file_getsetlist, /* tp_getset */
1314 0, /* tp_base */
1315 0, /* tp_dict */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001316};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001317
1318/* Interface for the 'soft space' between print items. */
1319
1320int
Fred Drakefd99de62000-07-09 05:02:18 +00001321PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001322{
1323 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001324 if (f == NULL) {
1325 /* Do nothing */
1326 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001327 else if (PyFile_Check(f)) {
1328 oldflag = ((PyFileObject *)f)->f_softspace;
1329 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001330 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001331 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001332 PyObject *v;
1333 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001334 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001335 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001336 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001337 if (PyInt_Check(v))
1338 oldflag = PyInt_AsLong(v);
1339 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001340 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001341 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001342 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001343 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001344 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001345 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1346 PyErr_Clear();
1347 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001348 }
1349 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001350 return oldflag;
1351}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001352
1353/* Interfaces to write objects/strings to file-like objects */
1354
1355int
Fred Drakefd99de62000-07-09 05:02:18 +00001356PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001357{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001358 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001359 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001360 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001361 return -1;
1362 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001363 else if (PyFile_Check(f)) {
1364 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001365 if (fp == NULL) {
1366 err_closed();
1367 return -1;
1368 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001369 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001370 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001371 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001372 if (writer == NULL)
1373 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001374 if (flags & Py_PRINT_RAW)
1375 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001376 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001377 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001378 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001379 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001380 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001381 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001382 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001383 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001384 Py_DECREF(value);
1385 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001386 return -1;
1387 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001388 result = PyEval_CallObject(writer, args);
1389 Py_DECREF(args);
1390 Py_DECREF(value);
1391 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001392 if (result == NULL)
1393 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001394 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001395 return 0;
1396}
1397
Guido van Rossum27a60b11997-05-22 22:25:11 +00001398int
Fred Drakefd99de62000-07-09 05:02:18 +00001399PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001400{
1401 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001402 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001403 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001404 PyErr_SetString(PyExc_SystemError,
1405 "null file for PyFile_WriteString");
1406 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001407 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001408 else if (PyFile_Check(f)) {
1409 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001410 if (fp == NULL) {
1411 err_closed();
1412 return -1;
1413 }
1414 fputs(s, fp);
1415 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001416 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001417 else if (!PyErr_Occurred()) {
1418 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001419 int err;
1420 if (v == NULL)
1421 return -1;
1422 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1423 Py_DECREF(v);
1424 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001425 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001426 else
1427 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001428}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001429
1430/* Try to get a file-descriptor from a Python object. If the object
1431 is an integer or long integer, its value is returned. If not, the
1432 object's fileno() method is called if it exists; the method must return
1433 an integer or long integer, which is returned as the file descriptor value.
1434 -1 is returned on failure.
1435*/
1436
1437int PyObject_AsFileDescriptor(PyObject *o)
1438{
1439 int fd;
1440 PyObject *meth;
1441
1442 if (PyInt_Check(o)) {
1443 fd = PyInt_AsLong(o);
1444 }
1445 else if (PyLong_Check(o)) {
1446 fd = PyLong_AsLong(o);
1447 }
1448 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1449 {
1450 PyObject *fno = PyEval_CallObject(meth, NULL);
1451 Py_DECREF(meth);
1452 if (fno == NULL)
1453 return -1;
Tim Peters86821b22001-01-07 21:19:34 +00001454
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001455 if (PyInt_Check(fno)) {
1456 fd = PyInt_AsLong(fno);
1457 Py_DECREF(fno);
1458 }
1459 else if (PyLong_Check(fno)) {
1460 fd = PyLong_AsLong(fno);
1461 Py_DECREF(fno);
1462 }
1463 else {
1464 PyErr_SetString(PyExc_TypeError,
1465 "fileno() returned a non-integer");
1466 Py_DECREF(fno);
1467 return -1;
1468 }
1469 }
1470 else {
1471 PyErr_SetString(PyExc_TypeError,
1472 "argument must be an int, or have a fileno() method.");
1473 return -1;
1474 }
1475
1476 if (fd < 0) {
1477 PyErr_Format(PyExc_ValueError,
1478 "file descriptor cannot be a negative integer (%i)",
1479 fd);
1480 return -1;
1481 }
1482 return fd;
1483}