blob: 88e60275dfaab21813769718e0e4b699a981da67 [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
Jack Jansene9791602000-08-22 21:51:22 +00007#ifdef HAVE_LIMITS_H
8#include <limits.h>
9#endif
10
Guido van Rossumff7e83d1999-08-27 20:39:37 +000011#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum41498431999-01-07 22:09:51 +000012#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000013#endif /* DONT_HAVE_SYS_TYPES_H */
Guido van Rossum41498431999-01-07 22:09:51 +000014
Guido van Rossumeceebb82000-06-28 20:57:07 +000015/* We expect that fstat exists on most systems.
16 It's confirmed on Unix, Mac and Windows.
17 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
18#ifndef DONT_HAVE_FSTAT
19#define HAVE_FSTAT
20
21#ifndef DONT_HAVE_SYS_TYPES_H
22#include <sys/types.h>
23#endif
24
25#ifndef DONT_HAVE_SYS_STAT_H
26#include <sys/stat.h>
27#else
28#ifdef HAVE_STAT_H
29#include <stat.h>
30#endif
31#endif
32
33#endif /* DONT_HAVE_FSTAT */
34
Guido van Rossum685a38e1996-12-05 21:54:17 +000035#ifdef HAVE_UNISTD_H
36#include <unistd.h>
37#endif
38
Guido van Rossumb8199141997-05-06 15:23:24 +000039#ifdef MS_WIN32
Guido van Rossumb8199141997-05-06 15:23:24 +000040#define fileno _fileno
Trent Mickf29f47b2000-08-11 19:02:59 +000041/* can (almost fully) duplicate with _chsize, see file_truncate */
Guido van Rossumb8199141997-05-06 15:23:24 +000042#define HAVE_FTRUNCATE
43#endif
44
Guido van Rossumf2044e11998-04-28 16:05:59 +000045#ifdef macintosh
46#ifdef USE_GUSI
47#define HAVE_FTRUNCATE
48#endif
49#endif
50
Jack Jansene08dea191995-04-23 22:12:47 +000051#ifdef __MWERKS__
52/* Mwerks fopen() doesn't always set errno */
53#define NO_FOPEN_ERRNO
54#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000055
Guido van Rossumc0b618a1997-05-02 03:12:38 +000056#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000057
Guido van Rossumff7e83d1999-08-27 20:39:37 +000058#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000059#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000060#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061
Trent Mickf29f47b2000-08-11 19:02:59 +000062/* define the appropriate 64-bit capable tell() function */
Guido van Rossum1a5e5832000-09-21 22:15:29 +000063#if defined(MS_WIN64)
64#define TELL64 _telli64
65#elif defined(__NetBSD__) || defined(__OpenBSD__)
66/* NOTE: this is only used on older
67 NetBSD prior to f*o() funcions */
68#define TELL64(fd) lseek((fd),0,SEEK_CUR)
Trent Mickf29f47b2000-08-11 19:02:59 +000069#endif
70
71
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000072typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000073 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000075 PyObject *f_name;
76 PyObject *f_mode;
Tim Petersdbd9ba62000-07-09 03:09:57 +000077 int (*f_close)(FILE *);
Guido van Rossumeb183da1991-04-04 10:44:06 +000078 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000079 int f_binary; /* Flag which indicates whether the file is open
80 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000081} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082
83FILE *
Fred Drakefd99de62000-07-09 05:02:18 +000084PyFile_AsFile(PyObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000086 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000088 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000089 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090}
91
Guido van Rossumc0b618a1997-05-02 03:12:38 +000092PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000093PyFile_Name(PyObject *f)
Guido van Rossumdb3165e1993-10-18 17:06:59 +000094{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000095 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000096 return NULL;
97 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000098 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000099}
100
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000101PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000102PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000104 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105 if (f == NULL)
106 return NULL;
107 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000108 f->f_name = PyString_FromString(name);
109 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000110 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000111 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +0000112 if (strchr(mode,'b') != NULL)
113 f->f_binary = 1;
114 else
115 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000117 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 return NULL;
119 }
120 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000121 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122}
123
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000124PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000125PyFile_FromString(char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000126{
Tim Petersdbd9ba62000-07-09 03:09:57 +0000127 extern int fclose(FILE *);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000128 PyFileObject *f;
129 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 if (f == NULL)
131 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000132#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000133 if (*mode == '*') {
134 FILE *fopenRF();
135 f->f_fp = fopenRF(name, mode+1);
136 }
137 else
138#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000139 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000140 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000141 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000142 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000143 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000144 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000145#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000146 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000147 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000148 PyErr_SetString(PyExc_IOError, "Cannot open file");
149 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000150 return NULL;
151 }
152#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000153 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000154 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 return NULL;
156 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000157 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158}
159
Guido van Rossumb6775db1994-08-01 11:34:53 +0000160void
Fred Drakefd99de62000-07-09 05:02:18 +0000161PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162{
163 if (bufsize >= 0) {
164#ifdef HAVE_SETVBUF
165 int type;
166 switch (bufsize) {
167 case 0:
168 type = _IONBF;
169 break;
170 case 1:
171 type = _IOLBF;
172 bufsize = BUFSIZ;
173 break;
174 default:
175 type = _IOFBF;
176 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000177 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
178 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000179#else /* !HAVE_SETVBUF */
180 if (bufsize <= 1)
181 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
182#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183 }
184}
185
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000186static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000187err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000188{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000189 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000190 return NULL;
191}
192
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193/* Methods */
194
195static void
Fred Drakefd99de62000-07-09 05:02:18 +0000196file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000198 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000199 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000200 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000201 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000202 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000203 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000205 }
206 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000207 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000208 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000209 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210}
211
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000212static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000213file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214{
215 char buf[300];
Fred Drakea44d3532000-06-30 15:01:00 +0000216 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000218 PyString_AsString(f->f_name),
219 PyString_AsString(f->f_mode),
Fred Drakea44d3532000-06-30 15:01:00 +0000220 f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222}
223
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000225file_close(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000227 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000231 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000232 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000233 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000234 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000236 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237 f->f_fp = NULL;
238 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000239 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000241 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000242 return PyInt_FromLong((long)sts);
243 Py_INCREF(Py_None);
244 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245}
246
Trent Mickf29f47b2000-08-11 19:02:59 +0000247
248/* a portable fseek() function
249 return 0 on success, non-zero on failure (with errno set) */
250int
Trent Mickf29f47b2000-08-11 19:02:59 +0000251#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Fred Drake8ce159a2000-08-31 05:18:54 +0000252_portable_fseek(FILE *fp, fpos_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000253#else
Fred Drake8ce159a2000-08-31 05:18:54 +0000254_portable_fseek(FILE *fp, off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000255#endif
Trent Mickf29f47b2000-08-11 19:02:59 +0000256{
257#if defined(HAVE_FSEEKO)
258 return fseeko(fp, offset, whence);
259#elif defined(HAVE_FSEEK64)
260 return fseek64(fp, offset, whence);
261#elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
262 /* lacking a 64-bit capable fseek() (as Win64 does) use a 64-bit capable
263 fsetpos() and tell() to implement fseek()*/
264 fpos_t pos;
265 switch (whence) {
266 case SEEK_CUR:
267 if (fgetpos(fp, &pos) != 0)
268 return -1;
269 offset += pos;
270 break;
271 case SEEK_END:
272 /* do a "no-op" seek first to sync the buffering so that
273 the low-level tell() can be used correctly */
274 if (fseek(fp, 0, SEEK_END) != 0)
275 return -1;
276 if ((pos = TELL64(fileno(fp))) == -1L)
277 return -1;
278 offset += pos;
279 break;
280 /* case SEEK_SET: break; */
281 }
282 return fsetpos(fp, &offset);
283#else
284 return fseek(fp, offset, whence);
285#endif
286}
287
288
289/* a portable ftell() function
290 Return -1 on failure with errno set appropriately, current file
291 position on success */
292#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
293fpos_t
294#else
295off_t
296#endif
Fred Drake8ce159a2000-08-31 05:18:54 +0000297_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000298{
299#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
300 return ftello(fp);
301#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
302 return ftell64(fp);
303#elif SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT)
304 fpos_t pos;
305 if (fgetpos(fp, &pos) != 0)
306 return -1;
307 return pos;
308#else
309 return ftell(fp);
310#endif
311}
312
313
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000314static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000315file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000317 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000318 int ret;
Trent Mickf29f47b2000-08-11 19:02:59 +0000319#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
320 fpos_t offset, pos;
321#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000322 off_t offset;
Trent Mickf29f47b2000-08-11 19:02:59 +0000323#endif /* !MS_WIN64 */
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000324 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000325
Guido van Rossumd7297e61992-07-06 14:19:26 +0000326 if (f->f_fp == NULL)
327 return err_closed();
328 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000329 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000330 return NULL;
331#if !defined(HAVE_LARGEFILE_SUPPORT)
332 offset = PyInt_AsLong(offobj);
333#else
334 offset = PyLong_Check(offobj) ?
335 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
336#endif
337 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000338 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000339
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000341 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000342 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000343 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000344
Guido van Rossumff4949e1992-08-05 19:58:53 +0000345 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000347 clearerr(f->f_fp);
348 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000349 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000350 Py_INCREF(Py_None);
351 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000352}
353
Trent Mickf29f47b2000-08-11 19:02:59 +0000354
Guido van Rossumd7047b31995-01-02 19:07:15 +0000355#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000357file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000358{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000359 int ret;
Trent Mickf29f47b2000-08-11 19:02:59 +0000360#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
361 fpos_t newsize;
362#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000363 off_t newsize;
Trent Mickf29f47b2000-08-11 19:02:59 +0000364#endif
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000365 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000366
367 if (f->f_fp == NULL)
368 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000369 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000370 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000371 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000372 if (newsizeobj != NULL) {
373#if !defined(HAVE_LARGEFILE_SUPPORT)
374 newsize = PyInt_AsLong(newsizeobj);
375#else
376 newsize = PyLong_Check(newsizeobj) ?
377 PyLong_AsLongLong(newsizeobj) :
378 PyInt_AsLong(newsizeobj);
379#endif
380 if (PyErr_Occurred())
381 return NULL;
382 } else {
383 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000384 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000385 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000386 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000387 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000388 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000390 clearerr(f->f_fp);
391 return NULL;
392 }
393 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000394 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000395 errno = 0;
396 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000397 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000398 if (ret != 0) goto onioerror;
399
400#ifdef MS_WIN32
401 /* can use _chsize; if, however, the newsize overflows 32-bits then
402 _chsize is *not* adequate; in this case, an OverflowError is raised */
403 if (newsize > LONG_MAX) {
404 PyErr_SetString(PyExc_OverflowError,
405 "the new size is too long for _chsize (it is limited to 32-bit values)");
Guido van Rossumd7047b31995-01-02 19:07:15 +0000406 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000407 } else {
408 Py_BEGIN_ALLOW_THREADS
409 errno = 0;
410 ret = _chsize(fileno(f->f_fp), newsize);
411 Py_END_ALLOW_THREADS
412 if (ret != 0) goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000413 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000414#else
415 Py_BEGIN_ALLOW_THREADS
416 errno = 0;
417 ret = ftruncate(fileno(f->f_fp), newsize);
418 Py_END_ALLOW_THREADS
419 if (ret != 0) goto onioerror;
420#endif /* !MS_WIN32 */
421
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 Py_INCREF(Py_None);
423 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000424
425onioerror:
426 PyErr_SetFromErrno(PyExc_IOError);
427 clearerr(f->f_fp);
428 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000429}
430#endif /* HAVE_FTRUNCATE */
431
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000433file_tell(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000434{
Trent Mickf29f47b2000-08-11 19:02:59 +0000435#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
436 fpos_t pos;
437#else
438 off_t pos;
439#endif
440
Guido van Rossumd7297e61992-07-06 14:19:26 +0000441 if (f->f_fp == NULL)
442 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000443 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000445 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000446 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000447 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000448 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000449 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000450 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000451 clearerr(f->f_fp);
452 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000453 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000454#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000455 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000456#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000457 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000458#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000459}
460
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000461static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000462file_fileno(PyFileObject *f, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000463{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000464 if (f->f_fp == NULL)
465 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000466 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000467 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000468 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000469}
470
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000471static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000472file_flush(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000473{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000474 int res;
475
Guido van Rossumd7297e61992-07-06 14:19:26 +0000476 if (f->f_fp == NULL)
477 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000478 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000480 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000481 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000482 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000483 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000484 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000486 clearerr(f->f_fp);
487 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000488 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489 Py_INCREF(Py_None);
490 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000491}
492
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000493static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000494file_isatty(PyFileObject *f, PyObject *args)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000495{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000496 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000497 if (f->f_fp == NULL)
498 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000499 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000500 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000501 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000502 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000503 Py_END_ALLOW_THREADS
504 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000505}
506
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000507
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000508#if BUFSIZ < 8192
509#define SMALLCHUNK 8192
510#else
511#define SMALLCHUNK BUFSIZ
512#endif
513
Guido van Rossum3c259041999-01-14 19:00:14 +0000514#if SIZEOF_INT < 4
515#define BIGCHUNK (512 * 32)
516#else
517#define BIGCHUNK (512 * 1024)
518#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000519
520static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000521new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000522{
523#ifdef HAVE_FSTAT
524 long pos, end;
525 struct stat st;
526 if (fstat(fileno(f->f_fp), &st) == 0) {
527 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000528 /* The following is not a bug: we really need to call lseek()
529 *and* ftell(). The reason is that some stdio libraries
530 mistakenly flush their buffer when ftell() is called and
531 the lseek() call it makes fails, thereby throwing away
532 data that cannot be recovered in any way. To avoid this,
533 we first test lseek(), and only call ftell() if lseek()
534 works. We can't use the lseek() value either, because we
535 need to take the amount of buffered data into account.
536 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000537 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
538 if (pos >= 0)
539 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000540 if (pos < 0)
541 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000542 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000543 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000544 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000545 }
546#endif
547 if (currentsize > SMALLCHUNK) {
548 /* Keep doubling until we reach BIGCHUNK;
549 then keep adding BIGCHUNK. */
550 if (currentsize <= BIGCHUNK)
551 return currentsize + currentsize;
552 else
553 return currentsize + BIGCHUNK;
554 }
555 return currentsize + SMALLCHUNK;
556}
557
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000558static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000559file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000560{
Guido van Rossum789a1611997-05-10 22:33:55 +0000561 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000562 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000563 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000564
Guido van Rossumd7297e61992-07-06 14:19:26 +0000565 if (f->f_fp == NULL)
566 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000567 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000568 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000569 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000570 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000571 else
572 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000573 if (buffersize > INT_MAX) {
574 PyErr_SetString(PyExc_OverflowError,
575 "requested number of bytes is more than a Python string can hold");
576 return NULL;
577 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000578 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000579 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000580 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000581 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000582 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000583 Py_BEGIN_ALLOW_THREADS
584 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000585 chunksize = fread(BUF(v) + bytesread, 1,
586 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000587 Py_END_ALLOW_THREADS
588 if (chunksize == 0) {
589 if (!ferror(f->f_fp))
590 break;
591 PyErr_SetFromErrno(PyExc_IOError);
592 clearerr(f->f_fp);
593 Py_DECREF(v);
594 return NULL;
595 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000596 bytesread += chunksize;
597 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000598 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000599 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000600 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000601 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000602 return NULL;
603 }
604 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000605 if (bytesread != buffersize)
606 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000607 return v;
608}
609
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000610static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000611file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000612{
613 char *ptr;
Trent Mickf29f47b2000-08-11 19:02:59 +0000614 size_t ntodo, ndone, nnow;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000615
616 if (f->f_fp == NULL)
617 return err_closed();
618 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
619 return NULL;
620 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000621 while (ntodo > 0) {
622 Py_BEGIN_ALLOW_THREADS
623 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000624 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000625 Py_END_ALLOW_THREADS
626 if (nnow == 0) {
627 if (!ferror(f->f_fp))
628 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000629 PyErr_SetFromErrno(PyExc_IOError);
630 clearerr(f->f_fp);
631 return NULL;
632 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000633 ndone += nnow;
634 ntodo -= nnow;
635 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000636 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000637}
638
639
Guido van Rossum0bd24411991-04-04 15:21:57 +0000640/* Internal routine to get a line.
641 Size argument interpretation:
642 > 0: max length;
643 = 0: read arbitrary line;
644 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000645*/
646
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000647static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000648get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000649{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000650 register FILE *fp;
651 register int c;
652 register char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000653 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000655
Guido van Rossumc10aa771992-07-31 12:42:38 +0000656 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000657 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000658 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000659 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000660 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000661 buf = BUF(v);
662 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000663
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000664 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000665 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000666 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000667 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000668 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000670 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000671 return NULL;
672 }
673 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000674 Py_DECREF(v);
675 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000676 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000677 return NULL;
678 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000679 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000680 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000681 }
682 if ((*buf++ = c) == '\n') {
683 if (n < 0)
684 buf--;
685 break;
686 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000687 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000688 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000689 break;
690 n1 = n2;
691 n2 += 1000;
Trent Mickf29f47b2000-08-11 19:02:59 +0000692 if (n2 > INT_MAX) {
693 PyErr_SetString(PyExc_OverflowError,
694 "line is longer than a Python string can hold");
695 return NULL;
696 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000697 Py_BLOCK_THREADS
698 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000699 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000700 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000701 buf = BUF(v) + n1;
702 end = BUF(v) + n2;
703 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000705 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000706
Guido van Rossumce5ba841991-03-06 13:06:18 +0000707 n1 = buf - BUF(v);
708 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000709 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000710 return v;
711}
712
Guido van Rossum0bd24411991-04-04 15:21:57 +0000713/* External C interface */
714
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000715PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000716PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000717{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000718 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000719 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000720 return NULL;
721 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000722 if (!PyFile_Check(f)) {
723 PyObject *reader;
724 PyObject *args;
725 PyObject *result;
726 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000727 if (reader == NULL)
728 return NULL;
729 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000730 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000731 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000732 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000733 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000734 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000735 return NULL;
736 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000737 result = PyEval_CallObject(reader, args);
738 Py_DECREF(reader);
739 Py_DECREF(args);
740 if (result != NULL && !PyString_Check(result)) {
741 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000742 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000743 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000744 "object.readline() returned non-string");
745 }
746 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000747 char *s = PyString_AsString(result);
748 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000749 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000750 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000751 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000752 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000753 "EOF when reading a line");
754 }
755 else if (s[len-1] == '\n') {
756 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000757 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000758 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000759 PyObject *v;
760 v = PyString_FromStringAndSize(s,
761 len-1);
762 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000763 result = v;
764 }
765 }
766 }
767 return result;
768 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000769 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000770 return err_closed();
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000771 return get_line((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000772}
773
774/* Python method */
775
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000776static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000777file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000778{
Guido van Rossum789a1611997-05-10 22:33:55 +0000779 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000780
Guido van Rossumd7297e61992-07-06 14:19:26 +0000781 if (f->f_fp == NULL)
782 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000783 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000784 return NULL;
785 if (n == 0)
786 return PyString_FromString("");
787 if (n < 0)
788 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000789 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000790}
791
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000792static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000793file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000794{
Guido van Rossum789a1611997-05-10 22:33:55 +0000795 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000796 PyObject *list;
797 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000798 char small_buffer[SMALLCHUNK];
799 char *buffer = small_buffer;
800 size_t buffersize = SMALLCHUNK;
801 PyObject *big_buffer = NULL;
802 size_t nfilled = 0;
803 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000804 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000805 char *p, *q, *end;
806 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000807
Guido van Rossumd7297e61992-07-06 14:19:26 +0000808 if (f->f_fp == NULL)
809 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000810 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000811 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000812 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000813 return NULL;
814 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000815 Py_BEGIN_ALLOW_THREADS
816 errno = 0;
817 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
818 Py_END_ALLOW_THREADS
819 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000820 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000821 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000822 break;
823 PyErr_SetFromErrno(PyExc_IOError);
824 clearerr(f->f_fp);
825 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000826 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000827 list = NULL;
828 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000829 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000830 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000831 p = memchr(buffer+nfilled, '\n', nread);
832 if (p == NULL) {
833 /* Need a larger buffer to fit this line */
834 nfilled += nread;
835 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +0000836 if (buffersize > INT_MAX) {
837 PyErr_SetString(PyExc_OverflowError,
838 "line is too long for a Python string");
839 goto error;
840 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000841 if (big_buffer == NULL) {
842 /* Create the big buffer */
843 big_buffer = PyString_FromStringAndSize(
844 NULL, buffersize);
845 if (big_buffer == NULL)
846 goto error;
847 buffer = PyString_AS_STRING(big_buffer);
848 memcpy(buffer, small_buffer, nfilled);
849 }
850 else {
851 /* Grow the big buffer */
852 _PyString_Resize(&big_buffer, buffersize);
853 buffer = PyString_AS_STRING(big_buffer);
854 }
855 continue;
856 }
857 end = buffer+nfilled+nread;
858 q = buffer;
859 do {
860 /* Process complete lines */
861 p++;
862 line = PyString_FromStringAndSize(q, p-q);
863 if (line == NULL)
864 goto error;
865 err = PyList_Append(list, line);
866 Py_DECREF(line);
867 if (err != 0)
868 goto error;
869 q = p;
870 p = memchr(q, '\n', end-q);
871 } while (p != NULL);
872 /* Move the remaining incomplete line to the start */
873 nfilled = end-q;
874 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000875 if (sizehint > 0)
876 if (totalread >= (size_t)sizehint)
877 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000878 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000879 if (nfilled != 0) {
880 /* Partial last line */
881 line = PyString_FromStringAndSize(buffer, nfilled);
882 if (line == NULL)
883 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000884 if (sizehint > 0) {
885 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000886 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +0000887 if (rest == NULL) {
888 Py_DECREF(line);
889 goto error;
890 }
891 PyString_Concat(&line, rest);
892 Py_DECREF(rest);
893 if (line == NULL)
894 goto error;
895 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000896 err = PyList_Append(list, line);
897 Py_DECREF(line);
898 if (err != 0)
899 goto error;
900 }
901 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000902 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000903 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000904 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000905 return list;
906}
907
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000908static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000909file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000910{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000911 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000912 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000913 if (f->f_fp == NULL)
914 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +0000915 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000916 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000917 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000918 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000919 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000920 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000921 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000922 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000923 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000924 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000925 return NULL;
926 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000927 Py_INCREF(Py_None);
928 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000929}
930
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000931static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000932file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000933{
Guido van Rossumee70ad12000-03-13 16:27:06 +0000934#define CHUNKSIZE 1000
935 PyObject *list, *line;
936 PyObject *result;
937 int i, j, index, len, nwritten, islist;
938
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000939 if (f->f_fp == NULL)
940 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +0000941 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000942 PyErr_SetString(PyExc_TypeError,
Guido van Rossumee70ad12000-03-13 16:27:06 +0000943 "writelines() requires sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000944 return NULL;
945 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000946 islist = PyList_Check(args);
947
948 /* Strategy: slurp CHUNKSIZE lines into a private list,
949 checking that they are all strings, then write that list
950 without holding the interpreter lock, then come back for more. */
951 index = 0;
952 if (islist)
953 list = NULL;
954 else {
955 list = PyList_New(CHUNKSIZE);
956 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000957 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000958 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000959 result = NULL;
960
961 for (;;) {
962 if (islist) {
963 Py_XDECREF(list);
964 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
965 if (list == NULL)
966 return NULL;
967 j = PyList_GET_SIZE(list);
968 }
969 else {
970 for (j = 0; j < CHUNKSIZE; j++) {
971 line = PySequence_GetItem(args, index+j);
972 if (line == NULL) {
973 if (PyErr_ExceptionMatches(
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +0000974 PyExc_IndexError)) {
Guido van Rossumee70ad12000-03-13 16:27:06 +0000975 PyErr_Clear();
976 break;
977 }
978 /* Some other error occurred.
979 XXX We may lose some output. */
980 goto error;
981 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000982 PyList_SetItem(list, j, line);
983 }
984 }
985 if (j == 0)
986 break;
987
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +0000988 /* Check that all entries are indeed strings. If not,
989 apply the same rules as for file.write() and
990 convert the results to strings. This is slow, but
991 seems to be the only way since all conversion APIs
992 could potentially execute Python code. */
993 for (i = 0; i < j; i++) {
994 PyObject *v = PyList_GET_ITEM(list, i);
995 if (!PyString_Check(v)) {
996 const char *buffer;
997 int len;
998 if (((f->f_binary &&
999 PyObject_AsReadBuffer(v,
1000 (const void**)&buffer,
1001 &len)) ||
1002 PyObject_AsCharBuffer(v,
1003 &buffer,
1004 &len))) {
1005 PyErr_SetString(PyExc_TypeError,
1006 "writelines() requires sequences of strings");
1007 goto error;
1008 }
1009 line = PyString_FromStringAndSize(buffer,
1010 len);
1011 if (line == NULL)
1012 goto error;
1013 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001014 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001015 }
1016 }
1017
1018 /* Since we are releasing the global lock, the
1019 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001020 Py_BEGIN_ALLOW_THREADS
1021 f->f_softspace = 0;
1022 errno = 0;
1023 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001024 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001025 len = PyString_GET_SIZE(line);
1026 nwritten = fwrite(PyString_AS_STRING(line),
1027 1, len, f->f_fp);
1028 if (nwritten != len) {
1029 Py_BLOCK_THREADS
1030 PyErr_SetFromErrno(PyExc_IOError);
1031 clearerr(f->f_fp);
1032 goto error;
1033 }
1034 }
1035 Py_END_ALLOW_THREADS
1036
1037 if (j < CHUNKSIZE)
1038 break;
1039 index += CHUNKSIZE;
1040 }
1041
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001042 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001043 result = Py_None;
1044 error:
1045 Py_XDECREF(list);
1046 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001047}
1048
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001049static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +00001050 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001051 {"read", (PyCFunction)file_read, 1},
1052 {"write", (PyCFunction)file_write, 0},
1053 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +00001054 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001055#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +00001056 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001057#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001058 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001059 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001060 {"readlines", (PyCFunction)file_readlines, 1},
1061 {"writelines", (PyCFunction)file_writelines, 0},
1062 {"flush", (PyCFunction)file_flush, 0},
1063 {"close", (PyCFunction)file_close, 0},
1064 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001065 {NULL, NULL} /* sentinel */
1066};
1067
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001068#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001069
1070static struct memberlist file_memberlist[] = {
1071 {"softspace", T_INT, OFF(f_softspace)},
1072 {"mode", T_OBJECT, OFF(f_mode), RO},
1073 {"name", T_OBJECT, OFF(f_name), RO},
1074 /* getattr(f, "closed") is implemented without this table */
1075 {"closed", T_INT, 0, RO},
1076 {NULL} /* Sentinel */
1077};
1078
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001079static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001080file_getattr(PyFileObject *f, char *name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001081{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001082 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001083
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001084 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001085 if (res != NULL)
1086 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001087 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001088 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001089 return PyInt_FromLong((long)(f->f_fp == 0));
1090 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001091}
1092
1093static int
Fred Drakefd99de62000-07-09 05:02:18 +00001094file_setattr(PyFileObject *f, char *name, PyObject *v)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001095{
1096 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001097 PyErr_SetString(PyExc_AttributeError,
1098 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001099 return -1;
1100 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001101 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001102}
1103
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001104PyTypeObject PyFile_Type = {
1105 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001106 0,
1107 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001108 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001109 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001110 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001111 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001112 (getattrfunc)file_getattr, /*tp_getattr*/
1113 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001114 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001115 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001116};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001117
1118/* Interface for the 'soft space' between print items. */
1119
1120int
Fred Drakefd99de62000-07-09 05:02:18 +00001121PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001122{
1123 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001124 if (f == NULL) {
1125 /* Do nothing */
1126 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001127 else if (PyFile_Check(f)) {
1128 oldflag = ((PyFileObject *)f)->f_softspace;
1129 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001130 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001131 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001132 PyObject *v;
1133 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001134 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001135 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001136 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001137 if (PyInt_Check(v))
1138 oldflag = PyInt_AsLong(v);
1139 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001140 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001141 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001142 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001143 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001144 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001145 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1146 PyErr_Clear();
1147 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001148 }
1149 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001150 return oldflag;
1151}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001152
1153/* Interfaces to write objects/strings to file-like objects */
1154
1155int
Fred Drakefd99de62000-07-09 05:02:18 +00001156PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001157{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001158 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001159 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001160 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001161 return -1;
1162 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001163 else if (PyFile_Check(f)) {
1164 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001165 if (fp == NULL) {
1166 err_closed();
1167 return -1;
1168 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001169 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001170 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001171 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001172 if (writer == NULL)
1173 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001174 if (flags & Py_PRINT_RAW)
1175 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001176 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001177 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001178 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001179 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001180 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001181 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001182 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001183 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001184 Py_DECREF(value);
1185 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001186 return -1;
1187 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001188 result = PyEval_CallObject(writer, args);
1189 Py_DECREF(args);
1190 Py_DECREF(value);
1191 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001192 if (result == NULL)
1193 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001194 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001195 return 0;
1196}
1197
Guido van Rossum27a60b11997-05-22 22:25:11 +00001198int
Fred Drakefd99de62000-07-09 05:02:18 +00001199PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001200{
1201 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001202 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001203 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001204 PyErr_SetString(PyExc_SystemError,
1205 "null file for PyFile_WriteString");
1206 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001207 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001208 else if (PyFile_Check(f)) {
1209 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001210 if (fp == NULL) {
1211 err_closed();
1212 return -1;
1213 }
1214 fputs(s, fp);
1215 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001216 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001217 else if (!PyErr_Occurred()) {
1218 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001219 int err;
1220 if (v == NULL)
1221 return -1;
1222 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1223 Py_DECREF(v);
1224 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001225 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001226 else
1227 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001228}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001229
1230/* Try to get a file-descriptor from a Python object. If the object
1231 is an integer or long integer, its value is returned. If not, the
1232 object's fileno() method is called if it exists; the method must return
1233 an integer or long integer, which is returned as the file descriptor value.
1234 -1 is returned on failure.
1235*/
1236
1237int PyObject_AsFileDescriptor(PyObject *o)
1238{
1239 int fd;
1240 PyObject *meth;
1241
1242 if (PyInt_Check(o)) {
1243 fd = PyInt_AsLong(o);
1244 }
1245 else if (PyLong_Check(o)) {
1246 fd = PyLong_AsLong(o);
1247 }
1248 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1249 {
1250 PyObject *fno = PyEval_CallObject(meth, NULL);
1251 Py_DECREF(meth);
1252 if (fno == NULL)
1253 return -1;
1254
1255 if (PyInt_Check(fno)) {
1256 fd = PyInt_AsLong(fno);
1257 Py_DECREF(fno);
1258 }
1259 else if (PyLong_Check(fno)) {
1260 fd = PyLong_AsLong(fno);
1261 Py_DECREF(fno);
1262 }
1263 else {
1264 PyErr_SetString(PyExc_TypeError,
1265 "fileno() returned a non-integer");
1266 Py_DECREF(fno);
1267 return -1;
1268 }
1269 }
1270 else {
1271 PyErr_SetString(PyExc_TypeError,
1272 "argument must be an int, or have a fileno() method.");
1273 return -1;
1274 }
1275
1276 if (fd < 0) {
1277 PyErr_Format(PyExc_ValueError,
1278 "file descriptor cannot be a negative integer (%i)",
1279 fd);
1280 return -1;
1281 }
1282 return fd;
1283}
1284
1285
1286