blob: beb36b5a08ba32b74a01f8826080cebb13a73e37 [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
256_portable_fseek(fp, offset, whence)
257 FILE* fp;
258#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
259 fpos_t offset;
260#else
261 off_t offset;
262#endif
263 int whence;
264{
265#if defined(HAVE_FSEEKO)
266 return fseeko(fp, offset, whence);
267#elif defined(HAVE_FSEEK64)
268 return fseek64(fp, offset, whence);
269#elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
270 /* lacking a 64-bit capable fseek() (as Win64 does) use a 64-bit capable
271 fsetpos() and tell() to implement fseek()*/
272 fpos_t pos;
273 switch (whence) {
274 case SEEK_CUR:
275 if (fgetpos(fp, &pos) != 0)
276 return -1;
277 offset += pos;
278 break;
279 case SEEK_END:
280 /* do a "no-op" seek first to sync the buffering so that
281 the low-level tell() can be used correctly */
282 if (fseek(fp, 0, SEEK_END) != 0)
283 return -1;
284 if ((pos = TELL64(fileno(fp))) == -1L)
285 return -1;
286 offset += pos;
287 break;
288 /* case SEEK_SET: break; */
289 }
290 return fsetpos(fp, &offset);
291#else
292 return fseek(fp, offset, whence);
293#endif
294}
295
296
297/* a portable ftell() function
298 Return -1 on failure with errno set appropriately, current file
299 position on success */
300#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
301fpos_t
302#else
303off_t
304#endif
305_portable_ftell(fp)
306 FILE* fp;
307{
308#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
309 return ftello(fp);
310#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
311 return ftell64(fp);
312#elif SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT)
313 fpos_t pos;
314 if (fgetpos(fp, &pos) != 0)
315 return -1;
316 return pos;
317#else
318 return ftell(fp);
319#endif
320}
321
322
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000323static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000324file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000326 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000327 int ret;
Trent Mickf29f47b2000-08-11 19:02:59 +0000328#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
329 fpos_t offset, pos;
330#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000331 off_t offset;
Trent Mickf29f47b2000-08-11 19:02:59 +0000332#endif /* !MS_WIN64 */
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000333 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000334
Guido van Rossumd7297e61992-07-06 14:19:26 +0000335 if (f->f_fp == NULL)
336 return err_closed();
337 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000338 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000339 return NULL;
340#if !defined(HAVE_LARGEFILE_SUPPORT)
341 offset = PyInt_AsLong(offobj);
342#else
343 offset = PyLong_Check(offobj) ?
344 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
345#endif
346 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000347 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000348
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000350 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000351 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000353
Guido van Rossumff4949e1992-08-05 19:58:53 +0000354 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000355 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000356 clearerr(f->f_fp);
357 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000358 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000359 Py_INCREF(Py_None);
360 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000361}
362
Trent Mickf29f47b2000-08-11 19:02:59 +0000363
Guido van Rossumd7047b31995-01-02 19:07:15 +0000364#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000365static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000366file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000367{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000368 int ret;
Trent Mickf29f47b2000-08-11 19:02:59 +0000369#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
370 fpos_t newsize;
371#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000372 off_t newsize;
Trent Mickf29f47b2000-08-11 19:02:59 +0000373#endif
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000374 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000375
376 if (f->f_fp == NULL)
377 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000378 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000379 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000380 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000381 if (newsizeobj != NULL) {
382#if !defined(HAVE_LARGEFILE_SUPPORT)
383 newsize = PyInt_AsLong(newsizeobj);
384#else
385 newsize = PyLong_Check(newsizeobj) ?
386 PyLong_AsLongLong(newsizeobj) :
387 PyInt_AsLong(newsizeobj);
388#endif
389 if (PyErr_Occurred())
390 return NULL;
391 } else {
392 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000393 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000394 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000395 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000396 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000397 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000398 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000399 clearerr(f->f_fp);
400 return NULL;
401 }
402 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000403 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000404 errno = 0;
405 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000406 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000407 if (ret != 0) goto onioerror;
408
409#ifdef MS_WIN32
410 /* can use _chsize; if, however, the newsize overflows 32-bits then
411 _chsize is *not* adequate; in this case, an OverflowError is raised */
412 if (newsize > LONG_MAX) {
413 PyErr_SetString(PyExc_OverflowError,
414 "the new size is too long for _chsize (it is limited to 32-bit values)");
Guido van Rossumd7047b31995-01-02 19:07:15 +0000415 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000416 } else {
417 Py_BEGIN_ALLOW_THREADS
418 errno = 0;
419 ret = _chsize(fileno(f->f_fp), newsize);
420 Py_END_ALLOW_THREADS
421 if (ret != 0) goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000422 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000423#else
424 Py_BEGIN_ALLOW_THREADS
425 errno = 0;
426 ret = ftruncate(fileno(f->f_fp), newsize);
427 Py_END_ALLOW_THREADS
428 if (ret != 0) goto onioerror;
429#endif /* !MS_WIN32 */
430
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000431 Py_INCREF(Py_None);
432 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000433
434onioerror:
435 PyErr_SetFromErrno(PyExc_IOError);
436 clearerr(f->f_fp);
437 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000438}
439#endif /* HAVE_FTRUNCATE */
440
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000441static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000442file_tell(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000443{
Trent Mickf29f47b2000-08-11 19:02:59 +0000444#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
445 fpos_t pos;
446#else
447 off_t pos;
448#endif
449
Guido van Rossumd7297e61992-07-06 14:19:26 +0000450 if (f->f_fp == NULL)
451 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000454 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000455 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000456 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000458 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000459 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000460 clearerr(f->f_fp);
461 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000462 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000463#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000464 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000465#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000466 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000467#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000468}
469
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000470static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000471file_fileno(PyFileObject *f, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000472{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000473 if (f->f_fp == NULL)
474 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000475 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000476 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000477 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000478}
479
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000480static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000481file_flush(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000482{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000483 int res;
484
Guido van Rossumd7297e61992-07-06 14:19:26 +0000485 if (f->f_fp == NULL)
486 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000487 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000490 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000491 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000492 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000493 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000494 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000495 clearerr(f->f_fp);
496 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000497 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000498 Py_INCREF(Py_None);
499 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000500}
501
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000503file_isatty(PyFileObject *f, PyObject *args)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000504{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000505 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000506 if (f->f_fp == NULL)
507 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000509 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000510 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000511 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000512 Py_END_ALLOW_THREADS
513 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000514}
515
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000516
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000517#if BUFSIZ < 8192
518#define SMALLCHUNK 8192
519#else
520#define SMALLCHUNK BUFSIZ
521#endif
522
Guido van Rossum3c259041999-01-14 19:00:14 +0000523#if SIZEOF_INT < 4
524#define BIGCHUNK (512 * 32)
525#else
526#define BIGCHUNK (512 * 1024)
527#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000528
529static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000530new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000531{
532#ifdef HAVE_FSTAT
533 long pos, end;
534 struct stat st;
535 if (fstat(fileno(f->f_fp), &st) == 0) {
536 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000537 /* The following is not a bug: we really need to call lseek()
538 *and* ftell(). The reason is that some stdio libraries
539 mistakenly flush their buffer when ftell() is called and
540 the lseek() call it makes fails, thereby throwing away
541 data that cannot be recovered in any way. To avoid this,
542 we first test lseek(), and only call ftell() if lseek()
543 works. We can't use the lseek() value either, because we
544 need to take the amount of buffered data into account.
545 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000546 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
547 if (pos >= 0)
548 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000549 if (pos < 0)
550 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000551 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000552 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000553 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000554 }
555#endif
556 if (currentsize > SMALLCHUNK) {
557 /* Keep doubling until we reach BIGCHUNK;
558 then keep adding BIGCHUNK. */
559 if (currentsize <= BIGCHUNK)
560 return currentsize + currentsize;
561 else
562 return currentsize + BIGCHUNK;
563 }
564 return currentsize + SMALLCHUNK;
565}
566
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000567static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000568file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000569{
Guido van Rossum789a1611997-05-10 22:33:55 +0000570 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000571 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000572 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000573
Guido van Rossumd7297e61992-07-06 14:19:26 +0000574 if (f->f_fp == NULL)
575 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000576 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000577 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000578 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000579 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000580 else
581 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000582 if (buffersize > INT_MAX) {
583 PyErr_SetString(PyExc_OverflowError,
584 "requested number of bytes is more than a Python string can hold");
585 return NULL;
586 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000587 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000588 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000589 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000590 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000591 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000592 Py_BEGIN_ALLOW_THREADS
593 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000594 chunksize = fread(BUF(v) + bytesread, 1,
595 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000596 Py_END_ALLOW_THREADS
597 if (chunksize == 0) {
598 if (!ferror(f->f_fp))
599 break;
600 PyErr_SetFromErrno(PyExc_IOError);
601 clearerr(f->f_fp);
602 Py_DECREF(v);
603 return NULL;
604 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000605 bytesread += chunksize;
606 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000607 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000608 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000609 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000610 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000611 return NULL;
612 }
613 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000614 if (bytesread != buffersize)
615 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000616 return v;
617}
618
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000619static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000620file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000621{
622 char *ptr;
Trent Mickf29f47b2000-08-11 19:02:59 +0000623 size_t ntodo, ndone, nnow;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000624
625 if (f->f_fp == NULL)
626 return err_closed();
627 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
628 return NULL;
629 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000630 while (ntodo > 0) {
631 Py_BEGIN_ALLOW_THREADS
632 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000633 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000634 Py_END_ALLOW_THREADS
635 if (nnow == 0) {
636 if (!ferror(f->f_fp))
637 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000638 PyErr_SetFromErrno(PyExc_IOError);
639 clearerr(f->f_fp);
640 return NULL;
641 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000642 ndone += nnow;
643 ntodo -= nnow;
644 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000645 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000646}
647
648
Guido van Rossum0bd24411991-04-04 15:21:57 +0000649/* Internal routine to get a line.
650 Size argument interpretation:
651 > 0: max length;
652 = 0: read arbitrary line;
653 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000654*/
655
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000656static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000657get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000659 register FILE *fp;
660 register int c;
661 register char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000662 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000663 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000664
Guido van Rossumc10aa771992-07-31 12:42:38 +0000665 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000666 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000667 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000668 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000669 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000670 buf = BUF(v);
671 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000672
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000673 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000674 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000675 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000676 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000677 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000678 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000679 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000680 return NULL;
681 }
682 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000683 Py_DECREF(v);
684 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000685 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000686 return NULL;
687 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000688 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000689 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000690 }
691 if ((*buf++ = c) == '\n') {
692 if (n < 0)
693 buf--;
694 break;
695 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000696 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000697 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000698 break;
699 n1 = n2;
700 n2 += 1000;
Trent Mickf29f47b2000-08-11 19:02:59 +0000701 if (n2 > INT_MAX) {
702 PyErr_SetString(PyExc_OverflowError,
703 "line is longer than a Python string can hold");
704 return NULL;
705 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000706 Py_BLOCK_THREADS
707 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000708 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000709 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000710 buf = BUF(v) + n1;
711 end = BUF(v) + n2;
712 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000713 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000714 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000715
Guido van Rossumce5ba841991-03-06 13:06:18 +0000716 n1 = buf - BUF(v);
717 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000718 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000719 return v;
720}
721
Guido van Rossum0bd24411991-04-04 15:21:57 +0000722/* External C interface */
723
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000724PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000725PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000726{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000727 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000728 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000729 return NULL;
730 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000731 if (!PyFile_Check(f)) {
732 PyObject *reader;
733 PyObject *args;
734 PyObject *result;
735 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000736 if (reader == NULL)
737 return NULL;
738 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000739 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000740 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000741 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000742 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000743 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000744 return NULL;
745 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000746 result = PyEval_CallObject(reader, args);
747 Py_DECREF(reader);
748 Py_DECREF(args);
749 if (result != NULL && !PyString_Check(result)) {
750 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_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000753 "object.readline() returned non-string");
754 }
755 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000756 char *s = PyString_AsString(result);
757 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000758 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000759 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000760 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000761 PyErr_SetString(PyExc_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000762 "EOF when reading a line");
763 }
764 else if (s[len-1] == '\n') {
765 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000766 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000767 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000768 PyObject *v;
769 v = PyString_FromStringAndSize(s,
770 len-1);
771 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000772 result = v;
773 }
774 }
775 }
776 return result;
777 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000778 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000779 return err_closed();
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000780 return get_line((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000781}
782
783/* Python method */
784
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000785static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000786file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000787{
Guido van Rossum789a1611997-05-10 22:33:55 +0000788 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000789
Guido van Rossumd7297e61992-07-06 14:19:26 +0000790 if (f->f_fp == NULL)
791 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000792 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000793 return NULL;
794 if (n == 0)
795 return PyString_FromString("");
796 if (n < 0)
797 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000798 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000799}
800
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000801static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000802file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000803{
Guido van Rossum789a1611997-05-10 22:33:55 +0000804 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000805 PyObject *list;
806 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000807 char small_buffer[SMALLCHUNK];
808 char *buffer = small_buffer;
809 size_t buffersize = SMALLCHUNK;
810 PyObject *big_buffer = NULL;
811 size_t nfilled = 0;
812 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000813 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000814 char *p, *q, *end;
815 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000816
Guido van Rossumd7297e61992-07-06 14:19:26 +0000817 if (f->f_fp == NULL)
818 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000819 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000820 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000821 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000822 return NULL;
823 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000824 Py_BEGIN_ALLOW_THREADS
825 errno = 0;
826 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
827 Py_END_ALLOW_THREADS
828 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000829 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000830 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000831 break;
832 PyErr_SetFromErrno(PyExc_IOError);
833 clearerr(f->f_fp);
834 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000835 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000836 list = NULL;
837 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000838 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000839 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000840 p = memchr(buffer+nfilled, '\n', nread);
841 if (p == NULL) {
842 /* Need a larger buffer to fit this line */
843 nfilled += nread;
844 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +0000845 if (buffersize > INT_MAX) {
846 PyErr_SetString(PyExc_OverflowError,
847 "line is too long for a Python string");
848 goto error;
849 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000850 if (big_buffer == NULL) {
851 /* Create the big buffer */
852 big_buffer = PyString_FromStringAndSize(
853 NULL, buffersize);
854 if (big_buffer == NULL)
855 goto error;
856 buffer = PyString_AS_STRING(big_buffer);
857 memcpy(buffer, small_buffer, nfilled);
858 }
859 else {
860 /* Grow the big buffer */
861 _PyString_Resize(&big_buffer, buffersize);
862 buffer = PyString_AS_STRING(big_buffer);
863 }
864 continue;
865 }
866 end = buffer+nfilled+nread;
867 q = buffer;
868 do {
869 /* Process complete lines */
870 p++;
871 line = PyString_FromStringAndSize(q, p-q);
872 if (line == NULL)
873 goto error;
874 err = PyList_Append(list, line);
875 Py_DECREF(line);
876 if (err != 0)
877 goto error;
878 q = p;
879 p = memchr(q, '\n', end-q);
880 } while (p != NULL);
881 /* Move the remaining incomplete line to the start */
882 nfilled = end-q;
883 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000884 if (sizehint > 0)
885 if (totalread >= (size_t)sizehint)
886 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000887 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000888 if (nfilled != 0) {
889 /* Partial last line */
890 line = PyString_FromStringAndSize(buffer, nfilled);
891 if (line == NULL)
892 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000893 if (sizehint > 0) {
894 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000895 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +0000896 if (rest == NULL) {
897 Py_DECREF(line);
898 goto error;
899 }
900 PyString_Concat(&line, rest);
901 Py_DECREF(rest);
902 if (line == NULL)
903 goto error;
904 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000905 err = PyList_Append(list, line);
906 Py_DECREF(line);
907 if (err != 0)
908 goto error;
909 }
910 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000911 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000912 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000913 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000914 return list;
915}
916
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000917static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000918file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000919{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000920 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000921 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000922 if (f->f_fp == NULL)
923 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +0000924 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000925 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000926 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000927 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000928 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000929 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000930 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000931 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000932 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000933 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000934 return NULL;
935 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000936 Py_INCREF(Py_None);
937 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000938}
939
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000940static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000941file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000942{
Guido van Rossumee70ad12000-03-13 16:27:06 +0000943#define CHUNKSIZE 1000
944 PyObject *list, *line;
945 PyObject *result;
946 int i, j, index, len, nwritten, islist;
947
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000948 if (f->f_fp == NULL)
949 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +0000950 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000951 PyErr_SetString(PyExc_TypeError,
Guido van Rossumee70ad12000-03-13 16:27:06 +0000952 "writelines() requires sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000953 return NULL;
954 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000955 islist = PyList_Check(args);
956
957 /* Strategy: slurp CHUNKSIZE lines into a private list,
958 checking that they are all strings, then write that list
959 without holding the interpreter lock, then come back for more. */
960 index = 0;
961 if (islist)
962 list = NULL;
963 else {
964 list = PyList_New(CHUNKSIZE);
965 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000966 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000967 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000968 result = NULL;
969
970 for (;;) {
971 if (islist) {
972 Py_XDECREF(list);
973 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
974 if (list == NULL)
975 return NULL;
976 j = PyList_GET_SIZE(list);
977 }
978 else {
979 for (j = 0; j < CHUNKSIZE; j++) {
980 line = PySequence_GetItem(args, index+j);
981 if (line == NULL) {
982 if (PyErr_ExceptionMatches(
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +0000983 PyExc_IndexError)) {
Guido van Rossumee70ad12000-03-13 16:27:06 +0000984 PyErr_Clear();
985 break;
986 }
987 /* Some other error occurred.
988 XXX We may lose some output. */
989 goto error;
990 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000991 PyList_SetItem(list, j, line);
992 }
993 }
994 if (j == 0)
995 break;
996
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +0000997 /* Check that all entries are indeed strings. If not,
998 apply the same rules as for file.write() and
999 convert the results to strings. This is slow, but
1000 seems to be the only way since all conversion APIs
1001 could potentially execute Python code. */
1002 for (i = 0; i < j; i++) {
1003 PyObject *v = PyList_GET_ITEM(list, i);
1004 if (!PyString_Check(v)) {
1005 const char *buffer;
1006 int len;
1007 if (((f->f_binary &&
1008 PyObject_AsReadBuffer(v,
1009 (const void**)&buffer,
1010 &len)) ||
1011 PyObject_AsCharBuffer(v,
1012 &buffer,
1013 &len))) {
1014 PyErr_SetString(PyExc_TypeError,
1015 "writelines() requires sequences of strings");
1016 goto error;
1017 }
1018 line = PyString_FromStringAndSize(buffer,
1019 len);
1020 if (line == NULL)
1021 goto error;
1022 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001023 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001024 }
1025 }
1026
1027 /* Since we are releasing the global lock, the
1028 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001029 Py_BEGIN_ALLOW_THREADS
1030 f->f_softspace = 0;
1031 errno = 0;
1032 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001033 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001034 len = PyString_GET_SIZE(line);
1035 nwritten = fwrite(PyString_AS_STRING(line),
1036 1, len, f->f_fp);
1037 if (nwritten != len) {
1038 Py_BLOCK_THREADS
1039 PyErr_SetFromErrno(PyExc_IOError);
1040 clearerr(f->f_fp);
1041 goto error;
1042 }
1043 }
1044 Py_END_ALLOW_THREADS
1045
1046 if (j < CHUNKSIZE)
1047 break;
1048 index += CHUNKSIZE;
1049 }
1050
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001051 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001052 result = Py_None;
1053 error:
1054 Py_XDECREF(list);
1055 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001056}
1057
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001058static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +00001059 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001060 {"read", (PyCFunction)file_read, 1},
1061 {"write", (PyCFunction)file_write, 0},
1062 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +00001063 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001064#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +00001065 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001066#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001067 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001068 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001069 {"readlines", (PyCFunction)file_readlines, 1},
1070 {"writelines", (PyCFunction)file_writelines, 0},
1071 {"flush", (PyCFunction)file_flush, 0},
1072 {"close", (PyCFunction)file_close, 0},
1073 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001074 {NULL, NULL} /* sentinel */
1075};
1076
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001077#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001078
1079static struct memberlist file_memberlist[] = {
1080 {"softspace", T_INT, OFF(f_softspace)},
1081 {"mode", T_OBJECT, OFF(f_mode), RO},
1082 {"name", T_OBJECT, OFF(f_name), RO},
1083 /* getattr(f, "closed") is implemented without this table */
1084 {"closed", T_INT, 0, RO},
1085 {NULL} /* Sentinel */
1086};
1087
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001088static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001089file_getattr(PyFileObject *f, char *name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001090{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001091 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001092
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001093 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001094 if (res != NULL)
1095 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001096 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001097 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001098 return PyInt_FromLong((long)(f->f_fp == 0));
1099 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001100}
1101
1102static int
Fred Drakefd99de62000-07-09 05:02:18 +00001103file_setattr(PyFileObject *f, char *name, PyObject *v)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001104{
1105 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001106 PyErr_SetString(PyExc_AttributeError,
1107 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001108 return -1;
1109 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001110 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001111}
1112
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001113PyTypeObject PyFile_Type = {
1114 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001115 0,
1116 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001117 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001118 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001119 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001120 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001121 (getattrfunc)file_getattr, /*tp_getattr*/
1122 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001123 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001124 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001125};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001126
1127/* Interface for the 'soft space' between print items. */
1128
1129int
Fred Drakefd99de62000-07-09 05:02:18 +00001130PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001131{
1132 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001133 if (f == NULL) {
1134 /* Do nothing */
1135 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001136 else if (PyFile_Check(f)) {
1137 oldflag = ((PyFileObject *)f)->f_softspace;
1138 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001139 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001140 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001141 PyObject *v;
1142 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001143 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001144 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001145 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001146 if (PyInt_Check(v))
1147 oldflag = PyInt_AsLong(v);
1148 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001149 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001150 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001151 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001152 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001153 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001154 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1155 PyErr_Clear();
1156 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001157 }
1158 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001159 return oldflag;
1160}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001161
1162/* Interfaces to write objects/strings to file-like objects */
1163
1164int
Fred Drakefd99de62000-07-09 05:02:18 +00001165PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001166{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001167 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001168 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001169 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001170 return -1;
1171 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001172 else if (PyFile_Check(f)) {
1173 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001174 if (fp == NULL) {
1175 err_closed();
1176 return -1;
1177 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001178 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001179 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001180 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001181 if (writer == NULL)
1182 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001183 if (flags & Py_PRINT_RAW)
1184 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001185 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001186 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001187 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001188 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001189 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001190 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001191 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001192 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001193 Py_DECREF(value);
1194 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001195 return -1;
1196 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001197 result = PyEval_CallObject(writer, args);
1198 Py_DECREF(args);
1199 Py_DECREF(value);
1200 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001201 if (result == NULL)
1202 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001203 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001204 return 0;
1205}
1206
Guido van Rossum27a60b11997-05-22 22:25:11 +00001207int
Fred Drakefd99de62000-07-09 05:02:18 +00001208PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001209{
1210 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001211 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001212 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001213 PyErr_SetString(PyExc_SystemError,
1214 "null file for PyFile_WriteString");
1215 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001216 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001217 else if (PyFile_Check(f)) {
1218 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001219 if (fp == NULL) {
1220 err_closed();
1221 return -1;
1222 }
1223 fputs(s, fp);
1224 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001225 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001226 else if (!PyErr_Occurred()) {
1227 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001228 int err;
1229 if (v == NULL)
1230 return -1;
1231 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1232 Py_DECREF(v);
1233 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001234 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001235 else
1236 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001237}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001238
1239/* Try to get a file-descriptor from a Python object. If the object
1240 is an integer or long integer, its value is returned. If not, the
1241 object's fileno() method is called if it exists; the method must return
1242 an integer or long integer, which is returned as the file descriptor value.
1243 -1 is returned on failure.
1244*/
1245
1246int PyObject_AsFileDescriptor(PyObject *o)
1247{
1248 int fd;
1249 PyObject *meth;
1250
1251 if (PyInt_Check(o)) {
1252 fd = PyInt_AsLong(o);
1253 }
1254 else if (PyLong_Check(o)) {
1255 fd = PyLong_AsLong(o);
1256 }
1257 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1258 {
1259 PyObject *fno = PyEval_CallObject(meth, NULL);
1260 Py_DECREF(meth);
1261 if (fno == NULL)
1262 return -1;
1263
1264 if (PyInt_Check(fno)) {
1265 fd = PyInt_AsLong(fno);
1266 Py_DECREF(fno);
1267 }
1268 else if (PyLong_Check(fno)) {
1269 fd = PyLong_AsLong(fno);
1270 Py_DECREF(fno);
1271 }
1272 else {
1273 PyErr_SetString(PyExc_TypeError,
1274 "fileno() returned a non-integer");
1275 Py_DECREF(fno);
1276 return -1;
1277 }
1278 }
1279 else {
1280 PyErr_SetString(PyExc_TypeError,
1281 "argument must be an int, or have a fileno() method.");
1282 return -1;
1283 }
1284
1285 if (fd < 0) {
1286 PyErr_Format(PyExc_ValueError,
1287 "file descriptor cannot be a negative integer (%i)",
1288 fd);
1289 return -1;
1290 }
1291 return fd;
1292}
1293
1294
1295