blob: 2978d259d90f48c57e6323729fbbc3c04f8b5064 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* File object implementation */
3
Guido van Rossumc0b618a1997-05-02 03:12:38 +00004#include "Python.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +00005#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006
Guido van Rossumff7e83d1999-08-27 20:39:37 +00007#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossum41498431999-01-07 22:09:51 +00008#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +00009#endif /* DONT_HAVE_SYS_TYPES_H */
Guido van Rossum41498431999-01-07 22:09:51 +000010
Guido van Rossumeceebb82000-06-28 20:57:07 +000011/* We expect that fstat exists on most systems.
12 It's confirmed on Unix, Mac and Windows.
13 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
14#ifndef DONT_HAVE_FSTAT
15#define HAVE_FSTAT
16
17#ifndef DONT_HAVE_SYS_TYPES_H
18#include <sys/types.h>
19#endif
20
21#ifndef DONT_HAVE_SYS_STAT_H
22#include <sys/stat.h>
23#else
24#ifdef HAVE_STAT_H
25#include <stat.h>
26#endif
27#endif
28
29#endif /* DONT_HAVE_FSTAT */
30
Guido van Rossum685a38e1996-12-05 21:54:17 +000031#ifdef HAVE_UNISTD_H
32#include <unistd.h>
33#endif
34
Guido van Rossumb8199141997-05-06 15:23:24 +000035#ifdef MS_WIN32
Guido van Rossumb8199141997-05-06 15:23:24 +000036#define fileno _fileno
Trent Mickf29f47b2000-08-11 19:02:59 +000037/* can (almost fully) duplicate with _chsize, see file_truncate */
Guido van Rossumb8199141997-05-06 15:23:24 +000038#define HAVE_FTRUNCATE
39#endif
40
Guido van Rossumf2044e11998-04-28 16:05:59 +000041#ifdef macintosh
42#ifdef USE_GUSI
43#define HAVE_FTRUNCATE
44#endif
45#endif
46
Jack Jansene08dea191995-04-23 22:12:47 +000047#ifdef __MWERKS__
48/* Mwerks fopen() doesn't always set errno */
49#define NO_FOPEN_ERRNO
50#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000051
Guido van Rossumc0b618a1997-05-02 03:12:38 +000052#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
Guido van Rossumce5ba841991-03-06 13:06:18 +000053
Guido van Rossumff7e83d1999-08-27 20:39:37 +000054#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumf1dc5661993-07-05 10:31:29 +000055#include <errno.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000056#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057
Trent Mickf29f47b2000-08-11 19:02:59 +000058/* define the appropriate 64-bit capable tell() function */
Guido van Rossum1a5e5832000-09-21 22:15:29 +000059#if defined(MS_WIN64)
60#define TELL64 _telli64
61#elif defined(__NetBSD__) || defined(__OpenBSD__)
62/* NOTE: this is only used on older
63 NetBSD prior to f*o() funcions */
64#define TELL64(fd) lseek((fd),0,SEEK_CUR)
Trent Mickf29f47b2000-08-11 19:02:59 +000065#endif
66
67
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000069 PyObject_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070 FILE *f_fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000071 PyObject *f_name;
72 PyObject *f_mode;
Tim Petersdbd9ba62000-07-09 03:09:57 +000073 int (*f_close)(FILE *);
Guido van Rossumeb183da1991-04-04 10:44:06 +000074 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum4c08d552000-03-10 22:55:18 +000075 int f_binary; /* Flag which indicates whether the file is open
76 open in binary (1) or test (0) mode */
Guido van Rossumc0b618a1997-05-02 03:12:38 +000077} PyFileObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078
79FILE *
Fred Drakefd99de62000-07-09 05:02:18 +000080PyFile_AsFile(PyObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082 if (f == NULL || !PyFile_Check(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000084 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000085 return ((PyFileObject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086}
87
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000089PyFile_Name(PyObject *f)
Guido van Rossumdb3165e1993-10-18 17:06:59 +000090{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000091 if (f == NULL || !PyFile_Check(f))
Guido van Rossumdb3165e1993-10-18 17:06:59 +000092 return NULL;
93 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +000094 return ((PyFileObject *)f)->f_name;
Guido van Rossumdb3165e1993-10-18 17:06:59 +000095}
96
Guido van Rossumc0b618a1997-05-02 03:12:38 +000097PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000098PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000100 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101 if (f == NULL)
102 return NULL;
103 f->f_fp = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000104 f->f_name = PyString_FromString(name);
105 f->f_mode = PyString_FromString(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000106 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000107 f->f_softspace = 0;
Guido van Rossum4c08d552000-03-10 22:55:18 +0000108 if (strchr(mode,'b') != NULL)
109 f->f_binary = 1;
110 else
111 f->f_binary = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 if (f->f_name == NULL || f->f_mode == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114 return NULL;
115 }
116 f->f_fp = fp;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000117 return (PyObject *) f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118}
119
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000120PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000121PyFile_FromString(char *name, char *mode)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122{
Tim Petersdbd9ba62000-07-09 03:09:57 +0000123 extern int fclose(FILE *);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000124 PyFileObject *f;
125 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000126 if (f == NULL)
127 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000128#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000129 if (*mode == '*') {
130 FILE *fopenRF();
131 f->f_fp = fopenRF(name, mode+1);
132 }
133 else
134#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000135 {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000136 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000137 f->f_fp = fopen(name, mode);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000138 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000139 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000140 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000141#ifdef NO_FOPEN_ERRNO
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000142 /* Metroworks only, not testable, so unchanged */
Jack Jansene08dea191995-04-23 22:12:47 +0000143 if ( errno == 0 ) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000144 PyErr_SetString(PyExc_IOError, "Cannot open file");
145 Py_DECREF(f);
Jack Jansene08dea191995-04-23 22:12:47 +0000146 return NULL;
147 }
148#endif
Barry Warsaw52ddc0e1998-07-23 16:07:02 +0000149 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000150 Py_DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 return NULL;
152 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000153 return (PyObject *)f;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154}
155
Guido van Rossumb6775db1994-08-01 11:34:53 +0000156void
Fred Drakefd99de62000-07-09 05:02:18 +0000157PyFile_SetBufSize(PyObject *f, int bufsize)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000158{
159 if (bufsize >= 0) {
160#ifdef HAVE_SETVBUF
161 int type;
162 switch (bufsize) {
163 case 0:
164 type = _IONBF;
165 break;
166 case 1:
167 type = _IOLBF;
168 bufsize = BUFSIZ;
169 break;
170 default:
171 type = _IOFBF;
172 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000173 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
174 type, bufsize);
Guido van Rossumf8b4de01998-03-06 15:32:40 +0000175#else /* !HAVE_SETVBUF */
176 if (bufsize <= 1)
177 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
178#endif /* !HAVE_SETVBUF */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179 }
180}
181
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000182static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000183err_closed(void)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000184{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000185 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
Guido van Rossumd7297e61992-07-06 14:19:26 +0000186 return NULL;
187}
188
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189/* Methods */
190
191static void
Fred Drakefd99de62000-07-09 05:02:18 +0000192file_dealloc(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000194 if (f->f_fp != NULL && f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000195 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000196 (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000197 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000198 }
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000199 if (f->f_name != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000200 Py_DECREF(f->f_name);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000201 }
202 if (f->f_mode != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000203 Py_DECREF(f->f_mode);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000204 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000205 PyObject_DEL(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206}
207
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000208static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000209file_repr(PyFileObject *f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210{
211 char buf[300];
Fred Drakea44d3532000-06-30 15:01:00 +0000212 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213 f->f_fp == NULL ? "closed" : "open",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000214 PyString_AsString(f->f_name),
215 PyString_AsString(f->f_mode),
Fred Drakea44d3532000-06-30 15:01:00 +0000216 f);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000217 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218}
219
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000220static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000221file_close(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000223 int sts = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000227 if (f->f_close != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000229 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000230 sts = (*f->f_close)(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000232 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233 f->f_fp = NULL;
234 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000235 if (sts == EOF)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000236 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000237 if (sts != 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000238 return PyInt_FromLong((long)sts);
239 Py_INCREF(Py_None);
240 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241}
242
Trent Mickf29f47b2000-08-11 19:02:59 +0000243
244/* a portable fseek() function
245 return 0 on success, non-zero on failure (with errno set) */
246int
Trent Mickf29f47b2000-08-11 19:02:59 +0000247#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
Fred Drake8ce159a2000-08-31 05:18:54 +0000248_portable_fseek(FILE *fp, fpos_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000249#else
Fred Drake8ce159a2000-08-31 05:18:54 +0000250_portable_fseek(FILE *fp, off_t offset, int whence)
Trent Mickf29f47b2000-08-11 19:02:59 +0000251#endif
Trent Mickf29f47b2000-08-11 19:02:59 +0000252{
253#if defined(HAVE_FSEEKO)
254 return fseeko(fp, offset, whence);
255#elif defined(HAVE_FSEEK64)
256 return fseek64(fp, offset, whence);
257#elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
258 /* lacking a 64-bit capable fseek() (as Win64 does) use a 64-bit capable
259 fsetpos() and tell() to implement fseek()*/
260 fpos_t pos;
261 switch (whence) {
262 case SEEK_CUR:
263 if (fgetpos(fp, &pos) != 0)
264 return -1;
265 offset += pos;
266 break;
267 case SEEK_END:
268 /* do a "no-op" seek first to sync the buffering so that
269 the low-level tell() can be used correctly */
270 if (fseek(fp, 0, SEEK_END) != 0)
271 return -1;
272 if ((pos = TELL64(fileno(fp))) == -1L)
273 return -1;
274 offset += pos;
275 break;
276 /* case SEEK_SET: break; */
277 }
278 return fsetpos(fp, &offset);
279#else
280 return fseek(fp, offset, whence);
281#endif
282}
283
284
285/* a portable ftell() function
286 Return -1 on failure with errno set appropriately, current file
287 position on success */
288#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
289fpos_t
290#else
291off_t
292#endif
Fred Drake8ce159a2000-08-31 05:18:54 +0000293_portable_ftell(FILE* fp)
Trent Mickf29f47b2000-08-11 19:02:59 +0000294{
295#if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
296 return ftello(fp);
297#elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
298 return ftell64(fp);
299#elif SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT)
300 fpos_t pos;
301 if (fgetpos(fp, &pos) != 0)
302 return -1;
303 return pos;
304#else
305 return ftell(fp);
306#endif
307}
308
309
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000310static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000311file_seek(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000312{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000313 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000314 int ret;
Trent Mickf29f47b2000-08-11 19:02:59 +0000315#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
316 fpos_t offset, pos;
317#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000318 off_t offset;
Trent Mickf29f47b2000-08-11 19:02:59 +0000319#endif /* !MS_WIN64 */
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000320 PyObject *offobj;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000321
Guido van Rossumd7297e61992-07-06 14:19:26 +0000322 if (f->f_fp == NULL)
323 return err_closed();
324 whence = 0;
Guido van Rossum43713e52000-02-29 13:59:29 +0000325 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000326 return NULL;
327#if !defined(HAVE_LARGEFILE_SUPPORT)
328 offset = PyInt_AsLong(offobj);
329#else
330 offset = PyLong_Check(offobj) ?
331 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
332#endif
333 if (PyErr_Occurred())
Guido van Rossum88303191999-01-04 17:22:18 +0000334 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000335
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000336 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000337 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000338 ret = _portable_fseek(f->f_fp, offset, whence);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000339 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000340
Guido van Rossumff4949e1992-08-05 19:58:53 +0000341 if (ret != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000342 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000343 clearerr(f->f_fp);
344 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000345 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000346 Py_INCREF(Py_None);
347 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000348}
349
Trent Mickf29f47b2000-08-11 19:02:59 +0000350
Guido van Rossumd7047b31995-01-02 19:07:15 +0000351#ifdef HAVE_FTRUNCATE
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000353file_truncate(PyFileObject *f, PyObject *args)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000354{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000355 int ret;
Trent Mickf29f47b2000-08-11 19:02:59 +0000356#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
357 fpos_t newsize;
358#else
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000359 off_t newsize;
Trent Mickf29f47b2000-08-11 19:02:59 +0000360#endif
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000361 PyObject *newsizeobj;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000362
363 if (f->f_fp == NULL)
364 return err_closed();
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000365 newsizeobj = NULL;
Guido van Rossum43713e52000-02-29 13:59:29 +0000366 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
Guido van Rossum88303191999-01-04 17:22:18 +0000367 return NULL;
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000368 if (newsizeobj != NULL) {
369#if !defined(HAVE_LARGEFILE_SUPPORT)
370 newsize = PyInt_AsLong(newsizeobj);
371#else
372 newsize = PyLong_Check(newsizeobj) ?
373 PyLong_AsLongLong(newsizeobj) :
374 PyInt_AsLong(newsizeobj);
375#endif
376 if (PyErr_Occurred())
377 return NULL;
378 } else {
379 /* Default to current position*/
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000381 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000382 newsize = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000383 Py_END_ALLOW_THREADS
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000384 if (newsize == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000385 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000386 clearerr(f->f_fp);
387 return NULL;
388 }
389 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd7047b31995-01-02 19:07:15 +0000391 errno = 0;
392 ret = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000393 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000394 if (ret != 0) goto onioerror;
395
396#ifdef MS_WIN32
397 /* can use _chsize; if, however, the newsize overflows 32-bits then
398 _chsize is *not* adequate; in this case, an OverflowError is raised */
399 if (newsize > LONG_MAX) {
400 PyErr_SetString(PyExc_OverflowError,
401 "the new size is too long for _chsize (it is limited to 32-bit values)");
Guido van Rossumd7047b31995-01-02 19:07:15 +0000402 return NULL;
Trent Mickf29f47b2000-08-11 19:02:59 +0000403 } else {
404 Py_BEGIN_ALLOW_THREADS
405 errno = 0;
406 ret = _chsize(fileno(f->f_fp), newsize);
407 Py_END_ALLOW_THREADS
408 if (ret != 0) goto onioerror;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000409 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000410#else
411 Py_BEGIN_ALLOW_THREADS
412 errno = 0;
413 ret = ftruncate(fileno(f->f_fp), newsize);
414 Py_END_ALLOW_THREADS
415 if (ret != 0) goto onioerror;
416#endif /* !MS_WIN32 */
417
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000418 Py_INCREF(Py_None);
419 return Py_None;
Trent Mickf29f47b2000-08-11 19:02:59 +0000420
421onioerror:
422 PyErr_SetFromErrno(PyExc_IOError);
423 clearerr(f->f_fp);
424 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000425}
426#endif /* HAVE_FTRUNCATE */
427
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000429file_tell(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000430{
Trent Mickf29f47b2000-08-11 19:02:59 +0000431#if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
432 fpos_t pos;
433#else
434 off_t pos;
435#endif
436
Guido van Rossumd7297e61992-07-06 14:19:26 +0000437 if (f->f_fp == NULL)
438 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000439 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000440 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000441 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000442 errno = 0;
Trent Mickf29f47b2000-08-11 19:02:59 +0000443 pos = _portable_ftell(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000444 Py_END_ALLOW_THREADS
Trent Mickf29f47b2000-08-11 19:02:59 +0000445 if (pos == -1) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000446 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000447 clearerr(f->f_fp);
448 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000449 }
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000450#if !defined(HAVE_LARGEFILE_SUPPORT)
Trent Mickf29f47b2000-08-11 19:02:59 +0000451 return PyInt_FromLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000452#else
Trent Mickf29f47b2000-08-11 19:02:59 +0000453 return PyLong_FromLongLong(pos);
Guido van Rossum3c9fe0c1999-01-06 18:51:17 +0000454#endif
Guido van Rossumce5ba841991-03-06 13:06:18 +0000455}
456
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000457static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000458file_fileno(PyFileObject *f, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000459{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000460 if (f->f_fp == NULL)
461 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000462 if (!PyArg_NoArgs(args))
Guido van Rossumed233a51992-06-23 09:07:03 +0000463 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000464 return PyInt_FromLong((long) fileno(f->f_fp));
Guido van Rossumed233a51992-06-23 09:07:03 +0000465}
466
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000467static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000468file_flush(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000469{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000470 int res;
471
Guido van Rossumd7297e61992-07-06 14:19:26 +0000472 if (f->f_fp == NULL)
473 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000474 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000475 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000476 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000477 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000478 res = fflush(f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000479 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000480 if (res != 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000481 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000482 clearerr(f->f_fp);
483 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000484 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485 Py_INCREF(Py_None);
486 return Py_None;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000487}
488
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000490file_isatty(PyFileObject *f, PyObject *args)
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000491{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000492 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000493 if (f->f_fp == NULL)
494 return err_closed();
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000495 if (!PyArg_NoArgs(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000496 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000497 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000498 res = isatty((int)fileno(f->f_fp));
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000499 Py_END_ALLOW_THREADS
500 return PyInt_FromLong(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000501}
502
Guido van Rossumff7e83d1999-08-27 20:39:37 +0000503
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000504#if BUFSIZ < 8192
505#define SMALLCHUNK 8192
506#else
507#define SMALLCHUNK BUFSIZ
508#endif
509
Guido van Rossum3c259041999-01-14 19:00:14 +0000510#if SIZEOF_INT < 4
511#define BIGCHUNK (512 * 32)
512#else
513#define BIGCHUNK (512 * 1024)
514#endif
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000515
516static size_t
Fred Drakefd99de62000-07-09 05:02:18 +0000517new_buffersize(PyFileObject *f, size_t currentsize)
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000518{
519#ifdef HAVE_FSTAT
520 long pos, end;
521 struct stat st;
522 if (fstat(fileno(f->f_fp), &st) == 0) {
523 end = st.st_size;
Guido van Rossumcada2931998-12-11 20:44:56 +0000524 /* The following is not a bug: we really need to call lseek()
525 *and* ftell(). The reason is that some stdio libraries
526 mistakenly flush their buffer when ftell() is called and
527 the lseek() call it makes fails, thereby throwing away
528 data that cannot be recovered in any way. To avoid this,
529 we first test lseek(), and only call ftell() if lseek()
530 works. We can't use the lseek() value either, because we
531 need to take the amount of buffered data into account.
532 (Yet another reason why stdio stinks. :-) */
Guido van Rossum91aaa921998-05-05 22:21:35 +0000533 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
534 if (pos >= 0)
535 pos = ftell(f->f_fp);
Guido van Rossumd30dc0a1998-04-27 19:01:08 +0000536 if (pos < 0)
537 clearerr(f->f_fp);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000538 if (end > pos && pos >= 0)
Guido van Rossumcada2931998-12-11 20:44:56 +0000539 return currentsize + end - pos + 1;
Guido van Rossumdcb5e7f1998-03-03 22:36:10 +0000540 /* Add 1 so if the file were to grow we'd notice. */
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000541 }
542#endif
543 if (currentsize > SMALLCHUNK) {
544 /* Keep doubling until we reach BIGCHUNK;
545 then keep adding BIGCHUNK. */
546 if (currentsize <= BIGCHUNK)
547 return currentsize + currentsize;
548 else
549 return currentsize + BIGCHUNK;
550 }
551 return currentsize + SMALLCHUNK;
552}
553
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000555file_read(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000556{
Guido van Rossum789a1611997-05-10 22:33:55 +0000557 long bytesrequested = -1;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000558 size_t bytesread, buffersize, chunksize;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 PyObject *v;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000560
Guido van Rossumd7297e61992-07-06 14:19:26 +0000561 if (f->f_fp == NULL)
562 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000563 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
Guido van Rossum789a1611997-05-10 22:33:55 +0000564 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000565 if (bytesrequested < 0)
Guido van Rossumff1ccbf1999-04-10 15:48:23 +0000566 buffersize = new_buffersize(f, (size_t)0);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000567 else
568 buffersize = bytesrequested;
Trent Mickf29f47b2000-08-11 19:02:59 +0000569 if (buffersize > INT_MAX) {
570 PyErr_SetString(PyExc_OverflowError,
571 "requested number of bytes is more than a Python string can hold");
572 return NULL;
573 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000574 v = PyString_FromStringAndSize((char *)NULL, buffersize);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000575 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000576 return NULL;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000577 bytesread = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000578 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000579 Py_BEGIN_ALLOW_THREADS
580 errno = 0;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000581 chunksize = fread(BUF(v) + bytesread, 1,
582 buffersize - bytesread, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000583 Py_END_ALLOW_THREADS
584 if (chunksize == 0) {
585 if (!ferror(f->f_fp))
586 break;
587 PyErr_SetFromErrno(PyExc_IOError);
588 clearerr(f->f_fp);
589 Py_DECREF(v);
590 return NULL;
591 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000592 bytesread += chunksize;
593 if (bytesread < buffersize)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000594 break;
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000595 if (bytesrequested < 0) {
Guido van Rossumcada2931998-12-11 20:44:56 +0000596 buffersize = new_buffersize(f, buffersize);
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000597 if (_PyString_Resize(&v, buffersize) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000598 return NULL;
599 }
600 }
Guido van Rossum5449b6e1997-05-09 22:27:31 +0000601 if (bytesread != buffersize)
602 _PyString_Resize(&v, bytesread);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603 return v;
604}
605
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000606static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000607file_readinto(PyFileObject *f, PyObject *args)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000608{
609 char *ptr;
Trent Mickf29f47b2000-08-11 19:02:59 +0000610 size_t ntodo, ndone, nnow;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000611
612 if (f->f_fp == NULL)
613 return err_closed();
614 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
615 return NULL;
616 ndone = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000617 while (ntodo > 0) {
618 Py_BEGIN_ALLOW_THREADS
619 errno = 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000620 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
Guido van Rossum6263d541997-05-10 22:07:25 +0000621 Py_END_ALLOW_THREADS
622 if (nnow == 0) {
623 if (!ferror(f->f_fp))
624 break;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000625 PyErr_SetFromErrno(PyExc_IOError);
626 clearerr(f->f_fp);
627 return NULL;
628 }
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000629 ndone += nnow;
630 ntodo -= nnow;
631 }
Trent Mickf29f47b2000-08-11 19:02:59 +0000632 return PyInt_FromLong((long)ndone);
Guido van Rossumfdf95dd1997-05-05 22:15:02 +0000633}
634
635
Guido van Rossum0bd24411991-04-04 15:21:57 +0000636/* Internal routine to get a line.
637 Size argument interpretation:
638 > 0: max length;
639 = 0: read arbitrary line;
640 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000641*/
642
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000643static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000644get_line(PyFileObject *f, int n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000645{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000646 register FILE *fp;
647 register int c;
648 register char *buf, *end;
Trent Mickf29f47b2000-08-11 19:02:59 +0000649 size_t n1, n2;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000650 PyObject *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000651
Guido van Rossumc10aa771992-07-31 12:42:38 +0000652 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000653 n2 = n > 0 ? n : 100;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000654 v = PyString_FromStringAndSize((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000655 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000656 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000657 buf = BUF(v);
658 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000659
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000660 Py_BEGIN_ALLOW_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000661 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000662 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000663 clearerr(fp);
Guido van Rossumf5181541997-11-07 19:20:34 +0000664 Py_BLOCK_THREADS
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000665 if (PyErr_CheckSignals()) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000666 Py_DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000667 return NULL;
668 }
669 if (n < 0 && buf == BUF(v)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000670 Py_DECREF(v);
671 PyErr_SetString(PyExc_EOFError,
Guido van Rossum201be051991-12-24 13:26:41 +0000672 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000673 return NULL;
674 }
Guido van Rossumf5181541997-11-07 19:20:34 +0000675 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000676 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000677 }
678 if ((*buf++ = c) == '\n') {
679 if (n < 0)
680 buf--;
681 break;
682 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000683 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000684 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000685 break;
686 n1 = n2;
687 n2 += 1000;
Trent Mickf29f47b2000-08-11 19:02:59 +0000688 if (n2 > INT_MAX) {
689 PyErr_SetString(PyExc_OverflowError,
690 "line is longer than a Python string can hold");
691 return NULL;
692 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000693 Py_BLOCK_THREADS
694 if (_PyString_Resize(&v, n2) < 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000695 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000696 Py_UNBLOCK_THREADS
Guido van Rossumce5ba841991-03-06 13:06:18 +0000697 buf = BUF(v) + n1;
698 end = BUF(v) + n2;
699 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000700 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000701 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000702
Guido van Rossumce5ba841991-03-06 13:06:18 +0000703 n1 = buf - BUF(v);
704 if (n1 != n2)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000705 _PyString_Resize(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000706 return v;
707}
708
Guido van Rossum0bd24411991-04-04 15:21:57 +0000709/* External C interface */
710
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000711PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000712PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000713{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000714 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000715 PyErr_BadInternalCall();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000716 return NULL;
717 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000718 if (!PyFile_Check(f)) {
719 PyObject *reader;
720 PyObject *args;
721 PyObject *result;
722 reader = PyObject_GetAttrString(f, "readline");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000723 if (reader == NULL)
724 return NULL;
725 if (n <= 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000726 args = Py_BuildValue("()");
Guido van Rossum3165fe61992-09-25 21:59:05 +0000727 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000728 args = Py_BuildValue("(i)", n);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000729 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000730 Py_DECREF(reader);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000731 return NULL;
732 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000733 result = PyEval_CallObject(reader, args);
734 Py_DECREF(reader);
735 Py_DECREF(args);
736 if (result != NULL && !PyString_Check(result)) {
737 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000738 result = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000739 PyErr_SetString(PyExc_TypeError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000740 "object.readline() returned non-string");
741 }
742 if (n < 0 && result != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000743 char *s = PyString_AsString(result);
744 int len = PyString_Size(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000745 if (len == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000746 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_EOFError,
Guido van Rossum3165fe61992-09-25 21:59:05 +0000749 "EOF when reading a line");
750 }
751 else if (s[len-1] == '\n') {
752 if (result->ob_refcnt == 1)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000753 _PyString_Resize(&result, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000754 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000755 PyObject *v;
756 v = PyString_FromStringAndSize(s,
757 len-1);
758 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000759 result = v;
760 }
761 }
762 }
763 return result;
764 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000765 if (((PyFileObject*)f)->f_fp == NULL)
Guido van Rossumd7297e61992-07-06 14:19:26 +0000766 return err_closed();
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000767 return get_line((PyFileObject *)f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000768}
769
770/* Python method */
771
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000772static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000773file_readline(PyFileObject *f, PyObject *args)
Guido van Rossum0bd24411991-04-04 15:21:57 +0000774{
Guido van Rossum789a1611997-05-10 22:33:55 +0000775 int n = -1;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000776
Guido van Rossumd7297e61992-07-06 14:19:26 +0000777 if (f->f_fp == NULL)
778 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000779 if (!PyArg_ParseTuple(args, "|i:readline", &n))
Guido van Rossum789a1611997-05-10 22:33:55 +0000780 return NULL;
781 if (n == 0)
782 return PyString_FromString("");
783 if (n < 0)
784 n = 0;
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000785 return get_line(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000786}
787
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000788static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000789file_readlines(PyFileObject *f, PyObject *args)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000790{
Guido van Rossum789a1611997-05-10 22:33:55 +0000791 long sizehint = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000792 PyObject *list;
793 PyObject *line;
Guido van Rossum6263d541997-05-10 22:07:25 +0000794 char small_buffer[SMALLCHUNK];
795 char *buffer = small_buffer;
796 size_t buffersize = SMALLCHUNK;
797 PyObject *big_buffer = NULL;
798 size_t nfilled = 0;
799 size_t nread;
Guido van Rossum789a1611997-05-10 22:33:55 +0000800 size_t totalread = 0;
Guido van Rossum6263d541997-05-10 22:07:25 +0000801 char *p, *q, *end;
802 int err;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000803
Guido van Rossumd7297e61992-07-06 14:19:26 +0000804 if (f->f_fp == NULL)
805 return err_closed();
Guido van Rossum43713e52000-02-29 13:59:29 +0000806 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
Guido van Rossum0bd24411991-04-04 15:21:57 +0000807 return NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000808 if ((list = PyList_New(0)) == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000809 return NULL;
810 for (;;) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000811 Py_BEGIN_ALLOW_THREADS
812 errno = 0;
813 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
814 Py_END_ALLOW_THREADS
815 if (nread == 0) {
Guido van Rossum789a1611997-05-10 22:33:55 +0000816 sizehint = 0;
Guido van Rossum3da3fce1998-02-19 20:46:48 +0000817 if (!ferror(f->f_fp))
Guido van Rossum6263d541997-05-10 22:07:25 +0000818 break;
819 PyErr_SetFromErrno(PyExc_IOError);
820 clearerr(f->f_fp);
821 error:
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000822 Py_DECREF(list);
Guido van Rossum6263d541997-05-10 22:07:25 +0000823 list = NULL;
824 goto cleanup;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000825 }
Guido van Rossum789a1611997-05-10 22:33:55 +0000826 totalread += nread;
Guido van Rossum6263d541997-05-10 22:07:25 +0000827 p = memchr(buffer+nfilled, '\n', nread);
828 if (p == NULL) {
829 /* Need a larger buffer to fit this line */
830 nfilled += nread;
831 buffersize *= 2;
Trent Mickf29f47b2000-08-11 19:02:59 +0000832 if (buffersize > INT_MAX) {
833 PyErr_SetString(PyExc_OverflowError,
834 "line is too long for a Python string");
835 goto error;
836 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000837 if (big_buffer == NULL) {
838 /* Create the big buffer */
839 big_buffer = PyString_FromStringAndSize(
840 NULL, buffersize);
841 if (big_buffer == NULL)
842 goto error;
843 buffer = PyString_AS_STRING(big_buffer);
844 memcpy(buffer, small_buffer, nfilled);
845 }
846 else {
847 /* Grow the big buffer */
848 _PyString_Resize(&big_buffer, buffersize);
849 buffer = PyString_AS_STRING(big_buffer);
850 }
851 continue;
852 }
853 end = buffer+nfilled+nread;
854 q = buffer;
855 do {
856 /* Process complete lines */
857 p++;
858 line = PyString_FromStringAndSize(q, p-q);
859 if (line == NULL)
860 goto error;
861 err = PyList_Append(list, line);
862 Py_DECREF(line);
863 if (err != 0)
864 goto error;
865 q = p;
866 p = memchr(q, '\n', end-q);
867 } while (p != NULL);
868 /* Move the remaining incomplete line to the start */
869 nfilled = end-q;
870 memmove(buffer, q, nfilled);
Guido van Rossum789a1611997-05-10 22:33:55 +0000871 if (sizehint > 0)
872 if (totalread >= (size_t)sizehint)
873 break;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000874 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000875 if (nfilled != 0) {
876 /* Partial last line */
877 line = PyString_FromStringAndSize(buffer, nfilled);
878 if (line == NULL)
879 goto error;
Guido van Rossum789a1611997-05-10 22:33:55 +0000880 if (sizehint > 0) {
881 /* Need to complete the last line */
Marc-André Lemburg1f468602000-07-05 15:32:40 +0000882 PyObject *rest = get_line(f, 0);
Guido van Rossum789a1611997-05-10 22:33:55 +0000883 if (rest == NULL) {
884 Py_DECREF(line);
885 goto error;
886 }
887 PyString_Concat(&line, rest);
888 Py_DECREF(rest);
889 if (line == NULL)
890 goto error;
891 }
Guido van Rossum6263d541997-05-10 22:07:25 +0000892 err = PyList_Append(list, line);
893 Py_DECREF(line);
894 if (err != 0)
895 goto error;
896 }
897 cleanup:
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000898 if (big_buffer) {
Guido van Rossum6263d541997-05-10 22:07:25 +0000899 Py_DECREF(big_buffer);
Guido van Rossum1109fbc1998-04-10 22:16:39 +0000900 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000901 return list;
902}
903
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000904static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000905file_write(PyFileObject *f, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000906{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000907 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000908 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000909 if (f->f_fp == NULL)
910 return err_closed();
Guido van Rossum4c08d552000-03-10 22:55:18 +0000911 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000912 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000913 f->f_softspace = 0;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000914 Py_BEGIN_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000915 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000916 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000917 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000918 if (n2 != n) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000919 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000920 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000921 return NULL;
922 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000923 Py_INCREF(Py_None);
924 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000925}
926
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000927static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000928file_writelines(PyFileObject *f, PyObject *args)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000929{
Guido van Rossumee70ad12000-03-13 16:27:06 +0000930#define CHUNKSIZE 1000
931 PyObject *list, *line;
932 PyObject *result;
933 int i, j, index, len, nwritten, islist;
934
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000935 if (f->f_fp == NULL)
936 return err_closed();
Guido van Rossumee70ad12000-03-13 16:27:06 +0000937 if (args == NULL || !PySequence_Check(args)) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000938 PyErr_SetString(PyExc_TypeError,
Guido van Rossumee70ad12000-03-13 16:27:06 +0000939 "writelines() requires sequence of strings");
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000940 return NULL;
941 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000942 islist = PyList_Check(args);
943
944 /* Strategy: slurp CHUNKSIZE lines into a private list,
945 checking that they are all strings, then write that list
946 without holding the interpreter lock, then come back for more. */
947 index = 0;
948 if (islist)
949 list = NULL;
950 else {
951 list = PyList_New(CHUNKSIZE);
952 if (list == NULL)
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000953 return NULL;
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000954 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000955 result = NULL;
956
957 for (;;) {
958 if (islist) {
959 Py_XDECREF(list);
960 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
961 if (list == NULL)
962 return NULL;
963 j = PyList_GET_SIZE(list);
964 }
965 else {
966 for (j = 0; j < CHUNKSIZE; j++) {
967 line = PySequence_GetItem(args, index+j);
968 if (line == NULL) {
969 if (PyErr_ExceptionMatches(
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +0000970 PyExc_IndexError)) {
Guido van Rossumee70ad12000-03-13 16:27:06 +0000971 PyErr_Clear();
972 break;
973 }
974 /* Some other error occurred.
975 XXX We may lose some output. */
976 goto error;
977 }
Guido van Rossumee70ad12000-03-13 16:27:06 +0000978 PyList_SetItem(list, j, line);
979 }
980 }
981 if (j == 0)
982 break;
983
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +0000984 /* Check that all entries are indeed strings. If not,
985 apply the same rules as for file.write() and
986 convert the results to strings. This is slow, but
987 seems to be the only way since all conversion APIs
988 could potentially execute Python code. */
989 for (i = 0; i < j; i++) {
990 PyObject *v = PyList_GET_ITEM(list, i);
991 if (!PyString_Check(v)) {
992 const char *buffer;
993 int len;
994 if (((f->f_binary &&
995 PyObject_AsReadBuffer(v,
996 (const void**)&buffer,
997 &len)) ||
998 PyObject_AsCharBuffer(v,
999 &buffer,
1000 &len))) {
1001 PyErr_SetString(PyExc_TypeError,
1002 "writelines() requires sequences of strings");
1003 goto error;
1004 }
1005 line = PyString_FromStringAndSize(buffer,
1006 len);
1007 if (line == NULL)
1008 goto error;
1009 Py_DECREF(v);
Marc-André Lemburgf5e96fa2000-08-25 22:49:05 +00001010 PyList_SET_ITEM(list, i, line);
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001011 }
1012 }
1013
1014 /* Since we are releasing the global lock, the
1015 following code may *not* execute Python code. */
Guido van Rossumee70ad12000-03-13 16:27:06 +00001016 Py_BEGIN_ALLOW_THREADS
1017 f->f_softspace = 0;
1018 errno = 0;
1019 for (i = 0; i < j; i++) {
Marc-André Lemburg6ef68b52000-08-25 22:39:50 +00001020 line = PyList_GET_ITEM(list, i);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001021 len = PyString_GET_SIZE(line);
1022 nwritten = fwrite(PyString_AS_STRING(line),
1023 1, len, f->f_fp);
1024 if (nwritten != len) {
1025 Py_BLOCK_THREADS
1026 PyErr_SetFromErrno(PyExc_IOError);
1027 clearerr(f->f_fp);
1028 goto error;
1029 }
1030 }
1031 Py_END_ALLOW_THREADS
1032
1033 if (j < CHUNKSIZE)
1034 break;
1035 index += CHUNKSIZE;
1036 }
1037
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001038 Py_INCREF(Py_None);
Guido van Rossumee70ad12000-03-13 16:27:06 +00001039 result = Py_None;
1040 error:
1041 Py_XDECREF(list);
1042 return result;
Guido van Rossum5a2a6831993-10-25 09:59:04 +00001043}
1044
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001045static PyMethodDef file_methods[] = {
Guido van Rossum789a1611997-05-10 22:33:55 +00001046 {"readline", (PyCFunction)file_readline, 1},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001047 {"read", (PyCFunction)file_read, 1},
1048 {"write", (PyCFunction)file_write, 0},
1049 {"fileno", (PyCFunction)file_fileno, 0},
Guido van Rossum88303191999-01-04 17:22:18 +00001050 {"seek", (PyCFunction)file_seek, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001051#ifdef HAVE_FTRUNCATE
Guido van Rossum88303191999-01-04 17:22:18 +00001052 {"truncate", (PyCFunction)file_truncate, 1},
Guido van Rossumd7047b31995-01-02 19:07:15 +00001053#endif
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001054 {"tell", (PyCFunction)file_tell, 0},
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001055 {"readinto", (PyCFunction)file_readinto, 0},
Guido van Rossum74ba2471997-07-13 03:56:50 +00001056 {"readlines", (PyCFunction)file_readlines, 1},
1057 {"writelines", (PyCFunction)file_writelines, 0},
1058 {"flush", (PyCFunction)file_flush, 0},
1059 {"close", (PyCFunction)file_close, 0},
1060 {"isatty", (PyCFunction)file_isatty, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061 {NULL, NULL} /* sentinel */
1062};
1063
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001064#define OFF(x) offsetof(PyFileObject, x)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001065
1066static struct memberlist file_memberlist[] = {
1067 {"softspace", T_INT, OFF(f_softspace)},
1068 {"mode", T_OBJECT, OFF(f_mode), RO},
1069 {"name", T_OBJECT, OFF(f_name), RO},
1070 /* getattr(f, "closed") is implemented without this table */
1071 {"closed", T_INT, 0, RO},
1072 {NULL} /* Sentinel */
1073};
1074
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001075static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +00001076file_getattr(PyFileObject *f, char *name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001077{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001078 PyObject *res;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001079
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001080 res = Py_FindMethod(file_methods, (PyObject *)f, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001081 if (res != NULL)
1082 return res;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001083 PyErr_Clear();
Guido van Rossumb6775db1994-08-01 11:34:53 +00001084 if (strcmp(name, "closed") == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001085 return PyInt_FromLong((long)(f->f_fp == 0));
1086 return PyMember_Get((char *)f, file_memberlist, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001087}
1088
1089static int
Fred Drakefd99de62000-07-09 05:02:18 +00001090file_setattr(PyFileObject *f, char *name, PyObject *v)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001091{
1092 if (v == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001093 PyErr_SetString(PyExc_AttributeError,
1094 "can't delete file attributes");
Guido van Rossumb6775db1994-08-01 11:34:53 +00001095 return -1;
1096 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001097 return PyMember_Set((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001098}
1099
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001100PyTypeObject PyFile_Type = {
1101 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001102 0,
1103 "file",
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001104 sizeof(PyFileObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001105 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +00001106 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001107 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001108 (getattrfunc)file_getattr, /*tp_getattr*/
1109 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001110 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001111 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001112};
Guido van Rossumeb183da1991-04-04 10:44:06 +00001113
1114/* Interface for the 'soft space' between print items. */
1115
1116int
Fred Drakefd99de62000-07-09 05:02:18 +00001117PyFile_SoftSpace(PyObject *f, int newflag)
Guido van Rossumeb183da1991-04-04 10:44:06 +00001118{
1119 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001120 if (f == NULL) {
1121 /* Do nothing */
1122 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001123 else if (PyFile_Check(f)) {
1124 oldflag = ((PyFileObject *)f)->f_softspace;
1125 ((PyFileObject *)f)->f_softspace = newflag;
Guido van Rossumeb183da1991-04-04 10:44:06 +00001126 }
Guido van Rossum3165fe61992-09-25 21:59:05 +00001127 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001128 PyObject *v;
1129 v = PyObject_GetAttrString(f, "softspace");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001130 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001131 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001132 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001133 if (PyInt_Check(v))
1134 oldflag = PyInt_AsLong(v);
1135 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001136 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001137 v = PyInt_FromLong((long)newflag);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001138 if (v == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001139 PyErr_Clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +00001140 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001141 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1142 PyErr_Clear();
1143 Py_DECREF(v);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001144 }
1145 }
Guido van Rossumeb183da1991-04-04 10:44:06 +00001146 return oldflag;
1147}
Guido van Rossum3165fe61992-09-25 21:59:05 +00001148
1149/* Interfaces to write objects/strings to file-like objects */
1150
1151int
Fred Drakefd99de62000-07-09 05:02:18 +00001152PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001153{
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001154 PyObject *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001155 if (f == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001156 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001157 return -1;
1158 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001159 else if (PyFile_Check(f)) {
1160 FILE *fp = PyFile_AsFile(f);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001161 if (fp == NULL) {
1162 err_closed();
1163 return -1;
1164 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001165 return PyObject_Print(v, fp, flags);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001166 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001167 writer = PyObject_GetAttrString(f, "write");
Guido van Rossum3165fe61992-09-25 21:59:05 +00001168 if (writer == NULL)
1169 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001170 if (flags & Py_PRINT_RAW)
1171 value = PyObject_Str(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001172 else
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001173 value = PyObject_Repr(v);
Guido van Rossumc6004111993-11-05 10:22:19 +00001174 if (value == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001175 Py_DECREF(writer);
Guido van Rossumc6004111993-11-05 10:22:19 +00001176 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001177 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001178 args = Py_BuildValue("(O)", value);
Guido van Rossume9eec541997-05-22 14:02:25 +00001179 if (args == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001180 Py_DECREF(value);
1181 Py_DECREF(writer);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +00001182 return -1;
1183 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001184 result = PyEval_CallObject(writer, args);
1185 Py_DECREF(args);
1186 Py_DECREF(value);
1187 Py_DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001188 if (result == NULL)
1189 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001190 Py_DECREF(result);
Guido van Rossum3165fe61992-09-25 21:59:05 +00001191 return 0;
1192}
1193
Guido van Rossum27a60b11997-05-22 22:25:11 +00001194int
Fred Drakefd99de62000-07-09 05:02:18 +00001195PyFile_WriteString(char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +00001196{
1197 if (f == NULL) {
Guido van Rossum27a60b11997-05-22 22:25:11 +00001198 /* Should be caused by a pre-existing error */
Fred Drakefd99de62000-07-09 05:02:18 +00001199 if (!PyErr_Occurred())
Guido van Rossum27a60b11997-05-22 22:25:11 +00001200 PyErr_SetString(PyExc_SystemError,
1201 "null file for PyFile_WriteString");
1202 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001203 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001204 else if (PyFile_Check(f)) {
1205 FILE *fp = PyFile_AsFile(f);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001206 if (fp == NULL) {
1207 err_closed();
1208 return -1;
1209 }
1210 fputs(s, fp);
1211 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001212 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001213 else if (!PyErr_Occurred()) {
1214 PyObject *v = PyString_FromString(s);
Guido van Rossum27a60b11997-05-22 22:25:11 +00001215 int err;
1216 if (v == NULL)
1217 return -1;
1218 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1219 Py_DECREF(v);
1220 return err;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001221 }
Guido van Rossum74ba2471997-07-13 03:56:50 +00001222 else
1223 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +00001224}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +00001225
1226/* Try to get a file-descriptor from a Python object. If the object
1227 is an integer or long integer, its value is returned. If not, the
1228 object's fileno() method is called if it exists; the method must return
1229 an integer or long integer, which is returned as the file descriptor value.
1230 -1 is returned on failure.
1231*/
1232
1233int PyObject_AsFileDescriptor(PyObject *o)
1234{
1235 int fd;
1236 PyObject *meth;
1237
1238 if (PyInt_Check(o)) {
1239 fd = PyInt_AsLong(o);
1240 }
1241 else if (PyLong_Check(o)) {
1242 fd = PyLong_AsLong(o);
1243 }
1244 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1245 {
1246 PyObject *fno = PyEval_CallObject(meth, NULL);
1247 Py_DECREF(meth);
1248 if (fno == NULL)
1249 return -1;
1250
1251 if (PyInt_Check(fno)) {
1252 fd = PyInt_AsLong(fno);
1253 Py_DECREF(fno);
1254 }
1255 else if (PyLong_Check(fno)) {
1256 fd = PyLong_AsLong(fno);
1257 Py_DECREF(fno);
1258 }
1259 else {
1260 PyErr_SetString(PyExc_TypeError,
1261 "fileno() returned a non-integer");
1262 Py_DECREF(fno);
1263 return -1;
1264 }
1265 }
1266 else {
1267 PyErr_SetString(PyExc_TypeError,
1268 "argument must be an int, or have a fileno() method.");
1269 return -1;
1270 }
1271
1272 if (fd < 0) {
1273 PyErr_Format(PyExc_ValueError,
1274 "file descriptor cannot be a negative integer (%i)",
1275 fd);
1276 return -1;
1277 }
1278 return fd;
1279}
1280
1281
1282