blob: f87e22e430ecaa613e495dd69741b91a96a0a335 [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;
64 if ((f->f_fp = fopen(name, mode)) == NULL) {
65 DECREF(f);
Guido van Rossum3f5da241990-12-20 15:06:42 +000066 err_errno(RuntimeError); /* XXX Should use another error */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067 return NULL;
68 }
69 return (object *)f;
70}
71
72/* Methods */
73
74static void
Guido van Rossum3f5da241990-12-20 15:06:42 +000075file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 fileobject *f;
77{
78 if (f->f_fp != NULL)
79 fclose(f->f_fp);
80 if (f->f_name != NULL)
81 DECREF(f->f_name);
82 if (f->f_mode != NULL)
83 DECREF(f->f_mode);
84 free((char *)f);
85}
86
87static void
Guido van Rossum3f5da241990-12-20 15:06:42 +000088file_print(f, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089 fileobject *f;
90 FILE *fp;
91 int flags;
92{
93 fprintf(fp, "<%s file ", f->f_fp == NULL ? "closed" : "open");
94 printobject(f->f_name, fp, flags);
95 fprintf(fp, ", mode ");
96 printobject(f->f_mode, fp, flags);
97 fprintf(fp, ">");
98}
99
100static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000101file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102 fileobject *f;
103{
104 char buf[300];
Guido van Rossum3f5da241990-12-20 15:06:42 +0000105 /* XXX This differs from file_print if the filename contains
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106 quotes or other funny characters. */
107 sprintf(buf, "<%s file '%.256s', mode '%.10s'>",
108 f->f_fp == NULL ? "closed" : "open",
109 getstringvalue(f->f_name),
110 getstringvalue(f->f_mode));
111 return newstringobject(buf);
112}
113
114static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000115file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116 fileobject *f;
117 object *args;
118{
119 if (args != NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000120 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 return NULL;
122 }
123 if (f->f_fp != NULL) {
124 fclose(f->f_fp);
125 f->f_fp = NULL;
126 }
127 INCREF(None);
128 return None;
129}
130
131static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000132file_read(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133 fileobject *f;
134 object *args;
135{
136 int n;
137 object *v;
138 if (f->f_fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000139 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000140 return NULL;
141 }
142 if (args == NULL || !is_intobject(args)) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000143 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144 return NULL;
145 }
146 n = getintvalue(args);
Guido van Rossumdd5c7be1990-10-26 14:58:11 +0000147 if (n < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000148 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149 return NULL;
150 }
151 v = newsizedstringobject((char *)NULL, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000152 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154 n = fread(getstringvalue(v), 1, n, f->f_fp);
155 /* EOF is reported as an empty string */
156 /* XXX should detect real I/O errors? */
157 resizestring(&v, n);
158 return v;
159}
160
161/* XXX Should this be unified with raw_input()? */
162
163static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000164file_readline(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) {
175 n = 10000; /* XXX should really be unlimited */
176 }
177 else if (is_intobject(args)) {
178 n = getintvalue(args);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000179 if (n < 0) {
180 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181 return NULL;
182 }
183 }
184 else {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000185 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186 return NULL;
187 }
188 v = newsizedstringobject((char *)NULL, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000189 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000190 return NULL;
Guido van Rossum59b35901991-01-02 13:51:41 +0000191#ifndef THINK_C_3_0
192 /* XXX Think C 3.0 wrongly reads up to n characters... */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000193 n = n+1;
194#endif
195 if (fgets(getstringvalue(v), n, f->f_fp) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 /* EOF is reported as an empty string */
197 /* XXX should detect real I/O errors? */
198 n = 0;
199 }
200 else {
201 n = strlen(getstringvalue(v));
202 }
203 resizestring(&v, n);
204 return v;
205}
206
207static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000208file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209 fileobject *f;
210 object *args;
211{
212 int n, n2;
213 if (f->f_fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000214 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215 return NULL;
216 }
217 if (args == NULL || !is_stringobject(args)) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000218 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219 return NULL;
220 }
221 errno = 0;
222 n2 = fwrite(getstringvalue(args), 1, n = getstringsize(args), f->f_fp);
223 if (n2 != n) {
224 if (errno == 0)
225 errno = EIO;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000226 err_errno(RuntimeError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227 return NULL;
228 }
229 INCREF(None);
230 return None;
231}
232
Guido van Rossum3f5da241990-12-20 15:06:42 +0000233static struct methodlist file_methods[] = {
234 {"write", file_write},
235 {"read", file_read},
236 {"readline", file_readline},
237 {"close", file_close},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238 {NULL, NULL} /* sentinel */
239};
240
241static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000242file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243 fileobject *f;
244 char *name;
245{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000246 return findmethod(file_methods, (object *)f, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247}
248
249typeobject Filetype = {
250 OB_HEAD_INIT(&Typetype)
251 0,
252 "file",
253 sizeof(fileobject),
254 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000255 file_dealloc, /*tp_dealloc*/
256 file_print, /*tp_print*/
257 file_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000258 0, /*tp_setattr*/
259 0, /*tp_compare*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000260 file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261};