VM: fix move_file called from save_image
save_image() shouldn't throw exceptions because if the 'then_die' argument is t it would leave factor in an inconsistent state. So therefore move_file() should be fixed and raw_fclose() called instead of safe_fclose().db4
							parent
							
								
									40eb664425
								
							
						
					
					
						commit
						2536b6cd93
					
				| 
						 | 
				
			
			@ -9,6 +9,7 @@ void open_console();
 | 
			
		|||
void close_console();
 | 
			
		||||
void lock_console();
 | 
			
		||||
void unlock_console();
 | 
			
		||||
bool move_file(const vm_char* path1, const vm_char* path2);
 | 
			
		||||
 | 
			
		||||
void ignore_ctrl_c();
 | 
			
		||||
void handle_ctrl_c();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -225,8 +225,10 @@ bool factor_vm::save_image(const vm_char* saving_filename,
 | 
			
		|||
    goto error;
 | 
			
		||||
  if (safe_fwrite((void*)code->allocator->start, h.code_size, 1, file) != 1)
 | 
			
		||||
    goto error;
 | 
			
		||||
  safe_fclose(file);
 | 
			
		||||
  move_file(saving_filename, filename);
 | 
			
		||||
  if (raw_fclose(file) == -1)
 | 
			
		||||
    goto error;
 | 
			
		||||
  if (!move_file(saving_filename, filename))
 | 
			
		||||
    goto error;
 | 
			
		||||
  return true;
 | 
			
		||||
 | 
			
		||||
 error:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								vm/io.cpp
								
								
								
								
							
							
						
						
									
										10
									
								
								vm/io.cpp
								
								
								
								
							| 
						 | 
				
			
			@ -56,7 +56,7 @@ void factor_vm::io_error_if_not_EINTR() {
 | 
			
		|||
  general_error(ERROR_IO, tag_fixnum(errno), false_object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FILE* factor_vm::safe_fopen(char* filename, char* mode) {
 | 
			
		||||
FILE* factor_vm::safe_fopen(char* filename, const char* mode) {
 | 
			
		||||
  FILE* file;
 | 
			
		||||
  for (;;) {
 | 
			
		||||
    file = fopen(filename, mode);
 | 
			
		||||
| 
						 | 
				
			
			@ -159,11 +159,6 @@ void factor_vm::safe_fflush(FILE* stream) {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::safe_fclose(FILE* stream) {
 | 
			
		||||
  if (raw_fclose(stream) == -1)
 | 
			
		||||
    io_error_if_not_EINTR();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::primitive_fopen() {
 | 
			
		||||
  data_root<byte_array> mode(ctx->pop(), this);
 | 
			
		||||
  data_root<byte_array> path(ctx->pop(), this);
 | 
			
		||||
| 
						 | 
				
			
			@ -245,7 +240,8 @@ void factor_vm::primitive_fflush() {
 | 
			
		|||
 | 
			
		||||
void factor_vm::primitive_fclose() {
 | 
			
		||||
  FILE* file = pop_file_handle();
 | 
			
		||||
  safe_fclose(file);
 | 
			
		||||
  if (raw_fclose(file) == -1)
 | 
			
		||||
    io_error_if_not_EINTR();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function is used by FFI I/O. Accessing the errno global directly is
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,14 +65,13 @@ void factor_vm::primitive_existsp() {
 | 
			
		|||
  ctx->push(tag_boolean(stat(path, &sb) >= 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::move_file(const vm_char* path1, const vm_char* path2) {
 | 
			
		||||
bool move_file(const vm_char* path1, const vm_char* path2) {
 | 
			
		||||
  int ret = 0;
 | 
			
		||||
  do {
 | 
			
		||||
    ret = rename((path1), (path2));
 | 
			
		||||
  } while (ret < 0 && errno == EINTR);
 | 
			
		||||
 | 
			
		||||
  if (ret < 0)
 | 
			
		||||
    general_error(ERROR_IO, tag_fixnum(errno), false_object);
 | 
			
		||||
  return ret == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void check_ENOMEM(const char* msg) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,7 +51,6 @@ inline static THREADHANDLE thread_id() { return pthread_self(); }
 | 
			
		|||
uint64_t nano_count();
 | 
			
		||||
void sleep_nanos(uint64_t nsec);
 | 
			
		||||
 | 
			
		||||
void move_file(const vm_char* path1, const vm_char* path2);
 | 
			
		||||
void check_ENOMEM(const char* msg);
 | 
			
		||||
 | 
			
		||||
static inline void breakpoint() { __builtin_trap(); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,9 +137,8 @@ long getpagesize() {
 | 
			
		|||
  return g_pagesize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::move_file(const vm_char* path1, const vm_char* path2) {
 | 
			
		||||
  if (MoveFileEx((path1), (path2), MOVEFILE_REPLACE_EXISTING) == false)
 | 
			
		||||
    general_error(ERROR_IO, tag_fixnum(GetLastError()), false_object);
 | 
			
		||||
bool move_file(const vm_char* path1, const vm_char* path2) {
 | 
			
		||||
  return MoveFileEx((path1), (path2), MOVEFILE_REPLACE_EXISTING);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::init_signals() {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,7 +72,6 @@ inline static void early_init() {}
 | 
			
		|||
uint64_t nano_count();
 | 
			
		||||
void sleep_nanos(uint64_t nsec);
 | 
			
		||||
long getpagesize();
 | 
			
		||||
void move_file(const vm_char* path1, const vm_char* path2);
 | 
			
		||||
VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void* frame, PCONTEXT c,
 | 
			
		||||
                                void* dispatch);
 | 
			
		||||
THREADHANDLE start_thread(void* (*start_routine)(void*), void* args);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -552,7 +552,6 @@ struct factor_vm {
 | 
			
		|||
  int safe_ftell(FILE* stream);
 | 
			
		||||
  void safe_fseek(FILE* stream, off_t offset, int whence);
 | 
			
		||||
  void safe_fflush(FILE* stream);
 | 
			
		||||
  void safe_fclose(FILE* stream);
 | 
			
		||||
  void primitive_fopen();
 | 
			
		||||
  FILE* pop_file_handle();
 | 
			
		||||
  FILE* peek_file_handle();
 | 
			
		||||
| 
						 | 
				
			
			@ -731,7 +730,6 @@ struct factor_vm {
 | 
			
		|||
 | 
			
		||||
  // os-*
 | 
			
		||||
  void primitive_existsp();
 | 
			
		||||
  void move_file(const vm_char* path1, const vm_char* path2);
 | 
			
		||||
  void init_ffi();
 | 
			
		||||
  void ffi_dlopen(dll* dll);
 | 
			
		||||
  cell ffi_dlsym(dll* dll, symbol_char* symbol);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue