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
							parent
							
								
									9d289e35f4
								
							
						
					
					
						commit
						f1ca83524a
					
				| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										53
									
								
								vm/io.cpp
								
								
								
								
							
							
						
						
									
										53
									
								
								vm/io.cpp
								
								
								
								
							| 
						 | 
				
			
			@ -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() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue