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 CELL error
= tag_object(from_char_string(strerror(errno
)));
29 general_error(ERROR_IO
,error
,F
,NULL
);
32 void primitive_fopen(void)
34 char *mode
= unbox_char_string();
35 REGISTER_C_STRING(mode
);
36 char *path
= unbox_char_string();
37 UNREGISTER_C_STRING(mode
);
41 FILE *file
= fopen(path
,mode
);
52 void primitive_fgetc(void)
54 FILE* file
= unbox_alien();
77 void primitive_fread(void)
79 FILE* file
= unbox_alien();
80 CELL size
= unbox_array_size();
84 dpush(tag_object(allot_string(0,0)));
88 F_BYTE_ARRAY
*buf
= allot_byte_array(size
);
92 int c
= fread(buf
+ 1,1,size
,file
);
107 REGISTER_UNTAGGED(buf
);
108 F_BYTE_ARRAY
*new_buf
= allot_byte_array(c
);
109 UNREGISTER_UNTAGGED(buf
);
110 memcpy(new_buf
+ 1, buf
+ 1,c
);
113 dpush(tag_object(buf
));
119 void primitive_fputc(void)
121 FILE *file
= unbox_alien();
122 F_FIXNUM ch
= to_fixnum(dpop());
126 if(fputc(ch
,file
) == EOF
)
130 /* Still here? EINTR */
137 void primitive_fwrite(void)
139 FILE *file
= unbox_alien();
140 F_BYTE_ARRAY
*text
= untag_byte_array(dpop());
141 F_FIXNUM length
= array_capacity(text
);
142 char *string
= (char *)(text
+ 1);
149 size_t written
= fwrite(string
,1,length
,file
);
150 if(written
== length
)
159 /* Still here? EINTR */
166 void primitive_fflush(void)
168 FILE *file
= unbox_alien();
171 if(fflush(file
) == EOF
)
178 void primitive_fclose(void)
180 FILE *file
= unbox_alien();
183 if(fclose(file
) == EOF
)
190 /* This function is used by FFI I/O. Accessing the errno global directly is
191 not portable, since on some libc's errno is not a global but a funky macro that
192 reads thread-local storage. */
198 void clear_err_no(void)