VM: new functions raw_fclose and raw_fread

These need to be used when the image is loaded because there is no
context so you can't throw io errors yet.
db4
Björn Lindqvist 2015-05-30 02:29:57 +02:00
parent 9d289e35f4
commit f1ca83524a
3 changed files with 42 additions and 24 deletions

View File

@ -18,7 +18,7 @@ void factor_vm::load_data_heap(FILE* file, image_header* h, vm_parameters* p) {
init_data_heap(p->young_size, p->aging_size, p->tenured_size);
fixnum bytes_read =
safe_fread((void*)data->tenured->start, 1, h->data_size, file);
raw_fread((void*)data->tenured->start, 1, h->data_size, file);
if ((cell)bytes_read != h->data_size) {
std::cout << "truncated image: " << bytes_read << " bytes read, ";
@ -37,7 +37,7 @@ void factor_vm::load_code_heap(FILE* file, image_header* h, vm_parameters* p) {
if (h->code_size != 0) {
size_t bytes_read =
safe_fread((void*)code->allocator->start, 1, h->code_size, file);
raw_fread((void*)code->allocator->start, 1, h->code_size, file);
if (bytes_read != h->code_size) {
std::cout << "truncated image: " << bytes_read << " bytes read, ";
std::cout << h->code_size << " bytes expected\n";
@ -239,9 +239,8 @@ void factor_vm::load_image(vm_parameters* p) {
free(msg);
exit(1);
}
image_header h;
if (safe_fread(&h, sizeof(image_header), 1, file) != 1)
if (raw_fread(&h, sizeof(image_header), 1, file) != 1)
fatal_error("Cannot read image header", 0);
if (h.magic != image_magic)
@ -253,7 +252,7 @@ void factor_vm::load_image(vm_parameters* p) {
load_data_heap(file, &h, p);
load_code_heap(file, &h, p);
safe_fclose(file);
raw_fclose(file);
init_objects(&h);

View File

@ -13,6 +13,34 @@ The Factor library provides platform-specific code for Unix and Windows
with many more capabilities so these words are not usually used in
normal operation. */
size_t raw_fread(void* ptr, size_t size, size_t nitems, FILE* stream) {
size_t items_read = 0;
size_t ret = 0;
do {
ret = fread((void*)((int*)ptr + items_read * size), size,
nitems - items_read, stream);
if (ret == 0) {
if (feof(stream))
break;
else if (errno != EINTR) {
return 0;
}
}
items_read += ret;
} while (items_read != nitems);
return items_read;
}
// Call fclose() once only. Issues #1335, #908.
int raw_fclose(FILE* stream) {
if (fclose(stream) == EOF && errno != EINTR)
return -1;
return 0;
}
void factor_vm::init_c_io() {
special_objects[OBJ_STDIN] = allot_alien(false_object, (cell)stdin);
special_objects[OBJ_STDOUT] = allot_alien(false_object, (cell)stdout);
@ -56,22 +84,10 @@ int factor_vm::safe_fgetc(FILE* stream) {
size_t factor_vm::safe_fread(void* ptr, size_t size, size_t nitems,
FILE* stream) {
size_t items_read = 0;
size_t ret = 0;
do {
ret = fread((void*)((int*)ptr + items_read * size), size,
nitems - items_read, stream);
if (ret == 0) {
if (feof(stream))
break;
else
io_error_if_not_EINTR();
}
items_read += ret;
} while (items_read != nitems);
return items_read;
size_t ret = raw_fread(ptr, size, nitems, stream);
if (!ret)
io_error_if_not_EINTR();
return ret;
}
void factor_vm::safe_fputc(int c, FILE* stream) {
@ -142,10 +158,9 @@ void factor_vm::safe_fflush(FILE* stream) {
}
}
// Call fclose() once only. Issues #1335, #908.
void factor_vm::safe_fclose(FILE* stream) {
if (fclose(stream) == EOF && errno != EINTR)
general_error(ERROR_IO, tag_fixnum(errno), false_object);
if (raw_fclose(stream) == -1)
io_error_if_not_EINTR();
}
void factor_vm::primitive_fopen() {

View File

@ -1,5 +1,9 @@
namespace factor {
/* Safe IO functions that does not throw Factor errors. */
int raw_fclose(FILE* stream);
size_t raw_fread(void* ptr, size_t size, size_t nitems, FILE* stream);
/* Platform specific primitives */
VM_C_API int err_no();