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
Björn Lindqvist 2015-09-29 23:08:45 +02:00
parent 40eb664425
commit 2536b6cd93
8 changed files with 12 additions and 19 deletions

View File

@ -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();

View File

@ -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:

View File

@ -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

View File

@ -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) {

View File

@ -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(); }

View File

@ -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() {}

View File

@ -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);

View File

@ -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);