blob: 6305520d145529c36cf931079788926e286db0cc [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* File object implementation */
12
Guido van Rossumc0b618a1997-05-02 03:12:38 +000013#include "Python.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000014#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000015
Jack Jansene9791602000-08-22 21:51:22 +000016#ifdef HAVE_LIMITS_H
17#include <limits.h>
18#endif
19
Guido van Rossumff7e83d1999-08-27 20:39:37 +000020#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum41498431999-01-07 22:09:51 +000021#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000022#endif /* DONT_HAVE_SYS_TYPES_H */
Guido van Rossum41498431999-01-07 22:09:51 +000023
Guido van Rossumeceebb82000-06-28 20:57:07 +000024/* We expect that fstat exists on most systems.
25 It's confirmed on Unix, Mac and Windows.
26 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
27#ifndef DONT_HAVE_FSTAT
28#define HAVE_FSTAT
29
30#ifndef DONT_HAVE_SYS_TYPES_H
31#include <sys/types.h>
32#endif
33
34#ifndef DONT_HAVE_SYS_STAT_H
35#include <sys/stat.h>
36#else
37#ifdef HAVE_STAT_H
38#include <stat.h>
39#endif
40#endif
41
42#endif /* DONT_HAVE_FSTAT */
43
Guido van Rossum685a38e1996-12-05 21:54:17 +000044#ifdef HAVE_UNISTD_H
45#include <unistd.h>
46#endif
47
Guido van Rossumb8199141997-05-06 15:23:24 +000048#ifdef MS_WIN32
Guido van Rossumb8199141997-05-06 15:23:24 +000049#define fileno _fileno
Trent Mickf29f47b2000-08-11 19:02:59 +000050/* can (almost fully) duplicate with _chsize, see file_truncate */
Guido van Rossumb8199141997-05-06 15:23:24 +000051#define HAVE_FTRUNCATE
52#endif
53
Guido van Rossumf2044e11998-04-28 16:05:59 +000054#ifdef macintosh
55#ifdef USE_GUSI
56#define HAVE_FTRUNCATE
57#endif
58#endif
59
Jack Jansene08dea191995-04-23 22:12:47 +000060#ifdef __MWERKS__
61/* Mwerks fopen() doesn't always set errno */
62#define NO_FOPEN_ERRNO
63#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000064
Guido van Rossumc0b618a1997-05-02 03:12:38 +000065#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000066
Guido van Rossumff7e83d1999-08-27 20:39:37 +000067#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000068#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000069#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070
Trent Mickf29f47b2000-08-11 19:02:59 +000071/* define the appropriate 64-bit capable tell() function */
72#ifdef MS_WIN64
73# define TELL64 _telli64
74#endif
75
76
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000078 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000080 PyObject *f_name;
81 PyObject *f_mode;
Tim Petersdbd9ba62000-07-09 03:09:57 +000082 int (*f_close)(FILE *);
Guido van Rossumeb183da1991-04-04 10:44:06 +000083 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000084 int f_binary; /* Flag which indicates whether the file is open
85 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000086} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087
88FILE *
Fred Drakefd99de62000-07-09 05:02:18 +000089PyFile_AsFile(PyObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000093 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000094 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095}
96
Guido van Rossumc0b618a1997-05-02 03:12:38 +000097PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000098PyFile_Name(PyObject *f)
Guido van Rossumdb3165e1993-10-18 17:06:59 +000099{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000100 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +0000101 return NULL;
102 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000103 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +0000104}
105
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000106PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000107PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 if (f == NULL)
111 return NULL;
112 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113 f->f_name = PyString_FromString(name);
114 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000115 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000116 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +0000117 if (strchr(mode,'b') != NULL)
118 f->f_binary = 1;
119 else
120 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000122 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123 return NULL;
124 }
125 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000126 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127}
128
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000129PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000130PyFile_FromString(char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131{
Tim Petersdbd9ba62000-07-09 03:09:57 +0000132 extern int fclose(FILE *);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000133 PyFileObject *f;
134 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 if (f == NULL)
136 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000137#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000138 if (*mode == '*') {
139 FILE *fopenRF();
140 f->f_fp = fopenRF(name, mode+1);
141 }
142 else
143#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000144 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000145 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000146 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000147 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000148 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000149 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000150#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000151 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000152 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000153 PyErr_SetString(PyExc_IOError, "Cannot open file");
154 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000155 return NULL;
156 }
157#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000158 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000159 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160 return NULL;
161 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000162 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163}
164
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165void
Fred Drakefd99de62000-07-09 05:02:18 +0000166PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000167{
168 if (bufsize >= 0) {
169#ifdef HAVE_SETVBUF
170 int type;
171 switch (bufsize) {
172 case 0:
173 type = _IONBF;
174 break;
175 case 1:
176 type = _IOLBF;
177 bufsize = BUFSIZ;
178 break;
179 default:
180 type = _IOFBF;
181 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000182 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
183 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000184#else /* !HAVE_SETVBUF */
185 if (bufsize <= 1)
186 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
187#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000188 }
189}
190
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000191static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000192err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000193{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000194 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000195 return NULL;
196}
197
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198/* Methods */
199
200static void
Fred Drakefd99de62000-07-09 05:02:18 +0000201file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000203 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000204 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000205 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000206 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000207 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000208 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000209 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000210 }
211 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000212 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000213 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000214 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215}
216
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000217static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000218file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219{
220 char buf[300];
Fred Drakea44d3532000-06-30 15:01:00 +0000221 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000223 PyString_AsString(f->f_name),
224 PyString_AsString(f->f_mode),
Fred Drakea44d3532000-06-30 15:01:00 +0000225 f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000226 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227}
228
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000229static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000230file_close(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000232 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000236 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000238 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000239 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000241 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242 f->f_fp = NULL;
243 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000244 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000245 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000246 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000247 return PyInt_FromLong((long)sts);
248 Py_INCREF(Py_None);
249 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250}
251
Trent Mickf29f47b2000-08-11 19:02:59 +0000252
253/* a portable fseek() function
254 return 0 on success, non-zero on failure (with errno set) */
255int
Trent Mickf29f47b2000-08-11 19:02:59 +0000256#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Fred Drake8ce159a2000-08-31 05:18:54 +0000257_portable_fseek(FILE *fp, fpos_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000258#else
Fred Drake8ce159a2000-08-31 05:18:54 +0000259_portable_fseek(FILE *fp, off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000260#endif
Trent Mickf29f47b2000-08-11 19:02:59 +0000261{
262#if defined(HAVE_FSEEKO)
263 return fseeko(fp, offset, whence);
264#elif defined(HAVE_FSEEK64)
265 return fseek64(fp, offset, whence);
266#elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
267 /* lacking a 64-bit capable fseek() (as Win64 does) use a 64-bit capable
268 fsetpos() and tell() to implement fseek()*/
269 fpos_t pos;
270 switch (whence) {
271 case SEEK_CUR:
272 if (fgetpos(fp, &pos) != 0)
273 return -1;
274 offset += pos;
275 break;
276 case SEEK_END:
277 /* do a "no-op" seek first to sync the buffering so that
278 the low-level tell() can be used correctly */
279 if (fseek(fp, 0, SEEK_END) != 0)
280 return -1;
281 if ((pos = TELL64(fileno(fp))) == -1L)
282 return -1;
283 offset += pos;
284 break;
285 /* case SEEK_SET: break; */
286 }
287 return fsetpos(fp, &offset);
288#else
289 return fseek(fp, offset, whence);
290#endif
291}
292
293
294/* a portable ftell() function
295 Return -1 on failure with errno set appropriately, current file
296 position on success */
297#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
298fpos_t
299#else
300off_t
301#endif
Fred Drake8ce159a2000-08-31 05:18:54 +0000302_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000303{
304#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
305 return ftello(fp);
306#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
307 return ftell64(fp);
308#elif SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT)
309 fpos_t pos;
310 if (fgetpos(fp, &pos) != 0)
311 return -1;
312 return pos;
313#else
314 return ftell(fp);
315#endif
316}
317
318
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000319static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000320file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000322 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000323 int ret;
Trent Mickf29f47b2000-08-11 19:02:59 +0000324#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
325 fpos_t offset, pos;
326#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000327 off_t offset;
Trent Mickf29f47b2000-08-11 19:02:59 +0000328#endif /* !MS_WIN64 */
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000329 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000330
Guido van Rossumd7297e61992-07-06 14:19:26 +0000331 if (f->f_fp == NULL)
332 return err_closed();
333 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000334 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000335 return NULL;
336#if !defined(HAVE_LARGEFILE_SUPPORT)
337 offset = PyInt_AsLong(offobj);
338#else
339 offset = PyLong_Check(offobj) ?
340 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
341#endif
342 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000343 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000344
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000345 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000346 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000347 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000348 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000349
Guido van Rossumff4949e1992-08-05 19:58:53 +0000350 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000351 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000352 clearerr(f->f_fp);
353 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000354 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 Py_INCREF(Py_None);
356 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000357}
358
Trent Mickf29f47b2000-08-11 19:02:59 +0000359
Guido van Rossumd7047b31995-01-02 19:07:15 +0000360#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000361static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000362file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000363{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000364 int ret;
Trent Mickf29f47b2000-08-11 19:02:59 +0000365#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
366 fpos_t newsize;
367#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000368 off_t newsize;
Trent Mickf29f47b2000-08-11 19:02:59 +0000369#endif
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000370 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000371
372 if (f->f_fp == NULL)
373 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000374 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000375 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000376 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000377 if (newsizeobj != NULL) {
378#if !defined(HAVE_LARGEFILE_SUPPORT)
379 newsize = PyInt_AsLong(newsizeobj);
380#else
381 newsize = PyLong_Check(newsizeobj) ?
382 PyLong_AsLongLong(newsizeobj) :
383 PyInt_AsLong(newsizeobj);
384#endif
385 if (PyErr_Occurred())
386 return NULL;
387 } else {
388 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000390 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000391 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000393 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000394 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000395 clearerr(f->f_fp);
396 return NULL;
397 }
398 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000399 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000400 errno = 0;
401 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000402 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000403 if (ret != 0) goto onioerror;
404
405#ifdef MS_WIN32
406 /* can use _chsize; if, however, the newsize overflows 32-bits then
407 _chsize is *not* adequate; in this case, an OverflowError is raised */
408 if (newsize > LONG_MAX) {
409 PyErr_SetString(PyExc_OverflowError,
410 "the new size is too long for _chsize (it is limited to 32-bit values)");
Guido van Rossumd7047b31995-01-02 19:07:15 +0000411 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000412 } else {
413 Py_BEGIN_ALLOW_THREADS
414 errno = 0;
415 ret = _chsize(fileno(f->f_fp), newsize);
416 Py_END_ALLOW_THREADS
417 if (ret != 0) goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000418 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000419#else
420 Py_BEGIN_ALLOW_THREADS
421 errno = 0;
422 ret = ftruncate(fileno(f->f_fp), newsize);
423 Py_END_ALLOW_THREADS
424 if (ret != 0) goto onioerror;
425#endif /* !MS_WIN32 */
426
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000427 Py_INCREF(Py_None);
428 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000429
430onioerror:
431 PyErr_SetFromErrno(PyExc_IOError);
432 clearerr(f->f_fp);
433 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000434}
435#endif /* HAVE_FTRUNCATE */
436
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000438file_tell(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000439{
Trent Mickf29f47b2000-08-11 19:02:59 +0000440#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
441 fpos_t pos;
442#else
443 off_t pos;
444#endif
445
Guido van Rossumd7297e61992-07-06 14:19:26 +0000446 if (f->f_fp == NULL)
447 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000448 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000449 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000450 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000451 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000452 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000453 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000454 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000455 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000456 clearerr(f->f_fp);
457 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000458 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000459#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000460 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000461#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000462 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000463#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000464}
465
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000466static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000467file_fileno(PyFileObject *f, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000468{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000469 if (f->f_fp == NULL)
470 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000471 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000472 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000473 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000474}
475
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000476static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000477file_flush(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000478{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000479 int res;
480
Guido van Rossumd7297e61992-07-06 14:19:26 +0000481 if (f->f_fp == NULL)
482 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000483 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000484 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000486 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000487 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000488 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000489 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000490 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000491 clearerr(f->f_fp);
492 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000493 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000494 Py_INCREF(Py_None);
495 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000496}
497
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000498static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000499file_isatty(PyFileObject *f, PyObject *args)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000500{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000501 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000502 if (f->f_fp == NULL)
503 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000504 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000505 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000506 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000507 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508 Py_END_ALLOW_THREADS
509 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000510}
511
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000512
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000513#if BUFSIZ < 8192
514#define SMALLCHUNK 8192
515#else
516#define SMALLCHUNK BUFSIZ
517#endif
518
Guido van Rossum3c259041999-01-14 19:00:14 +0000519#if SIZEOF_INT < 4
520#define BIGCHUNK (512 * 32)
521#else
522#define BIGCHUNK (512 * 1024)
523#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000524
525static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000526new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000527{
528#ifdef HAVE_FSTAT
529 long pos, end;
530 struct stat st;
531 if (fstat(fileno(f->f_fp), &st) == 0) {
532 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000533 /* The following is not a bug: we really need to call lseek()
534 *and* ftell(). The reason is that some stdio libraries
535 mistakenly flush their buffer when ftell() is called and
536 the lseek() call it makes fails, thereby throwing away
537 data that cannot be recovered in any way. To avoid this,
538 we first test lseek(), and only call ftell() if lseek()
539 works. We can't use the lseek() value either, because we
540 need to take the amount of buffered data into account.
541 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000542 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
543 if (pos >= 0)
544 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000545 if (pos < 0)
546 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000547 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000548 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000549 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000550 }
551#endif
552 if (currentsize > SMALLCHUNK) {
553 /* Keep doubling until we reach BIGCHUNK;
554 then keep adding BIGCHUNK. */
555 if (currentsize <= BIGCHUNK)
556 return currentsize + currentsize;
557 else
558 return currentsize + BIGCHUNK;
559 }
560 return currentsize + SMALLCHUNK;
561}
562
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000563static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000564file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000565{
Guido van Rossum789a1611997-05-10 22:33:55 +0000566 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000567 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000569
Guido van Rossumd7297e61992-07-06 14:19:26 +0000570 if (f->f_fp == NULL)
571 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000572 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000573 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000574 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000575 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000576 else
577 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000578 if (buffersize > INT_MAX) {
579 PyErr_SetString(PyExc_OverflowError,
580 "requested number of bytes is more than a Python string can hold");
581 return NULL;
582 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000583 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000584 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000585 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000586 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000587 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000588 Py_BEGIN_ALLOW_THREADS
589 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000590 chunksize = fread(BUF(v) + bytesread, 1,
591 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000592 Py_END_ALLOW_THREADS
593 if (chunksize == 0) {
594 if (!ferror(f->f_fp))
595 break;
596 PyErr_SetFromErrno(PyExc_IOError);
597 clearerr(f->f_fp);
598 Py_DECREF(v);
599 return NULL;
600 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000601 bytesread += chunksize;
602 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000603 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000604 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000605 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000606 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000607 return NULL;
608 }
609 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000610 if (bytesread != buffersize)
611 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612 return v;
613}
614
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000615static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000616file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000617{
618 char *ptr;
Trent Mickf29f47b2000-08-11 19:02:59 +0000619 size_t ntodo, ndone, nnow;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000620
621 if (f->f_fp == NULL)
622 return err_closed();
623 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
624 return NULL;
625 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000626 while (ntodo > 0) {
627 Py_BEGIN_ALLOW_THREADS
628 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000629 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000630 Py_END_ALLOW_THREADS
631 if (nnow == 0) {
632 if (!ferror(f->f_fp))
633 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000634 PyErr_SetFromErrno(PyExc_IOError);
635 clearerr(f->f_fp);
636 return NULL;
637 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000638 ndone += nnow;
639 ntodo -= nnow;
640 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000641 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000642}
643
644
Guido van Rossum0bd24411991-04-04 15:21:57 +0000645/* Internal routine to get a line.
646 Size argument interpretation:
647 > 0: max length;
648 = 0: read arbitrary line;
649 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000650*/
651
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000652static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000653get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000654{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000655 register FILE *fp;
656 register int c;
657 register char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000658 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000659 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000660
Guido van Rossumc10aa771992-07-31 12:42:38 +0000661 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000662 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000664 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000665 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000666 buf = BUF(v);
667 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000668
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000670 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000671 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000672 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000673 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000674 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000675 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000676 return NULL;
677 }
678 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000679 Py_DECREF(v);
680 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000681 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000682 return NULL;
683 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000684 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000685 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000686 }
687 if ((*buf++ = c) == '\n') {
688 if (n < 0)
689 buf--;
690 break;
691 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000692 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000693 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000694 break;
695 n1 = n2;
696 n2 += 1000;
Trent Mickf29f47b2000-08-11 19:02:59 +0000697 if (n2 > INT_MAX) {
698 PyErr_SetString(PyExc_OverflowError,
699 "line is longer than a Python string can hold");
700 return NULL;
701 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000702 Py_BLOCK_THREADS
703 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000704 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000705 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000706 buf = BUF(v) + n1;
707 end = BUF(v) + n2;
708 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000709 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000710 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000711
Guido van Rossumce5ba841991-03-06 13:06:18 +0000712 n1 = buf - BUF(v);
713 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000714 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000715 return v;
716}
717
Guido van Rossum0bd24411991-04-04 15:21:57 +0000718/* External C interface */
719
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000720PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000721PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000722{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000723 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000724 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000725 return NULL;
726 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000727 if (!PyFile_Check(f)) {
728 PyObject *reader;
729 PyObject *args;
730 PyObject *result;
731 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000732 if (reader == NULL)
733 return NULL;
734 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000735 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000736 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000737 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000738 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000739 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000740 return NULL;
741 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000742 result = PyEval_CallObject(reader, args);
743 Py_DECREF(reader);
744 Py_DECREF(args);
745 if (result != NULL && !PyString_Check(result)) {
746 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000747 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000748 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000749 "object.readline() returned non-string");
750 }
751 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000752 char *s = PyString_AsString(result);
753 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000754 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000755 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000756 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000757 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000758 "EOF when reading a line");
759 }
760 else if (s[len-1] == '\n') {
761 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000762 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000763 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000764 PyObject *v;
765 v = PyString_FromStringAndSize(s,
766 len-1);
767 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000768 result = v;
769 }
770 }
771 }
772 return result;
773 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000774 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000775 return err_closed();
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000776 return get_line((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000777}
778
779/* Python method */
780
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000781static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000782file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000783{
Guido van Rossum789a1611997-05-10 22:33:55 +0000784 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000785
Guido van Rossumd7297e61992-07-06 14:19:26 +0000786 if (f->f_fp == NULL)
787 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000788 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000789 return NULL;
790 if (n == 0)
791 return PyString_FromString("");
792 if (n < 0)
793 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000794 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000795}
796
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000797static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000798file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000799{
Guido van Rossum789a1611997-05-10 22:33:55 +0000800 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000801 PyObject *list;
802 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000803 char small_buffer[SMALLCHUNK];
804 char *buffer = small_buffer;
805 size_t buffersize = SMALLCHUNK;
806 PyObject *big_buffer = NULL;
807 size_t nfilled = 0;
808 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000809 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000810 char *p, *q, *end;
811 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000812
Guido van Rossumd7297e61992-07-06 14:19:26 +0000813 if (f->f_fp == NULL)
814 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000815 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000816 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000817 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000818 return NULL;
819 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000820 Py_BEGIN_ALLOW_THREADS
821 errno = 0;
822 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
823 Py_END_ALLOW_THREADS
824 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000825 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000826 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000827 break;
828 PyErr_SetFromErrno(PyExc_IOError);
829 clearerr(f->f_fp);
830 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000831 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000832 list = NULL;
833 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000834 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000835 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000836 p = memchr(buffer+nfilled, '\n', nread);
837 if (p == NULL) {
838 /* Need a larger buffer to fit this line */
839 nfilled += nread;
840 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +0000841 if (buffersize > INT_MAX) {
842 PyErr_SetString(PyExc_OverflowError,
843 "line is too long for a Python string");
844 goto error;
845 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000846 if (big_buffer == NULL) {
847 /* Create the big buffer */
848 big_buffer = PyString_FromStringAndSize(
849 NULL, buffersize);
850 if (big_buffer == NULL)
851 goto error;
852 buffer = PyString_AS_STRING(big_buffer);
853 memcpy(buffer, small_buffer, nfilled);
854 }
855 else {
856 /* Grow the big buffer */
857 _PyString_Resize(&big_buffer, buffersize);
858 buffer = PyString_AS_STRING(big_buffer);
859 }
860 continue;
861 }
862 end = buffer+nfilled+nread;
863 q = buffer;
864 do {
865 /* Process complete lines */
866 p++;
867 line = PyString_FromStringAndSize(q, p-q);
868 if (line == NULL)
869 goto error;
870 err = PyList_Append(list, line);
871 Py_DECREF(line);
872 if (err != 0)
873 goto error;
874 q = p;
875 p = memchr(q, '\n', end-q);
876 } while (p != NULL);
877 /* Move the remaining incomplete line to the start */
878 nfilled = end-q;
879 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000880 if (sizehint > 0)
881 if (totalread >= (size_t)sizehint)
882 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000883 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000884 if (nfilled != 0) {
885 /* Partial last line */
886 line = PyString_FromStringAndSize(buffer, nfilled);
887 if (line == NULL)
888 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000889 if (sizehint > 0) {
890 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000891 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +0000892 if (rest == NULL) {
893 Py_DECREF(line);
894 goto error;
895 }
896 PyString_Concat(&line, rest);
897 Py_DECREF(rest);
898 if (line == NULL)
899 goto error;
900 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000901 err = PyList_Append(list, line);
902 Py_DECREF(line);
903 if (err != 0)
904 goto error;
905 }
906 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000907 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000908 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000909 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000910 return list;
911}
912
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000913static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000914file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000915{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000916 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000917 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000918 if (f->f_fp == NULL)
919 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +0000920 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000921 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000922 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000923 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000924 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000925 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000926 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000927 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000928 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000929 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930 return NULL;
931 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000932 Py_INCREF(Py_None);
933 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000934}
935
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000936static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000937file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000938{
Guido van Rossumee70ad12000-03-13 16:27:06 +0000939#define CHUNKSIZE 1000
940 PyObject *list, *line;
941 PyObject *result;
942 int i, j, index, len, nwritten, islist;
943
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000944 if (f->f_fp == NULL)
945 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +0000946 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000947 PyErr_SetString(PyExc_TypeError,
Guido van Rossumee70ad12000-03-13 16:27:06 +0000948 "writelines() requires sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000949 return NULL;
950 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000951 islist = PyList_Check(args);
952
953 /* Strategy: slurp CHUNKSIZE lines into a private list,
954 checking that they are all strings, then write that list
955 without holding the interpreter lock, then come back for more. */
956 index = 0;
957 if (islist)
958 list = NULL;
959 else {
960 list = PyList_New(CHUNKSIZE);
961 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000962 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000963 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000964 result = NULL;
965
966 for (;;) {
967 if (islist) {
968 Py_XDECREF(list);
969 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
970 if (list == NULL)
971 return NULL;
972 j = PyList_GET_SIZE(list);
973 }
974 else {
975 for (j = 0; j < CHUNKSIZE; j++) {
976 line = PySequence_GetItem(args, index+j);
977 if (line == NULL) {
978 if (PyErr_ExceptionMatches(
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +0000979 PyExc_IndexError)) {
Guido van Rossumee70ad12000-03-13 16:27:06 +0000980 PyErr_Clear();
981 break;
982 }
983 /* Some other error occurred.
984 XXX We may lose some output. */
985 goto error;
986 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000987 PyList_SetItem(list, j, line);
988 }
989 }
990 if (j == 0)
991 break;
992
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +0000993 /* Check that all entries are indeed strings. If not,
994 apply the same rules as for file.write() and
995 convert the results to strings. This is slow, but
996 seems to be the only way since all conversion APIs
997 could potentially execute Python code. */
998 for (i = 0; i < j; i++) {
999 PyObject *v = PyList_GET_ITEM(list, i);
1000 if (!PyString_Check(v)) {
1001 const char *buffer;
1002 int len;
1003 if (((f->f_binary &&
1004 PyObject_AsReadBuffer(v,
1005 (const void**)&buffer,
1006 &len)) ||
1007 PyObject_AsCharBuffer(v,
1008 &buffer,
1009 &len))) {
1010 PyErr_SetString(PyExc_TypeError,
1011 "writelines() requires sequences of strings");
1012 goto error;
1013 }
1014 line = PyString_FromStringAndSize(buffer,
1015 len);
1016 if (line == NULL)
1017 goto error;
1018 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001019 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001020 }
1021 }
1022
1023 /* Since we are releasing the global lock, the
1024 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001025 Py_BEGIN_ALLOW_THREADS
1026 f->f_softspace = 0;
1027 errno = 0;
1028 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001029 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001030 len = PyString_GET_SIZE(line);
1031 nwritten = fwrite(PyString_AS_STRING(line),
1032 1, len, f->f_fp);
1033 if (nwritten != len) {
1034 Py_BLOCK_THREADS
1035 PyErr_SetFromErrno(PyExc_IOError);
1036 clearerr(f->f_fp);
1037 goto error;
1038 }
1039 }
1040 Py_END_ALLOW_THREADS
1041
1042 if (j < CHUNKSIZE)
1043 break;
1044 index += CHUNKSIZE;
1045 }
1046
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001047 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001048 result = Py_None;
1049 error:
1050 Py_XDECREF(list);
1051 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001052}
1053
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001054static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +00001055 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001056 {"read", (PyCFunction)file_read, 1},
1057 {"write", (PyCFunction)file_write, 0},
1058 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +00001059 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001060#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +00001061 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001062#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001063 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001064 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001065 {"readlines", (PyCFunction)file_readlines, 1},
1066 {"writelines", (PyCFunction)file_writelines, 0},
1067 {"flush", (PyCFunction)file_flush, 0},
1068 {"close", (PyCFunction)file_close, 0},
1069 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001070 {NULL, NULL} /* sentinel */
1071};
1072
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001073#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001074
1075static struct memberlist file_memberlist[] = {
1076 {"softspace", T_INT, OFF(f_softspace)},
1077 {"mode", T_OBJECT, OFF(f_mode), RO},
1078 {"name", T_OBJECT, OFF(f_name), RO},
1079 /* getattr(f, "closed") is implemented without this table */
1080 {"closed", T_INT, 0, RO},
1081 {NULL} /* Sentinel */
1082};
1083
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001084static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001085file_getattr(PyFileObject *f, char *name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001086{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001087 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001088
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001089 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001090 if (res != NULL)
1091 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001092 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001093 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001094 return PyInt_FromLong((long)(f->f_fp == 0));
1095 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001096}
1097
1098static int
Fred Drakefd99de62000-07-09 05:02:18 +00001099file_setattr(PyFileObject *f, char *name, PyObject *v)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001100{
1101 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001102 PyErr_SetString(PyExc_AttributeError,
1103 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001104 return -1;
1105 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001106 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001107}
1108
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001109PyTypeObject PyFile_Type = {
1110 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001111 0,
1112 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001113 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001114 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001115 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001116 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001117 (getattrfunc)file_getattr, /*tp_getattr*/
1118 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001120 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001121};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001122
1123/* Interface for the 'soft space' between print items. */
1124
1125int
Fred Drakefd99de62000-07-09 05:02:18 +00001126PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001127{
1128 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001129 if (f == NULL) {
1130 /* Do nothing */
1131 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001132 else if (PyFile_Check(f)) {
1133 oldflag = ((PyFileObject *)f)->f_softspace;
1134 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001135 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001136 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001137 PyObject *v;
1138 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001139 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001140 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001141 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001142 if (PyInt_Check(v))
1143 oldflag = PyInt_AsLong(v);
1144 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001145 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001146 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001147 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001148 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001149 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001150 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1151 PyErr_Clear();
1152 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001153 }
1154 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001155 return oldflag;
1156}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001157
1158/* Interfaces to write objects/strings to file-like objects */
1159
1160int
Fred Drakefd99de62000-07-09 05:02:18 +00001161PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001162{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001163 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001164 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001165 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001166 return -1;
1167 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001168 else if (PyFile_Check(f)) {
1169 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001170 if (fp == NULL) {
1171 err_closed();
1172 return -1;
1173 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001174 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001175 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001176 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001177 if (writer == NULL)
1178 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001179 if (flags & Py_PRINT_RAW)
1180 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001181 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001182 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001183 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001184 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001185 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001186 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001187 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001188 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001189 Py_DECREF(value);
1190 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001191 return -1;
1192 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001193 result = PyEval_CallObject(writer, args);
1194 Py_DECREF(args);
1195 Py_DECREF(value);
1196 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001197 if (result == NULL)
1198 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001199 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001200 return 0;
1201}
1202
Guido van Rossum27a60b11997-05-22 22:25:11 +00001203int
Fred Drakefd99de62000-07-09 05:02:18 +00001204PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001205{
1206 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001207 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001208 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001209 PyErr_SetString(PyExc_SystemError,
1210 "null file for PyFile_WriteString");
1211 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001212 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001213 else if (PyFile_Check(f)) {
1214 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001215 if (fp == NULL) {
1216 err_closed();
1217 return -1;
1218 }
1219 fputs(s, fp);
1220 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001221 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001222 else if (!PyErr_Occurred()) {
1223 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001224 int err;
1225 if (v == NULL)
1226 return -1;
1227 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1228 Py_DECREF(v);
1229 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001230 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001231 else
1232 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001233}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001234
1235/* Try to get a file-descriptor from a Python object. If the object
1236 is an integer or long integer, its value is returned. If not, the
1237 object's fileno() method is called if it exists; the method must return
1238 an integer or long integer, which is returned as the file descriptor value.
1239 -1 is returned on failure.
1240*/
1241
1242int PyObject_AsFileDescriptor(PyObject *o)
1243{
1244 int fd;
1245 PyObject *meth;
1246
1247 if (PyInt_Check(o)) {
1248 fd = PyInt_AsLong(o);
1249 }
1250 else if (PyLong_Check(o)) {
1251 fd = PyLong_AsLong(o);
1252 }
1253 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1254 {
1255 PyObject *fno = PyEval_CallObject(meth, NULL);
1256 Py_DECREF(meth);
1257 if (fno == NULL)
1258 return -1;
1259
1260 if (PyInt_Check(fno)) {
1261 fd = PyInt_AsLong(fno);
1262 Py_DECREF(fno);
1263 }
1264 else if (PyLong_Check(fno)) {
1265 fd = PyLong_AsLong(fno);
1266 Py_DECREF(fno);
1267 }
1268 else {
1269 PyErr_SetString(PyExc_TypeError,
1270 "fileno() returned a non-integer");
1271 Py_DECREF(fno);
1272 return -1;
1273 }
1274 }
1275 else {
1276 PyErr_SetString(PyExc_TypeError,
1277 "argument must be an int, or have a fileno() method.");
1278 return -1;
1279 }
1280
1281 if (fd < 0) {
1282 PyErr_Format(PyExc_ValueError,
1283 "file descriptor cannot be a negative integer (%i)",
1284 fd);
1285 return -1;
1286 }
1287 return fd;
1288}
1289
1290
1291