blob: 7da32a95644e99bba21cbe18ea6810e61b7d0ec9 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* File object implementation */
2
Guido van Rossumdd5c7be1990-10-26 14:58:11 +00003/* XXX This should become a built-in module 'io'. It should support more
4 functionality, better exception handling for invalid calls, etc.
Guido van Rossum3f5da241990-12-20 15:06:42 +00005 (Especially reading on a write-only file or vice versa!)
Guido van Rossumdd5c7be1990-10-26 14:58:11 +00006 It should also cooperate with posix to support popen(), which should
7 share most code but have a special close function. */
8
Guido van Rossum3f5da241990-12-20 15:06:42 +00009#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010
Guido van Rossum3f5da241990-12-20 15:06:42 +000011#include "errno.h"
12#ifndef errno
13extern int errno;
14#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000015
16typedef struct {
17 OB_HEAD
18 FILE *f_fp;
19 object *f_name;
20 object *f_mode;
21 /* XXX Should move the 'need space' on printing flag here */
22} fileobject;
23
24FILE *
25getfilefile(f)
26 object *f;
27{
28 if (!is_fileobject(f)) {
Guido van Rossum3f5da241990-12-20 15:06:42 +000029 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030 return NULL;
31 }
32 return ((fileobject *)f)->f_fp;
33}
34
35object *
36newopenfileobject(fp, name, mode)
37 FILE *fp;
38 char *name;
39 char *mode;
40{
41 fileobject *f = NEWOBJ(fileobject, &Filetype);
42 if (f == NULL)
43 return NULL;
44 f->f_fp = NULL;
45 f->f_name = newstringobject(name);
46 f->f_mode = newstringobject(mode);
47 if (f->f_name == NULL || f->f_mode == NULL) {
48 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000049 return NULL;
50 }
51 f->f_fp = fp;
52 return (object *) f;
53}
54
55object *
56newfileobject(name, mode)
57 char *name, *mode;
58{
59 fileobject *f;
60 FILE *fp;
61 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode);
62 if (f == NULL)
63 return NULL;
Guido van Rossuma08095a1991-02-13 23:25:27 +000064#ifdef THINK_C
65 if (*mode == '*') {
66 FILE *fopenRF();
67 f->f_fp = fopenRF(name, mode+1);
68 }
69 else
70#endif
71 f->f_fp = fopen(name, mode);
72 if (f->f_fp == NULL) {
73 err_errno(RuntimeError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 DECREF(f);
75 return NULL;
76 }
77 return (object *)f;
78}
79
80/* Methods */
81
82static void
Guido van Rossum3f5da241990-12-20 15:06:42 +000083file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084 fileobject *f;
85{
86 if (f->f_fp != NULL)
87 fclose(f->f_fp);
88 if (f->f_name != NULL)
89 DECREF(f->f_name);
90 if (f->f_mode != NULL)
91 DECREF(f->f_mode);
92 free((char *)f);
93}
94
95static void
Guido van Rossum3f5da241990-12-20 15:06:42 +000096file_print(f, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 fileobject *f;
98 FILE *fp;
99 int flags;
100{
101 fprintf(fp, "<%s file ", f->f_fp == NULL ? "closed" : "open");
102 printobject(f->f_name, fp, flags);
103 fprintf(fp, ", mode ");
104 printobject(f->f_mode, fp, flags);
105 fprintf(fp, ">");
106}
107
108static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000109file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 fileobject *f;
111{
112 char buf[300];
Guido van Rossum3f5da241990-12-20 15:06:42 +0000113 /* XXX This differs from file_print if the filename contains
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114 quotes or other funny characters. */
115 sprintf(buf, "<%s file '%.256s', mode '%.10s'>",
116 f->f_fp == NULL ? "closed" : "open",
117 getstringvalue(f->f_name),
118 getstringvalue(f->f_mode));
119 return newstringobject(buf);
120}
121
122static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000123file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124 fileobject *f;
125 object *args;
126{
127 if (args != NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000128 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129 return NULL;
130 }
131 if (f->f_fp != NULL) {
132 fclose(f->f_fp);
133 f->f_fp = NULL;
134 }
135 INCREF(None);
136 return None;
137}
138
139static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000140file_read(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141 fileobject *f;
142 object *args;
143{
144 int n;
145 object *v;
146 if (f->f_fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000147 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148 return NULL;
149 }
150 if (args == NULL || !is_intobject(args)) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000151 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 return NULL;
153 }
154 n = getintvalue(args);
Guido van Rossumdd5c7be1990-10-26 14:58:11 +0000155 if (n < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000156 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157 return NULL;
158 }
159 v = newsizedstringobject((char *)NULL, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000160 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 n = fread(getstringvalue(v), 1, n, f->f_fp);
163 /* EOF is reported as an empty string */
164 /* XXX should detect real I/O errors? */
165 resizestring(&v, n);
166 return v;
167}
168
169/* XXX Should this be unified with raw_input()? */
170
171static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000172file_readline(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173 fileobject *f;
174 object *args;
175{
176 int n;
177 object *v;
178 if (f->f_fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000179 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180 return NULL;
181 }
182 if (args == NULL) {
183 n = 10000; /* XXX should really be unlimited */
184 }
185 else if (is_intobject(args)) {
186 n = getintvalue(args);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000187 if (n < 0) {
188 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189 return NULL;
190 }
191 }
192 else {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000193 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 return NULL;
195 }
196 v = newsizedstringobject((char *)NULL, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000197 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198 return NULL;
Guido van Rossum59b35901991-01-02 13:51:41 +0000199#ifndef THINK_C_3_0
200 /* XXX Think C 3.0 wrongly reads up to n characters... */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000201 n = n+1;
202#endif
203 if (fgets(getstringvalue(v), n, f->f_fp) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204 /* EOF is reported as an empty string */
205 /* XXX should detect real I/O errors? */
206 n = 0;
207 }
208 else {
209 n = strlen(getstringvalue(v));
210 }
211 resizestring(&v, n);
212 return v;
213}
214
215static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000216file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 fileobject *f;
218 object *args;
219{
220 int n, n2;
221 if (f->f_fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000222 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223 return NULL;
224 }
225 if (args == NULL || !is_stringobject(args)) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000226 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227 return NULL;
228 }
229 errno = 0;
230 n2 = fwrite(getstringvalue(args), 1, n = getstringsize(args), f->f_fp);
231 if (n2 != n) {
232 if (errno == 0)
233 errno = EIO;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000234 err_errno(RuntimeError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 return NULL;
236 }
237 INCREF(None);
238 return None;
239}
240
Guido van Rossum3f5da241990-12-20 15:06:42 +0000241static struct methodlist file_methods[] = {
242 {"write", file_write},
243 {"read", file_read},
244 {"readline", file_readline},
245 {"close", file_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000246 {NULL, NULL} /* sentinel */
247};
248
249static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000250file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 fileobject *f;
252 char *name;
253{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000254 return findmethod(file_methods, (object *)f, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000255}
256
257typeobject Filetype = {
258 OB_HEAD_INIT(&Typetype)
259 0,
260 "file",
261 sizeof(fileobject),
262 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000263 file_dealloc, /*tp_dealloc*/
264 file_print, /*tp_print*/
265 file_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000266 0, /*tp_setattr*/
267 0, /*tp_compare*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000268 file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269};