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
17 void factor_vm::init_c_io()
19 special_objects[OBJ_STDIN] = allot_alien(false_object,(cell)stdin);
20 special_objects[OBJ_STDOUT] = allot_alien(false_object,(cell)stdout);
21 special_objects[OBJ_STDERR] = allot_alien(false_object,(cell)stderr);
24 void factor_vm::io_error()
29 general_error(ERROR_IO,tag_fixnum(errno),false_object);
32 FILE *factor_vm::safe_fopen(char *filename, char *mode)
37 file = fopen(filename,mode);
46 int factor_vm::safe_fgetc(FILE *stream)
65 size_t factor_vm::safe_fread(void *ptr, size_t size, size_t nitems, FILE *stream)
67 size_t items_read = 0;
72 ret = fread((void*)((int*)ptr+items_read*size),size,nitems-items_read,stream);
81 } while(items_read != nitems);
86 void factor_vm::safe_fputc(int c, FILE *stream)
90 if(putc(c,stream) == EOF)
97 size_t factor_vm::safe_fwrite(void *ptr, size_t size, size_t nitems, FILE *stream)
99 size_t items_written = 0;
103 ret = fwrite((void*)((int*)ptr+items_written*size),size,nitems-items_written,stream);
106 items_written += ret;
107 } while(items_written != nitems);
109 return items_written;
112 int factor_vm::safe_ftell(FILE *stream)
117 if((offset = FTELL(stream)) == -1)
125 void factor_vm::safe_fseek(FILE *stream, off_t offset, int whence)
129 case 0: whence = SEEK_SET; break;
130 case 1: whence = SEEK_CUR; break;
131 case 2: whence = SEEK_END; break;
133 critical_error("Bad value for whence",whence);
138 if(FSEEK(stream,offset,whence) == -1)
145 void factor_vm::safe_fflush(FILE *stream)
149 if(fflush(stream) == EOF)
156 void factor_vm::safe_fclose(FILE *stream)
160 if(fclose(stream) == EOF)
167 void factor_vm::primitive_fopen()
169 data_root<byte_array> mode(ctx->pop(),this);
170 data_root<byte_array> path(ctx->pop(),this);
171 mode.untag_check(this);
172 path.untag_check(this);
175 file = safe_fopen((char *)(path.untagged() + 1),
176 (char *)(mode.untagged() + 1));
177 ctx->push(allot_alien(file));
180 FILE *factor_vm::pop_file_handle()
182 return (FILE *)alien_offset(ctx->pop());
185 FILE *factor_vm::peek_file_handle()
187 return (FILE *)alien_offset(ctx->peek());
190 void factor_vm::primitive_fgetc()
192 FILE *file = peek_file_handle();
194 int c = safe_fgetc(file);
195 if(c == EOF && feof(file))
198 ctx->replace(false_object);
201 ctx->replace(tag_fixnum(c));
204 /* Allocates memory */
205 void factor_vm::primitive_fread()
207 FILE *file = pop_file_handle();
208 void *buf = (void*)alien_offset(ctx->peek());
209 fixnum size = unbox_array_size();
213 ctx->replace(from_unsigned_cell(0));
217 size_t c = safe_fread(buf,1,size,file);
218 if(c == 0 || feof(file))
220 ctx->replace(from_unsigned_cell(c));
223 void factor_vm::primitive_fputc()
225 FILE *file = pop_file_handle();
226 fixnum ch = to_fixnum(ctx->pop());
227 safe_fputc((int)ch, file);
230 void factor_vm::primitive_fwrite()
232 FILE *file = pop_file_handle();
233 cell length = to_cell(ctx->pop());
234 char *text = alien_offset(ctx->pop());
239 size_t written = safe_fwrite(text,1,length,file);
240 if(written != length)
244 void factor_vm::primitive_ftell()
246 FILE *file = peek_file_handle();
247 ctx->replace(from_signed_8(safe_ftell(file)));
250 void factor_vm::primitive_fseek()
252 FILE *file = pop_file_handle();
253 int whence = (int)to_fixnum(ctx->pop());
254 off_t offset = (off_t)to_signed_8(ctx->pop());
255 safe_fseek(file,offset,whence);
258 void factor_vm::primitive_fflush()
260 FILE *file = pop_file_handle();
264 void factor_vm::primitive_fclose()
266 FILE *file = pop_file_handle();
270 /* This function is used by FFI I/O. Accessing the errno global directly is
271 not portable, since on some libc's errno is not a global but a funky macro that
272 reads thread-local storage. */
273 VM_C_API int err_no()
278 VM_C_API void set_err_no(int err)