blob: 44bc51bdf7e87c638f5f309dbde7dbcc5c6418c8 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumb6775db1994-08-01 11:34:53 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossum34679b71993-01-26 13:33:44 +00003Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* File object implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossumfa3da8a1992-01-27 16:53:23 +000028#include "modsupport.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000029#include "structmember.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000030#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000031
Guido van Rossumce5ba841991-03-06 13:06:18 +000032#define BUF(v) GETSTRINGVALUE((stringobject *)v)
33
Guido van Rossumf1dc5661993-07-05 10:31:29 +000034#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035
36typedef struct {
37 OB_HEAD
38 FILE *f_fp;
39 object *f_name;
40 object *f_mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000041 int (*f_close) PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000042 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043} fileobject;
44
45FILE *
46getfilefile(f)
47 object *f;
48{
Guido van Rossum3165fe61992-09-25 21:59:05 +000049 if (f == NULL || !is_fileobject(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000051 else
52 return ((fileobject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053}
54
55object *
Guido van Rossumdb3165e1993-10-18 17:06:59 +000056getfilename(f)
57 object *f;
58{
59 if (f == NULL || !is_fileobject(f))
60 return NULL;
61 else
62 return ((fileobject *)f)->f_name;
63}
64
65object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000066newopenfileobject(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067 FILE *fp;
68 char *name;
69 char *mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000070 int (*close) FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071{
72 fileobject *f = NEWOBJ(fileobject, &Filetype);
73 if (f == NULL)
74 return NULL;
75 f->f_fp = NULL;
76 f->f_name = newstringobject(name);
77 f->f_mode = newstringobject(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000078 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000079 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 if (f->f_name == NULL || f->f_mode == NULL) {
81 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082 return NULL;
83 }
84 f->f_fp = fp;
85 return (object *) f;
86}
87
88object *
89newfileobject(name, mode)
90 char *name, *mode;
91{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000092 extern int fclose PROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000093 fileobject *f;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000094 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095 if (f == NULL)
96 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +000097#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +000098 if (*mode == '*') {
99 FILE *fopenRF();
100 f->f_fp = fopenRF(name, mode+1);
101 }
102 else
103#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000104 {
105 BGN_SAVE
106 f->f_fp = fopen(name, mode);
107 END_SAVE
108 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000109 if (f->f_fp == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000110 err_errno(IOError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 DECREF(f);
112 return NULL;
113 }
114 return (object *)f;
115}
116
Guido van Rossumb6775db1994-08-01 11:34:53 +0000117void
118setfilebufsize(f, bufsize)
119 object *f;
120 int bufsize;
121{
122 if (bufsize >= 0) {
123#ifdef HAVE_SETVBUF
124 int type;
125 switch (bufsize) {
126 case 0:
127 type = _IONBF;
128 break;
129 case 1:
130 type = _IOLBF;
131 bufsize = BUFSIZ;
132 break;
133 default:
134 type = _IOFBF;
135 }
136 setvbuf(((fileobject *)f)->f_fp, (char *)NULL, type, bufsize);
137#endif /* HAVE_SETVBUF */
138 }
139}
140
Guido van Rossumd7297e61992-07-06 14:19:26 +0000141static object *
142err_closed()
143{
144 err_setstr(ValueError, "I/O operation on closed file");
145 return NULL;
146}
147
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148/* Methods */
149
150static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000151file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 fileobject *f;
153{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000154 if (f->f_fp != NULL && f->f_close != NULL) {
155 BGN_SAVE
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000156 (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000157 END_SAVE
158 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 if (f->f_name != NULL)
160 DECREF(f->f_name);
161 if (f->f_mode != NULL)
162 DECREF(f->f_mode);
163 free((char *)f);
164}
165
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000167file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 fileobject *f;
169{
170 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000171 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 f->f_fp == NULL ? "closed" : "open",
173 getstringvalue(f->f_name),
Guido van Rossume35399e1993-01-10 18:33:56 +0000174 getstringvalue(f->f_mode),
175 (long)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 return newstringobject(buf);
177}
178
179static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000180file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181 fileobject *f;
182 object *args;
183{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000184 int sts = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000185 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000188 if (f->f_close != NULL) {
189 BGN_SAVE
190 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000191 sts = (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000192 END_SAVE
193 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 f->f_fp = NULL;
195 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000196 if (sts == EOF)
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000197 return err_errno(IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000198 if (sts != 0)
199 return newintobject((long)sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 INCREF(None);
201 return None;
202}
203
204static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000205file_seek(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 fileobject *f;
207 object *args;
208{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000209 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000210 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000211 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000212
Guido van Rossumd7297e61992-07-06 14:19:26 +0000213 if (f->f_fp == NULL)
214 return err_closed();
215 whence = 0;
216 if (!getargs(args, "l", &offset)) {
217 err_clear();
218 if (!getargs(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000219 return NULL;
220 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000221 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000222 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000223 ret = fseek(f->f_fp, offset, whence);
224 END_SAVE
225 if (ret != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000226 err_errno(IOError);
227 clearerr(f->f_fp);
228 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000229 }
230 INCREF(None);
231 return None;
232}
233
Guido van Rossumd7047b31995-01-02 19:07:15 +0000234#ifdef HAVE_FTRUNCATE
235static object *
236file_truncate(f, args)
237 fileobject *f;
238 object *args;
239{
240 long newsize;
241 int ret;
242
243 if (f->f_fp == NULL)
244 return err_closed();
245 if (!getargs(args, "l", &newsize)) {
246 err_clear();
247 if (!getnoarg(args))
248 return NULL;
249 BGN_SAVE
250 errno = 0;
251 newsize = ftell(f->f_fp); /* default to current position*/
252 END_SAVE
253 if (newsize == -1L) {
254 err_errno(IOError);
255 clearerr(f->f_fp);
256 return NULL;
257 }
258 }
259 BGN_SAVE
260 errno = 0;
261 ret = fflush(f->f_fp);
262 END_SAVE
263 if (ret == 0) {
264 BGN_SAVE
265 errno = 0;
266 ret = ftruncate(fileno(f->f_fp), newsize);
267 END_SAVE
268 }
269 if (ret != 0) {
270 err_errno(IOError);
271 clearerr(f->f_fp);
272 return NULL;
273 }
274 INCREF(None);
275 return None;
276}
277#endif /* HAVE_FTRUNCATE */
278
Guido van Rossumce5ba841991-03-06 13:06:18 +0000279static object *
280file_tell(f, args)
281 fileobject *f;
282 object *args;
283{
284 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000285 if (f->f_fp == NULL)
286 return err_closed();
287 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000289 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000290 errno = 0;
291 offset = ftell(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000292 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000293 if (offset == -1L) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000294 err_errno(IOError);
295 clearerr(f->f_fp);
296 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000297 }
298 return newintobject(offset);
299}
300
301static object *
Guido van Rossumed233a51992-06-23 09:07:03 +0000302file_fileno(f, args)
303 fileobject *f;
304 object *args;
305{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000306 if (f->f_fp == NULL)
307 return err_closed();
Guido van Rossumed233a51992-06-23 09:07:03 +0000308 if (!getnoarg(args))
309 return NULL;
310 return newintobject((long) fileno(f->f_fp));
311}
312
313static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000314file_flush(f, args)
315 fileobject *f;
316 object *args;
317{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000318 int res;
319
Guido van Rossumd7297e61992-07-06 14:19:26 +0000320 if (f->f_fp == NULL)
321 return err_closed();
322 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000324 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000325 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000326 res = fflush(f->f_fp);
327 END_SAVE
328 if (res != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000329 err_errno(IOError);
330 clearerr(f->f_fp);
331 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000332 }
333 INCREF(None);
334 return None;
335}
336
337static object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000338file_isatty(f, args)
339 fileobject *f;
340 object *args;
341{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000342 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000343 if (f->f_fp == NULL)
344 return err_closed();
345 if (!getnoarg(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000346 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000347 BGN_SAVE
348 res = isatty((int)fileno(f->f_fp));
349 END_SAVE
350 return newintobject(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000351}
352
353static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000354file_read(f, args)
355 fileobject *f;
356 object *args;
357{
358 int n, n1, n2, n3;
359 object *v;
360
Guido van Rossumd7297e61992-07-06 14:19:26 +0000361 if (f->f_fp == NULL)
362 return err_closed();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000363 if (args == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000364 n = 0;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000365 else {
366 if (!getargs(args, "i", &n))
367 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000368 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000369 err_setstr(ValueError, "negative read count");
Guido van Rossumce5ba841991-03-06 13:06:18 +0000370 return NULL;
371 }
372 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000373 n2 = n != 0 ? n : BUFSIZ;
374 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000375 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000377 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000378 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000379 for (;;) {
380 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
381 /* XXX Error check? */
382 if (n3 == 0)
383 break;
384 n1 += n3;
385 if (n1 == n)
386 break;
387 if (n == 0) {
388 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000389 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000390 if (resizestring(&v, n2) < 0)
391 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000392 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000393 }
394 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000395 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000396 if (n1 != n2)
397 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 return v;
399}
400
Guido van Rossum0bd24411991-04-04 15:21:57 +0000401/* Internal routine to get a line.
402 Size argument interpretation:
403 > 0: max length;
404 = 0: read arbitrary line;
405 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000406*/
407
Guido van Rossum234f9421993-06-17 12:35:49 +0000408static object *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000409getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000410 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000411 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000412{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000413 register FILE *fp;
414 register int c;
415 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000416 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000417 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000418
Guido van Rossumc10aa771992-07-31 12:42:38 +0000419 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000420 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000421 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000422 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000423 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000424 buf = BUF(v);
425 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000426
Guido van Rossumff4949e1992-08-05 19:58:53 +0000427 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000428 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000429 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000430 clearerr(fp);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000431 if (sigcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000432 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000433 DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000434 return NULL;
435 }
436 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000437 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000438 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000439 err_setstr(EOFError,
440 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000441 return NULL;
442 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000443 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000444 }
445 if ((*buf++ = c) == '\n') {
446 if (n < 0)
447 buf--;
448 break;
449 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000450 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000451 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000452 break;
453 n1 = n2;
454 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000455 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000456 if (resizestring(&v, n2) < 0)
457 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000458 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000459 buf = BUF(v) + n1;
460 end = BUF(v) + n2;
461 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000462 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000463 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000464
Guido van Rossumce5ba841991-03-06 13:06:18 +0000465 n1 = buf - BUF(v);
466 if (n1 != n2)
467 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000468 return v;
469}
470
Guido van Rossum0bd24411991-04-04 15:21:57 +0000471/* External C interface */
472
473object *
474filegetline(f, n)
475 object *f;
476 int n;
477{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000478 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000479 err_badcall();
480 return NULL;
481 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000482 if (!is_fileobject(f)) {
483 object *reader;
484 object *args;
485 object *result;
486 reader = getattr(f, "readline");
487 if (reader == NULL)
488 return NULL;
489 if (n <= 0)
490 args = mkvalue("()");
491 else
492 args = mkvalue("(i)", n);
493 if (args == NULL) {
494 DECREF(reader);
495 return NULL;
496 }
497 result = call_object(reader, args);
498 DECREF(reader);
499 DECREF(args);
500 if (result != NULL && !is_stringobject(result)) {
501 DECREF(result);
502 result = NULL;
503 err_setstr(TypeError,
504 "object.readline() returned non-string");
505 }
506 if (n < 0 && result != NULL) {
507 char *s = getstringvalue(result);
508 int len = getstringsize(result);
509 if (len == 0) {
510 DECREF(result);
511 result = NULL;
512 err_setstr(EOFError,
513 "EOF when reading a line");
514 }
515 else if (s[len-1] == '\n') {
516 if (result->ob_refcnt == 1)
517 resizestring(&result, len-1);
518 else {
519 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000520 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000521 DECREF(result);
522 result = v;
523 }
524 }
525 }
526 return result;
527 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000528 if (((fileobject*)f)->f_fp == NULL)
529 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000530 return getline((fileobject *)f, n);
531}
532
533/* Python method */
534
535static object *
536file_readline(f, args)
537 fileobject *f;
538 object *args;
539{
540 int n;
541
Guido van Rossumd7297e61992-07-06 14:19:26 +0000542 if (f->f_fp == NULL)
543 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000544 if (args == NULL)
545 n = 0; /* Unlimited */
546 else {
547 if (!getintarg(args, &n))
548 return NULL;
549 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000550 err_setstr(ValueError, "negative readline count");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000551 return NULL;
552 }
553 }
554
Guido van Rossum51415a71992-03-27 17:23:38 +0000555 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000556}
557
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000558static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000559file_readlines(f, args)
560 fileobject *f;
561 object *args;
562{
563 object *list;
564 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000565
Guido van Rossumd7297e61992-07-06 14:19:26 +0000566 if (f->f_fp == NULL)
567 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000568 if (!getnoarg(args))
569 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000570 if ((list = newlistobject(0)) == NULL)
571 return NULL;
572 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000573 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000574 if (line != NULL && getstringsize(line) == 0) {
575 DECREF(line);
576 break;
577 }
578 if (line == NULL || addlistitem(list, line) != 0) {
579 DECREF(list);
580 XDECREF(line);
581 return NULL;
582 }
583 DECREF(line);
584 }
585 return list;
586}
587
588static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000589file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000590 fileobject *f;
591 object *args;
592{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000593 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000594 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000595 if (f->f_fp == NULL)
596 return err_closed();
597 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000598 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000599 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000600 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000601 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000602 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000603 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000604 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000605 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000606 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000607 return NULL;
608 }
609 INCREF(None);
610 return None;
611}
612
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000613static object *
614file_writelines(f, args)
615 fileobject *f;
616 object *args;
617{
618 int i, n;
619 if (f->f_fp == NULL)
620 return err_closed();
621 if (args == NULL || !is_listobject(args)) {
622 err_setstr(TypeError,
623 "writelines() requires list of strings");
624 return NULL;
625 }
626 n = getlistsize(args);
627 f->f_softspace = 0;
628 BGN_SAVE
629 errno = 0;
630 for (i = 0; i < n; i++) {
631 object *line = getlistitem(args, i);
632 int len;
633 int nwritten;
634 if (!is_stringobject(line)) {
635 RET_SAVE
636 err_setstr(TypeError,
637 "writelines() requires list of strings");
638 return NULL;
639 }
640 len = getstringsize(line);
641 nwritten = fwrite(getstringvalue(line), 1, len, f->f_fp);
642 if (nwritten != len) {
643 RET_SAVE
644 err_errno(IOError);
645 clearerr(f->f_fp);
646 return NULL;
647 }
648 }
649 END_SAVE
650 INCREF(None);
651 return None;
652}
653
Guido van Rossum3f5da241990-12-20 15:06:42 +0000654static struct methodlist file_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000655 {"close", (method)file_close},
656 {"flush", (method)file_flush},
657 {"fileno", (method)file_fileno},
658 {"isatty", (method)file_isatty},
659 {"read", (method)file_read},
660 {"readline", (method)file_readline},
661 {"readlines", (method)file_readlines},
662 {"seek", (method)file_seek},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000663#ifdef HAVE_FTRUNCATE
664 {"truncate", (method)file_truncate},
665#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000666 {"tell", (method)file_tell},
667 {"write", (method)file_write},
668 {"writelines", (method)file_writelines},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000669 {NULL, NULL} /* sentinel */
670};
671
Guido van Rossumb6775db1994-08-01 11:34:53 +0000672#define OFF(x) offsetof(fileobject, x)
673
674static struct memberlist file_memberlist[] = {
675 {"softspace", T_INT, OFF(f_softspace)},
676 {"mode", T_OBJECT, OFF(f_mode), RO},
677 {"name", T_OBJECT, OFF(f_name), RO},
678 /* getattr(f, "closed") is implemented without this table */
679 {"closed", T_INT, 0, RO},
680 {NULL} /* Sentinel */
681};
682
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000683static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000684file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000685 fileobject *f;
686 char *name;
687{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000688 object *res;
689
690 res = findmethod(file_methods, (object *)f, name);
691 if (res != NULL)
692 return res;
693 err_clear();
694 if (strcmp(name, "closed") == 0)
695 return newintobject((long)(f->f_fp == 0));
696 return getmember((char *)f, file_memberlist, name);
697}
698
699static int
700file_setattr(f, name, v)
701 fileobject *f;
702 char *name;
703 object *v;
704{
705 if (v == NULL) {
706 err_setstr(AttributeError, "can't delete file attributes");
707 return -1;
708 }
709 return setmember((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000710}
711
712typeobject Filetype = {
713 OB_HEAD_INIT(&Typetype)
714 0,
715 "file",
716 sizeof(fileobject),
717 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000718 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000719 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000720 (getattrfunc)file_getattr, /*tp_getattr*/
721 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000722 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000723 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000725
726/* Interface for the 'soft space' between print items. */
727
728int
729softspace(f, newflag)
730 object *f;
731 int newflag;
732{
733 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000734 if (f == NULL) {
735 /* Do nothing */
736 }
Guido van Rossum82d410e1993-11-01 16:26:16 +0000737 else if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000738 oldflag = ((fileobject *)f)->f_softspace;
739 ((fileobject *)f)->f_softspace = newflag;
740 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000741 else {
742 object *v;
743 v = getattr(f, "softspace");
744 if (v == NULL)
745 err_clear();
746 else {
747 if (is_intobject(v))
748 oldflag = getintvalue(v);
749 DECREF(v);
750 }
751 v = newintobject((long)newflag);
752 if (v == NULL)
753 err_clear();
754 else {
755 if (setattr(f, "softspace", v) != 0)
756 err_clear();
757 DECREF(v);
758 }
759 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000760 return oldflag;
761}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000762
763/* Interfaces to write objects/strings to file-like objects */
764
765int
766writeobject(v, f, flags)
767 object *v;
768 object *f;
769 int flags;
770{
771 object *writer, *value, *result;
772 if (f == NULL) {
773 err_setstr(TypeError, "writeobject with NULL file");
774 return -1;
775 }
776 else if (is_fileobject(f)) {
777 FILE *fp = getfilefile(f);
778 if (fp == NULL) {
779 err_closed();
780 return -1;
781 }
782 return printobject(v, fp, flags);
783 }
784 writer = getattr(f, "write");
785 if (writer == NULL)
786 return -1;
Guido van Rossumc6004111993-11-05 10:22:19 +0000787 if (flags & PRINT_RAW)
788 value = strobject(v);
789 else
Guido van Rossum3165fe61992-09-25 21:59:05 +0000790 value = reprobject(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000791 if (value == NULL) {
792 DECREF(writer);
793 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000794 }
795 result = call_object(writer, value);
796 DECREF(writer);
797 DECREF(value);
798 if (result == NULL)
799 return -1;
800 DECREF(result);
801 return 0;
802}
803
804void
805writestring(s, f)
806 char *s;
807 object *f;
808{
809 if (f == NULL) {
810 /* Do nothing */
811 }
812 else if (is_fileobject(f)) {
813 FILE *fp = getfilefile(f);
814 if (fp != NULL)
815 fputs(s, fp);
816 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817 else if (!err_occurred()) {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000818 object *v = newstringobject(s);
819 if (v == NULL) {
820 err_clear();
821 }
822 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000823 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000824 err_clear();
825 DECREF(v);
826 }
827 }
828}