blob: dd2ede09d70213a238e9f123b98d15a233ea7bfb [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
Guido van Rossumff7e83d1999-08-27 20:39:37 +000016#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum41498431999-01-07 22:09:51 +000017#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000018#endif /* DONT_HAVE_SYS_TYPES_H */
Guido van Rossum41498431999-01-07 22:09:51 +000019
Guido van Rossumeceebb82000-06-28 20:57:07 +000020/* We expect that fstat exists on most systems.
21 It's confirmed on Unix, Mac and Windows.
22 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
23#ifndef DONT_HAVE_FSTAT
24#define HAVE_FSTAT
25
26#ifndef DONT_HAVE_SYS_TYPES_H
27#include <sys/types.h>
28#endif
29
30#ifndef DONT_HAVE_SYS_STAT_H
31#include <sys/stat.h>
32#else
33#ifdef HAVE_STAT_H
34#include <stat.h>
35#endif
36#endif
37
38#endif /* DONT_HAVE_FSTAT */
39
Guido van Rossum685a38e1996-12-05 21:54:17 +000040#ifdef HAVE_UNISTD_H
41#include <unistd.h>
42#endif
43
Guido van Rossumb8199141997-05-06 15:23:24 +000044#ifdef MS_WIN32
Guido van Rossumb8199141997-05-06 15:23:24 +000045#define fileno _fileno
Trent Mickf29f47b2000-08-11 19:02:59 +000046/* can (almost fully) duplicate with _chsize, see file_truncate */
Guido van Rossumb8199141997-05-06 15:23:24 +000047#define HAVE_FTRUNCATE
48#endif
49
Guido van Rossumf2044e11998-04-28 16:05:59 +000050#ifdef macintosh
51#ifdef USE_GUSI
52#define HAVE_FTRUNCATE
53#endif
54#endif
55
Jack Jansene08dea191995-04-23 22:12:47 +000056#ifdef __MWERKS__
57/* Mwerks fopen() doesn't always set errno */
58#define NO_FOPEN_ERRNO
59#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000060
Guido van Rossumc0b618a1997-05-02 03:12:38 +000061#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000062
Guido van Rossumff7e83d1999-08-27 20:39:37 +000063#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000064#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000065#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Trent Mickf29f47b2000-08-11 19:02:59 +000067/* define the appropriate 64-bit capable tell() function */
68#ifdef MS_WIN64
69# define TELL64 _telli64
70#endif
71
72
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000074 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000076 PyObject *f_name;
77 PyObject *f_mode;
Tim Petersdbd9ba62000-07-09 03:09:57 +000078 int (*f_close)(FILE *);
Guido van Rossumeb183da1991-04-04 10:44:06 +000079 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000080 int f_binary; /* Flag which indicates whether the file is open
81 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083
84FILE *
Fred Drakefd99de62000-07-09 05:02:18 +000085PyFile_AsFile(PyObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000087 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000089 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000090 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091}
92
Guido van Rossumc0b618a1997-05-02 03:12:38 +000093PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000094PyFile_Name(PyObject *f)
Guido van Rossumdb3165e1993-10-18 17:06:59 +000095{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000096 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000097 return NULL;
98 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000099 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +0000100}
101
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000102PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000103PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000105 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106 if (f == NULL)
107 return NULL;
108 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000109 f->f_name = PyString_FromString(name);
110 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000111 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000112 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +0000113 if (strchr(mode,'b') != NULL)
114 f->f_binary = 1;
115 else
116 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000118 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119 return NULL;
120 }
121 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000122 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123}
124
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000125PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000126PyFile_FromString(char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127{
Tim Petersdbd9ba62000-07-09 03:09:57 +0000128 extern int fclose(FILE *);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000129 PyFileObject *f;
130 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131 if (f == NULL)
132 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000133#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000134 if (*mode == '*') {
135 FILE *fopenRF();
136 f->f_fp = fopenRF(name, mode+1);
137 }
138 else
139#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000140 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000141 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000142 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000143 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000144 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000145 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000146#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000147 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000148 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000149 PyErr_SetString(PyExc_IOError, "Cannot open file");
150 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000151 return NULL;
152 }
153#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000154 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000155 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156 return NULL;
157 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000158 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159}
160
Guido van Rossumb6775db1994-08-01 11:34:53 +0000161void
Fred Drakefd99de62000-07-09 05:02:18 +0000162PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000163{
164 if (bufsize >= 0) {
165#ifdef HAVE_SETVBUF
166 int type;
167 switch (bufsize) {
168 case 0:
169 type = _IONBF;
170 break;
171 case 1:
172 type = _IOLBF;
173 bufsize = BUFSIZ;
174 break;
175 default:
176 type = _IOFBF;
177 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000178 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
179 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000180#else /* !HAVE_SETVBUF */
181 if (bufsize <= 1)
182 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
183#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184 }
185}
186
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000187static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000188err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000189{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000190 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000191 return NULL;
192}
193
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194/* Methods */
195
196static void
Fred Drakefd99de62000-07-09 05:02:18 +0000197file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000199 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000200 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000201 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000202 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000203 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000204 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000205 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000206 }
207 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000208 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000209 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000210 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211}
212
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000213static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000214file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215{
216 char buf[300];
Fred Drakea44d3532000-06-30 15:01:00 +0000217 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000219 PyString_AsString(f->f_name),
220 PyString_AsString(f->f_mode),
Fred Drakea44d3532000-06-30 15:01:00 +0000221 f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000222 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223}
224
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000225static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000226file_close(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000228 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000229 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000232 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000234 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000235 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000236 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000237 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238 f->f_fp = NULL;
239 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000240 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000241 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000242 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000243 return PyInt_FromLong((long)sts);
244 Py_INCREF(Py_None);
245 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000246}
247
Trent Mickf29f47b2000-08-11 19:02:59 +0000248
249/* a portable fseek() function
250 return 0 on success, non-zero on failure (with errno set) */
251int
252_portable_fseek(fp, offset, whence)
253 FILE* fp;
254#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
255 fpos_t offset;
256#else
257 off_t offset;
258#endif
259 int whence;
260{
261#if defined(HAVE_FSEEKO)
262 return fseeko(fp, offset, whence);
263#elif defined(HAVE_FSEEK64)
264 return fseek64(fp, offset, whence);
265#elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
266 /* lacking a 64-bit capable fseek() (as Win64 does) use a 64-bit capable
267 fsetpos() and tell() to implement fseek()*/
268 fpos_t pos;
269 switch (whence) {
270 case SEEK_CUR:
271 if (fgetpos(fp, &pos) != 0)
272 return -1;
273 offset += pos;
274 break;
275 case SEEK_END:
276 /* do a "no-op" seek first to sync the buffering so that
277 the low-level tell() can be used correctly */
278 if (fseek(fp, 0, SEEK_END) != 0)
279 return -1;
280 if ((pos = TELL64(fileno(fp))) == -1L)
281 return -1;
282 offset += pos;
283 break;
284 /* case SEEK_SET: break; */
285 }
286 return fsetpos(fp, &offset);
287#else
288 return fseek(fp, offset, whence);
289#endif
290}
291
292
293/* a portable ftell() function
294 Return -1 on failure with errno set appropriately, current file
295 position on success */
296#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
297fpos_t
298#else
299off_t
300#endif
301_portable_ftell(fp)
302 FILE* fp;
303{
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(
979 PyExc_IndexError))
980 {
981 PyErr_Clear();
982 break;
983 }
984 /* Some other error occurred.
985 XXX We may lose some output. */
986 goto error;
987 }
988 if (!PyString_Check(line)) {
989 Py_DECREF(line);
990 PyErr_SetString(PyExc_TypeError,
991 "writelines() requires sequences of strings");
992 goto error;
993 }
994 PyList_SetItem(list, j, line);
995 }
996 }
997 if (j == 0)
998 break;
999
1000 Py_BEGIN_ALLOW_THREADS
1001 f->f_softspace = 0;
1002 errno = 0;
1003 for (i = 0; i < j; i++) {
1004 line = PyList_GET_ITEM(list, i);
1005 len = PyString_GET_SIZE(line);
1006 nwritten = fwrite(PyString_AS_STRING(line),
1007 1, len, f->f_fp);
1008 if (nwritten != len) {
1009 Py_BLOCK_THREADS
1010 PyErr_SetFromErrno(PyExc_IOError);
1011 clearerr(f->f_fp);
1012 goto error;
1013 }
1014 }
1015 Py_END_ALLOW_THREADS
1016
1017 if (j < CHUNKSIZE)
1018 break;
1019 index += CHUNKSIZE;
1020 }
1021
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001022 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001023 result = Py_None;
1024 error:
1025 Py_XDECREF(list);
1026 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001027}
1028
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001029static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +00001030 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001031 {"read", (PyCFunction)file_read, 1},
1032 {"write", (PyCFunction)file_write, 0},
1033 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +00001034 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001035#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +00001036 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001037#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001038 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001039 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001040 {"readlines", (PyCFunction)file_readlines, 1},
1041 {"writelines", (PyCFunction)file_writelines, 0},
1042 {"flush", (PyCFunction)file_flush, 0},
1043 {"close", (PyCFunction)file_close, 0},
1044 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001045 {NULL, NULL} /* sentinel */
1046};
1047
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001048#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001049
1050static struct memberlist file_memberlist[] = {
1051 {"softspace", T_INT, OFF(f_softspace)},
1052 {"mode", T_OBJECT, OFF(f_mode), RO},
1053 {"name", T_OBJECT, OFF(f_name), RO},
1054 /* getattr(f, "closed") is implemented without this table */
1055 {"closed", T_INT, 0, RO},
1056 {NULL} /* Sentinel */
1057};
1058
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001059static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001060file_getattr(PyFileObject *f, char *name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001062 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001063
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001064 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001065 if (res != NULL)
1066 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001067 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001068 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001069 return PyInt_FromLong((long)(f->f_fp == 0));
1070 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001071}
1072
1073static int
Fred Drakefd99de62000-07-09 05:02:18 +00001074file_setattr(PyFileObject *f, char *name, PyObject *v)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001075{
1076 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001077 PyErr_SetString(PyExc_AttributeError,
1078 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001079 return -1;
1080 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001081 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001082}
1083
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001084PyTypeObject PyFile_Type = {
1085 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001086 0,
1087 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001088 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001089 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001090 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001091 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001092 (getattrfunc)file_getattr, /*tp_getattr*/
1093 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001094 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001095 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001096};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001097
1098/* Interface for the 'soft space' between print items. */
1099
1100int
Fred Drakefd99de62000-07-09 05:02:18 +00001101PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001102{
1103 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001104 if (f == NULL) {
1105 /* Do nothing */
1106 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001107 else if (PyFile_Check(f)) {
1108 oldflag = ((PyFileObject *)f)->f_softspace;
1109 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001110 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001111 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001112 PyObject *v;
1113 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001114 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001115 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001116 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001117 if (PyInt_Check(v))
1118 oldflag = PyInt_AsLong(v);
1119 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001120 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001121 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001122 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001123 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001124 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001125 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1126 PyErr_Clear();
1127 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001128 }
1129 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001130 return oldflag;
1131}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001132
1133/* Interfaces to write objects/strings to file-like objects */
1134
1135int
Fred Drakefd99de62000-07-09 05:02:18 +00001136PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001137{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001138 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001139 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001140 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001141 return -1;
1142 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001143 else if (PyFile_Check(f)) {
1144 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001145 if (fp == NULL) {
1146 err_closed();
1147 return -1;
1148 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001149 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001150 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001151 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001152 if (writer == NULL)
1153 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001154 if (flags & Py_PRINT_RAW)
1155 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001156 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001157 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001158 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001159 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001160 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001161 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001162 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001163 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001164 Py_DECREF(value);
1165 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001166 return -1;
1167 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001168 result = PyEval_CallObject(writer, args);
1169 Py_DECREF(args);
1170 Py_DECREF(value);
1171 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001172 if (result == NULL)
1173 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001174 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001175 return 0;
1176}
1177
Guido van Rossum27a60b11997-05-22 22:25:11 +00001178int
Fred Drakefd99de62000-07-09 05:02:18 +00001179PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001180{
1181 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001182 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001183 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001184 PyErr_SetString(PyExc_SystemError,
1185 "null file for PyFile_WriteString");
1186 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001187 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001188 else if (PyFile_Check(f)) {
1189 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001190 if (fp == NULL) {
1191 err_closed();
1192 return -1;
1193 }
1194 fputs(s, fp);
1195 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001196 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001197 else if (!PyErr_Occurred()) {
1198 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001199 int err;
1200 if (v == NULL)
1201 return -1;
1202 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1203 Py_DECREF(v);
1204 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001205 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001206 else
1207 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001208}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001209
1210/* Try to get a file-descriptor from a Python object. If the object
1211 is an integer or long integer, its value is returned. If not, the
1212 object's fileno() method is called if it exists; the method must return
1213 an integer or long integer, which is returned as the file descriptor value.
1214 -1 is returned on failure.
1215*/
1216
1217int PyObject_AsFileDescriptor(PyObject *o)
1218{
1219 int fd;
1220 PyObject *meth;
1221
1222 if (PyInt_Check(o)) {
1223 fd = PyInt_AsLong(o);
1224 }
1225 else if (PyLong_Check(o)) {
1226 fd = PyLong_AsLong(o);
1227 }
1228 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1229 {
1230 PyObject *fno = PyEval_CallObject(meth, NULL);
1231 Py_DECREF(meth);
1232 if (fno == NULL)
1233 return -1;
1234
1235 if (PyInt_Check(fno)) {
1236 fd = PyInt_AsLong(fno);
1237 Py_DECREF(fno);
1238 }
1239 else if (PyLong_Check(fno)) {
1240 fd = PyLong_AsLong(fno);
1241 Py_DECREF(fno);
1242 }
1243 else {
1244 PyErr_SetString(PyExc_TypeError,
1245 "fileno() returned a non-integer");
1246 Py_DECREF(fno);
1247 return -1;
1248 }
1249 }
1250 else {
1251 PyErr_SetString(PyExc_TypeError,
1252 "argument must be an int, or have a fileno() method.");
1253 return -1;
1254 }
1255
1256 if (fd < 0) {
1257 PyErr_Format(PyExc_ValueError,
1258 "file descriptor cannot be a negative integer (%i)",
1259 fd);
1260 return -1;
1261 }
1262 return fd;
1263}
1264
1265
1266