blob: 09f19e51ade3c392c9eee846b74a5685a14c2361 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
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 Rossumdd5c7be1990-10-26 14:58:11 +000027/* XXX This should become a built-in module 'io'. It should support more
28 functionality, better exception handling for invalid calls, etc.
Guido van Rossum3f5da241990-12-20 15:06:42 +000029 (Especially reading on a write-only file or vice versa!)
Guido van Rossumdd5c7be1990-10-26 14:58:11 +000030 It should also cooperate with posix to support popen(), which should
31 share most code but have a special close function. */
32
Guido van Rossum3f5da241990-12-20 15:06:42 +000033#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000034
Guido van Rossum3f5da241990-12-20 15:06:42 +000035#include "errno.h"
36#ifndef errno
37extern int errno;
38#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039
40typedef struct {
41 OB_HEAD
42 FILE *f_fp;
43 object *f_name;
44 object *f_mode;
45 /* XXX Should move the 'need space' on printing flag here */
46} fileobject;
47
48FILE *
49getfilefile(f)
50 object *f;
51{
52 if (!is_fileobject(f)) {
Guido van Rossum3f5da241990-12-20 15:06:42 +000053 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054 return NULL;
55 }
56 return ((fileobject *)f)->f_fp;
57}
58
59object *
60newopenfileobject(fp, name, mode)
61 FILE *fp;
62 char *name;
63 char *mode;
64{
65 fileobject *f = NEWOBJ(fileobject, &Filetype);
66 if (f == NULL)
67 return NULL;
68 f->f_fp = NULL;
69 f->f_name = newstringobject(name);
70 f->f_mode = newstringobject(mode);
71 if (f->f_name == NULL || f->f_mode == NULL) {
72 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 return NULL;
74 }
75 f->f_fp = fp;
76 return (object *) f;
77}
78
79object *
80newfileobject(name, mode)
81 char *name, *mode;
82{
83 fileobject *f;
84 FILE *fp;
85 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode);
86 if (f == NULL)
87 return NULL;
Guido van Rossuma08095a1991-02-13 23:25:27 +000088#ifdef THINK_C
89 if (*mode == '*') {
90 FILE *fopenRF();
91 f->f_fp = fopenRF(name, mode+1);
92 }
93 else
94#endif
95 f->f_fp = fopen(name, mode);
96 if (f->f_fp == NULL) {
97 err_errno(RuntimeError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098 DECREF(f);
99 return NULL;
100 }
101 return (object *)f;
102}
103
104/* Methods */
105
106static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000107file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108 fileobject *f;
109{
110 if (f->f_fp != NULL)
111 fclose(f->f_fp);
112 if (f->f_name != NULL)
113 DECREF(f->f_name);
114 if (f->f_mode != NULL)
115 DECREF(f->f_mode);
116 free((char *)f);
117}
118
119static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000120file_print(f, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 fileobject *f;
122 FILE *fp;
123 int flags;
124{
125 fprintf(fp, "<%s file ", f->f_fp == NULL ? "closed" : "open");
126 printobject(f->f_name, fp, flags);
127 fprintf(fp, ", mode ");
128 printobject(f->f_mode, fp, flags);
129 fprintf(fp, ">");
130}
131
132static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000133file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 fileobject *f;
135{
136 char buf[300];
Guido van Rossum3f5da241990-12-20 15:06:42 +0000137 /* XXX This differs from file_print if the filename contains
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000138 quotes or other funny characters. */
139 sprintf(buf, "<%s file '%.256s', mode '%.10s'>",
140 f->f_fp == NULL ? "closed" : "open",
141 getstringvalue(f->f_name),
142 getstringvalue(f->f_mode));
143 return newstringobject(buf);
144}
145
146static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000147file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148 fileobject *f;
149 object *args;
150{
151 if (args != NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000152 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 return NULL;
154 }
155 if (f->f_fp != NULL) {
156 fclose(f->f_fp);
157 f->f_fp = NULL;
158 }
159 INCREF(None);
160 return None;
161}
162
163static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000164file_read(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 fileobject *f;
166 object *args;
167{
168 int n;
169 object *v;
170 if (f->f_fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000171 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 return NULL;
173 }
174 if (args == NULL || !is_intobject(args)) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000175 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 return NULL;
177 }
178 n = getintvalue(args);
Guido van Rossumdd5c7be1990-10-26 14:58:11 +0000179 if (n < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000180 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181 return NULL;
182 }
183 v = newsizedstringobject((char *)NULL, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000184 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186 n = fread(getstringvalue(v), 1, n, f->f_fp);
187 /* EOF is reported as an empty string */
188 /* XXX should detect real I/O errors? */
189 resizestring(&v, n);
190 return v;
191}
192
193/* XXX Should this be unified with raw_input()? */
194
195static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000196file_readline(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 fileobject *f;
198 object *args;
199{
200 int n;
201 object *v;
202 if (f->f_fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000203 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204 return NULL;
205 }
206 if (args == NULL) {
207 n = 10000; /* XXX should really be unlimited */
208 }
209 else if (is_intobject(args)) {
210 n = getintvalue(args);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000211 if (n < 0) {
212 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213 return NULL;
214 }
215 }
216 else {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000217 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218 return NULL;
219 }
220 v = newsizedstringobject((char *)NULL, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000221 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 return NULL;
Guido van Rossum59b35901991-01-02 13:51:41 +0000223#ifndef THINK_C_3_0
224 /* XXX Think C 3.0 wrongly reads up to n characters... */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000225 n = n+1;
226#endif
227 if (fgets(getstringvalue(v), n, f->f_fp) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228 /* EOF is reported as an empty string */
229 /* XXX should detect real I/O errors? */
230 n = 0;
231 }
232 else {
233 n = strlen(getstringvalue(v));
234 }
235 resizestring(&v, n);
236 return v;
237}
238
239static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000240file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241 fileobject *f;
242 object *args;
243{
244 int n, n2;
245 if (f->f_fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000246 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247 return NULL;
248 }
249 if (args == NULL || !is_stringobject(args)) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000250 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 return NULL;
252 }
253 errno = 0;
254 n2 = fwrite(getstringvalue(args), 1, n = getstringsize(args), f->f_fp);
255 if (n2 != n) {
256 if (errno == 0)
257 errno = EIO;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000258 err_errno(RuntimeError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259 return NULL;
260 }
261 INCREF(None);
262 return None;
263}
264
Guido van Rossum3f5da241990-12-20 15:06:42 +0000265static struct methodlist file_methods[] = {
266 {"write", file_write},
267 {"read", file_read},
268 {"readline", file_readline},
269 {"close", file_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270 {NULL, NULL} /* sentinel */
271};
272
273static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000274file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275 fileobject *f;
276 char *name;
277{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000278 return findmethod(file_methods, (object *)f, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279}
280
281typeobject Filetype = {
282 OB_HEAD_INIT(&Typetype)
283 0,
284 "file",
285 sizeof(fileobject),
286 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000287 file_dealloc, /*tp_dealloc*/
288 file_print, /*tp_print*/
289 file_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 0, /*tp_setattr*/
291 0, /*tp_compare*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000292 file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293};