diff --git a/vm/image.cpp b/vm/image.cpp index b394885730..fe607ad747 100644 --- a/vm/image.cpp +++ b/vm/image.cpp @@ -200,12 +200,26 @@ bool factor_vm::read_embedded_image_footer(FILE* file, return footer->magic == image_magic; } +char *threadsafe_strerror(int errnum) { + char *buf = (char *) malloc(STRERROR_BUFFER_SIZE); + if(!buf) { + fatal_error("Out of memory in threadsafe_strerror", 0); + } + int ret = THREADSAFE_STRERROR(errnum, buf, STRERROR_BUFFER_SIZE); + if(ret != 0) { + std::cout << "Truncated output from THREADSAFE_STRERROR, error code:" << errnum << ", ret: " << ret << std::endl; + } + return buf; +} + FILE* factor_vm::open_image(vm_parameters* p) { if (p->embedded_image) { FILE* file = OPEN_READ(p->executable_path); if (file == NULL) { std::cout << "Cannot open embedded image" << std::endl; - std::cout << strerror(errno) << std::endl; + char *msg = threadsafe_strerror(errno); + std::cout << "strerror: " << msg << std::endl; + free(msg); exit(1); } embedded_image_footer footer; @@ -225,7 +239,9 @@ void factor_vm::load_image(vm_parameters* p) { FILE* file = open_image(p); if (file == NULL) { std::cout << "Cannot open image file: " << p->image_path << std::endl; - std::cout << strerror(errno) << std::endl; + char *msg = threadsafe_strerror(errno); + std::cout << "strerror: " << msg << std::endl; + free(msg); exit(1); } @@ -265,7 +281,9 @@ bool factor_vm::save_image(const vm_char* saving_filename, file = OPEN_WRITE(saving_filename); if (file == NULL) { std::cout << "Cannot open image file for writing: " << saving_filename << std::endl; - std::cout << strerror(errno) << std::endl; + char *msg = threadsafe_strerror(errno); + std::cout << "strerror: " << msg << std::endl; + free(msg); return false; } @@ -295,8 +313,12 @@ bool factor_vm::save_image(const vm_char* saving_filename, ok = false; safe_fclose(file); - if (!ok) - std::cout << "save-image failed: " << strerror(errno) << std::endl; + if (!ok) { + std::cout << "save-image failed." << std::endl; + char *msg = threadsafe_strerror(errno); + std::cout << "strerror: " << msg << std::endl; + free(msg); + } else move_file(saving_filename, filename); diff --git a/vm/image.hpp b/vm/image.hpp index efc0c82856..e1a71c6781 100644 --- a/vm/image.hpp +++ b/vm/image.hpp @@ -3,6 +3,8 @@ namespace factor { static const cell image_magic = 0x0f0e0d0c; static const cell image_version = 4; +const size_t STRERROR_BUFFER_SIZE = 1024; + struct embedded_image_footer { cell magic; cell image_offset; diff --git a/vm/os-genunix.hpp b/vm/os-genunix.hpp index 82773a7944..dee563a968 100644 --- a/vm/os-genunix.hpp +++ b/vm/os-genunix.hpp @@ -5,5 +5,4 @@ namespace factor { void early_init(); const char* vm_executable_path(); const char* default_image_path(); - } diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index d5122545e9..2b816b361a 100644 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -502,4 +502,8 @@ void abort() { ::abort(); } +int THREADSAFE_STRERROR(int errnum, char *buf, size_t buflen) { + return strerror_r(errnum, buf, buflen); +} + } diff --git a/vm/os-unix.hpp b/vm/os-unix.hpp index d6b7bea93c..036399f91b 100644 --- a/vm/os-unix.hpp +++ b/vm/os-unix.hpp @@ -46,4 +46,6 @@ void move_file(const vm_char* path1, const vm_char* path2); static inline void breakpoint() { __builtin_trap(); } +int THREADSAFE_STRERROR(int errnum, char *buf, size_t buflen); + } diff --git a/vm/os-windows.cpp b/vm/os-windows.cpp index f83f67f91d..4fee07f7e9 100644 --- a/vm/os-windows.cpp +++ b/vm/os-windows.cpp @@ -373,4 +373,6 @@ void factor_vm::end_sampling_profiler_timer() { void abort() { ::abort(); } +int THREADSAFE_STRERROR(int errnum, char *buf, size_t buflen) { + return strerror_s(buf, buflen, errnum); } diff --git a/vm/os-windows.hpp b/vm/os-windows.hpp index 2dab596c4d..de00b89f0f 100644 --- a/vm/os-windows.hpp +++ b/vm/os-windows.hpp @@ -93,4 +93,6 @@ inline static void breakpoint() { DebugBreak(); } #define FUNCTION_TOC_POINTER(ptr) ptr extern HANDLE boot_thread; + +int THREADSAFE_STRERROR(int errnum, char *buf, size_t buflen); }