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 close_console();
 | 
				
			||||||
void lock_console();
 | 
					void lock_console();
 | 
				
			||||||
void unlock_console();
 | 
					void unlock_console();
 | 
				
			||||||
 | 
					bool move_file(const vm_char* path1, const vm_char* path2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ignore_ctrl_c();
 | 
					void ignore_ctrl_c();
 | 
				
			||||||
void handle_ctrl_c();
 | 
					void handle_ctrl_c();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,8 +225,10 @@ bool factor_vm::save_image(const vm_char* saving_filename,
 | 
				
			||||||
    goto error;
 | 
					    goto error;
 | 
				
			||||||
  if (safe_fwrite((void*)code->allocator->start, h.code_size, 1, file) != 1)
 | 
					  if (safe_fwrite((void*)code->allocator->start, h.code_size, 1, file) != 1)
 | 
				
			||||||
    goto error;
 | 
					    goto error;
 | 
				
			||||||
  safe_fclose(file);
 | 
					  if (raw_fclose(file) == -1)
 | 
				
			||||||
  move_file(saving_filename, filename);
 | 
					    goto error;
 | 
				
			||||||
 | 
					  if (!move_file(saving_filename, filename))
 | 
				
			||||||
 | 
					    goto error;
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 error:
 | 
					 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);
 | 
					  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;
 | 
					  FILE* file;
 | 
				
			||||||
  for (;;) {
 | 
					  for (;;) {
 | 
				
			||||||
    file = fopen(filename, mode);
 | 
					    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() {
 | 
					void factor_vm::primitive_fopen() {
 | 
				
			||||||
  data_root<byte_array> mode(ctx->pop(), this);
 | 
					  data_root<byte_array> mode(ctx->pop(), this);
 | 
				
			||||||
  data_root<byte_array> path(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() {
 | 
					void factor_vm::primitive_fclose() {
 | 
				
			||||||
  FILE* file = pop_file_handle();
 | 
					  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
 | 
					/* 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));
 | 
					  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;
 | 
					  int ret = 0;
 | 
				
			||||||
  do {
 | 
					  do {
 | 
				
			||||||
    ret = rename((path1), (path2));
 | 
					    ret = rename((path1), (path2));
 | 
				
			||||||
  } while (ret < 0 && errno == EINTR);
 | 
					  } while (ret < 0 && errno == EINTR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ret < 0)
 | 
					  return ret == 0;
 | 
				
			||||||
    general_error(ERROR_IO, tag_fixnum(errno), false_object);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void check_ENOMEM(const char* msg) {
 | 
					void check_ENOMEM(const char* msg) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,6 @@ inline static THREADHANDLE thread_id() { return pthread_self(); }
 | 
				
			||||||
uint64_t nano_count();
 | 
					uint64_t nano_count();
 | 
				
			||||||
void sleep_nanos(uint64_t nsec);
 | 
					void sleep_nanos(uint64_t nsec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void move_file(const vm_char* path1, const vm_char* path2);
 | 
					 | 
				
			||||||
void check_ENOMEM(const char* msg);
 | 
					void check_ENOMEM(const char* msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void breakpoint() { __builtin_trap(); }
 | 
					static inline void breakpoint() { __builtin_trap(); }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,9 +137,8 @@ long getpagesize() {
 | 
				
			||||||
  return g_pagesize;
 | 
					  return g_pagesize;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void factor_vm::move_file(const vm_char* path1, const vm_char* path2) {
 | 
					bool move_file(const vm_char* path1, const vm_char* path2) {
 | 
				
			||||||
  if (MoveFileEx((path1), (path2), MOVEFILE_REPLACE_EXISTING) == false)
 | 
					  return MoveFileEx((path1), (path2), MOVEFILE_REPLACE_EXISTING);
 | 
				
			||||||
    general_error(ERROR_IO, tag_fixnum(GetLastError()), false_object);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void factor_vm::init_signals() {}
 | 
					void factor_vm::init_signals() {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,7 +72,6 @@ inline static void early_init() {}
 | 
				
			||||||
uint64_t nano_count();
 | 
					uint64_t nano_count();
 | 
				
			||||||
void sleep_nanos(uint64_t nsec);
 | 
					void sleep_nanos(uint64_t nsec);
 | 
				
			||||||
long getpagesize();
 | 
					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,
 | 
					VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void* frame, PCONTEXT c,
 | 
				
			||||||
                                void* dispatch);
 | 
					                                void* dispatch);
 | 
				
			||||||
THREADHANDLE start_thread(void* (*start_routine)(void*), void* args);
 | 
					THREADHANDLE start_thread(void* (*start_routine)(void*), void* args);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -552,7 +552,6 @@ struct factor_vm {
 | 
				
			||||||
  int safe_ftell(FILE* stream);
 | 
					  int safe_ftell(FILE* stream);
 | 
				
			||||||
  void safe_fseek(FILE* stream, off_t offset, int whence);
 | 
					  void safe_fseek(FILE* stream, off_t offset, int whence);
 | 
				
			||||||
  void safe_fflush(FILE* stream);
 | 
					  void safe_fflush(FILE* stream);
 | 
				
			||||||
  void safe_fclose(FILE* stream);
 | 
					 | 
				
			||||||
  void primitive_fopen();
 | 
					  void primitive_fopen();
 | 
				
			||||||
  FILE* pop_file_handle();
 | 
					  FILE* pop_file_handle();
 | 
				
			||||||
  FILE* peek_file_handle();
 | 
					  FILE* peek_file_handle();
 | 
				
			||||||
| 
						 | 
					@ -731,7 +730,6 @@ struct factor_vm {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // os-*
 | 
					  // os-*
 | 
				
			||||||
  void primitive_existsp();
 | 
					  void primitive_existsp();
 | 
				
			||||||
  void move_file(const vm_char* path1, const vm_char* path2);
 | 
					 | 
				
			||||||
  void init_ffi();
 | 
					  void init_ffi();
 | 
				
			||||||
  void ffi_dlopen(dll* dll);
 | 
					  void ffi_dlopen(dll* dll);
 | 
				
			||||||
  cell ffi_dlsym(dll* dll, symbol_char* symbol);
 | 
					  cell ffi_dlsym(dll* dll, symbol_char* symbol);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue