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