3 /* Simple wrappers for ANSI C I/O functions, used for bootstrapping.
5 Note the ugly loop logic in almost every function; we have to handle EINTR
6 and restart the operation if the system call was interrupted. Naive
7 applications don't do this, but then they quickly fail if one enables
8 itimer()s or other signals.
10 The Factor library provides platform-specific code for Unix and Windows
11 with many more capabilities so these words are not usually used in
16 userenv[STDIN_ENV] = allot_alien(F,(CELL)stdin);
17 userenv[STDOUT_ENV] = allot_alien(F,(CELL)stdout);
18 userenv[STDERR_ENV] = allot_alien(F,(CELL)stderr);
28 general_error(ERROR_IO,tag_fixnum(errno),F,NULL);
31 void primitive_fopen(void)
33 gc_root<F_BYTE_ARRAY> mode(dpop());
34 gc_root<F_BYTE_ARRAY> path(dpop());
40 FILE *file = fopen((char *)(path.untagged() + 1),
41 (char *)(mode.untagged() + 1));
52 void primitive_fgetc(void)
54 FILE *file = (FILE *)unbox_alien();
77 void primitive_fread(void)
79 FILE *file = (FILE *)unbox_alien();
80 F_FIXNUM size = unbox_array_size();
84 dpush(tag_object(allot_string(0,0)));
88 gc_root<F_BYTE_ARRAY> buf(allot_array_internal<F_BYTE_ARRAY>(size));
92 int c = fread(buf.untagged() + 1,1,size,file);
107 F_BYTE_ARRAY *new_buf = allot_byte_array(c);
108 memcpy(new_buf + 1, buf.untagged() + 1,c);
117 void primitive_fputc(void)
119 FILE *file = (FILE *)unbox_alien();
120 F_FIXNUM ch = to_fixnum(dpop());
124 if(fputc(ch,file) == EOF)
128 /* Still here? EINTR */
135 void primitive_fwrite(void)
137 FILE *file = (FILE *)unbox_alien();
138 F_BYTE_ARRAY *text = untag_byte_array(dpop());
139 CELL length = array_capacity(text);
140 char *string = (char *)(text + 1);
147 size_t written = fwrite(string,1,length,file);
148 if(written == length)
157 /* Still here? EINTR */
164 void primitive_fseek(void)
166 int whence = to_fixnum(dpop());
167 FILE *file = (FILE *)unbox_alien();
168 off_t offset = to_signed_8(dpop());
172 case 0: whence = SEEK_SET; break;
173 case 1: whence = SEEK_CUR; break;
174 case 2: whence = SEEK_END; break;
176 critical_error("Bad value for whence",whence);
180 if(FSEEK(file,offset,whence) == -1)
184 /* Still here? EINTR */
185 critical_error("Don't know what to do; EINTR from fseek()?",0);
189 void primitive_fflush(void)
191 FILE *file = (FILE *)unbox_alien();
194 if(fflush(file) == EOF)
201 void primitive_fclose(void)
203 FILE *file = (FILE *)unbox_alien();
206 if(fclose(file) == EOF)
213 /* This function is used by FFI I/O. Accessing the errno global directly is
214 not portable, since on some libc's errno is not a global but a funky macro that
215 reads thread-local storage. */
221 void clear_err_no(void)