6 /* Simple wrappers for ANSI C I/O functions, used for bootstrapping.
8 Note the ugly loop logic in almost every function; we have to handle EINTR
9 and restart the operation if the system call was interrupted. Naive
10 applications don't do this, but then they quickly fail if one enables
11 itimer()s or other signals.
13 The Factor library provides platform-specific code for Unix and Windows
14 with many more capabilities so these words are not usually used in
19 userenv[STDIN_ENV] = allot_alien(F,(cell)stdin);
20 userenv[STDOUT_ENV] = allot_alien(F,(cell)stdout);
21 userenv[STDERR_ENV] = allot_alien(F,(cell)stderr);
31 general_error(ERROR_IO,tag_fixnum(errno),F,NULL);
36 gc_root<byte_array> mode(dpop());
37 gc_root<byte_array> path(dpop());
43 FILE *file = fopen((char *)(path.untagged() + 1),
44 (char *)(mode.untagged() + 1));
57 FILE *file = (FILE *)unbox_alien();
82 FILE *file = (FILE *)unbox_alien();
83 fixnum size = unbox_array_size();
87 dpush(tag<string>(allot_string(0,0)));
91 gc_root<byte_array> buf(allot_array_internal<byte_array>(size));
95 int c = fread(buf.untagged() + 1,1,size,file);
110 byte_array *new_buf = allot_byte_array(c);
111 memcpy(new_buf + 1, buf.untagged() + 1,c);
122 FILE *file = (FILE *)unbox_alien();
123 fixnum ch = to_fixnum(dpop());
127 if(fputc(ch,file) == EOF)
131 /* Still here? EINTR */
140 FILE *file = (FILE *)unbox_alien();
141 byte_array *text = untag_check<byte_array>(dpop());
142 cell length = array_capacity(text);
143 char *string = (char *)(text + 1);
150 size_t written = fwrite(string,1,length,file);
151 if(written == length)
160 /* Still here? EINTR */
169 int whence = to_fixnum(dpop());
170 FILE *file = (FILE *)unbox_alien();
171 off_t offset = to_signed_8(dpop());
175 case 0: whence = SEEK_SET; break;
176 case 1: whence = SEEK_CUR; break;
177 case 2: whence = SEEK_END; break;
179 critical_error("Bad value for whence",whence);
183 if(FSEEK(file,offset,whence) == -1)
187 /* Still here? EINTR */
188 critical_error("Don't know what to do; EINTR from fseek()?",0);
194 FILE *file = (FILE *)unbox_alien();
197 if(fflush(file) == EOF)
206 FILE *file = (FILE *)unbox_alien();
209 if(fclose(file) == EOF)
216 /* This function is used by FFI I/O. Accessing the errno global directly is
217 not portable, since on some libc's errno is not a global but a funky macro that
218 reads thread-local storage. */
219 VM_C_API int err_no()
224 VM_C_API void clear_err_no()