diff --git a/src/c/cinit.d b/src/c/cinit.d index a9b868c71..73fbb93f5 100644 --- a/src/c/cinit.d +++ b/src/c/cinit.d @@ -98,8 +98,11 @@ extern cl_object si_signal_simple_error(cl_narg narg, cl_object condition, cl_object continuable, cl_object format, cl_object format_args, ...) { ecl_va_list args; + cl_object rest; ecl_va_start(args, format_args, narg, 4); - return cl_apply(6, @'si::signal-simple-error', condition, continuable, format, format_args, cl_grab_rest_args(args)); + rest = cl_grab_rest_args(args); + return cl_apply(6, @'si::signal-simple-error', condition, continuable, + format, format_args, rest); } extern cl_object diff --git a/src/c/error.d b/src/c/error.d index 2e4321161..505480d19 100644 --- a/src/c/error.d +++ b/src/c/error.d @@ -468,6 +468,13 @@ FEdivision_by_zero(cl_object x, cl_object y) @':operands', cl_list(2, x, y)); } +cl_object +_ecl_strerror(int code) +{ + const char *error = strerror(code); + return make_base_string_copy(error); +} + /************************************* * Errors generated by the C library * *************************************/ @@ -480,14 +487,14 @@ void FElibc_error(const char *msg, int narg, ...) { ecl_va_list args; - cl_object rest; - const char *error = strerror(errno); + cl_object rest, error = _ecl_strerror(errno); ecl_va_start(args, narg, narg, 0); rest = cl_grab_rest_args(args); - FEerror("~?~%C library explanation: ~A.", 3, make_constant_base_string(msg), rest, - make_constant_base_string(error)); + FEerror("~?~%C library explanation: ~A.", 3, + make_constant_base_string(msg), rest, + error); } #if defined(ECL_MS_WINDOWS_HOST) || defined(cygwin) diff --git a/src/c/unixfsys.d b/src/c/unixfsys.d index bb12edf09..da1e19552 100644 --- a/src/c/unixfsys.d +++ b/src/c/unixfsys.d @@ -482,9 +482,16 @@ ecl_file_len(int f) } /* if the file already exists */ if (if_exists == @':error') { - if_exists = CEerror(@':supersede', - "When trying to rename ~S, ~S already exists", - 2, oldn, new_filename); + const char *msg = "When trying to rename ~S, ~S already exists"; + if_exists = + si_signal_simple_error + (6, @'file-error', /* condition */ + @':supersede', /* continuable */ + /* format */ + ecl_make_constant_base_string(msg,strlen(msg)), + cl_list(2, oldn, new_filename), /* format args */ + @':pathname', /* file-error options */ + new_filename); if (if_exists == ECL_T) if_exists= @':error'; } if (if_exists == ECL_NIL) { @@ -547,7 +554,17 @@ ecl_file_len(int f) } FAILURE_CLOBBER: ecl_enable_interrupts(); - FElibc_error("Cannot rename the file ~S to ~S.", 2, oldn, newn); + { + cl_object c_error = _ecl_strerror(errno); + const char *msg = "Unable to rename file ~S to ~S.~%C library error: ~S"; + si_signal_simple_error + (6, @'file-error', /* condition */ + ECL_NIL, /* continuable */ + ecl_make_constant_base_string(msg,strlen(msg)), /* format */ + cl_list(3, oldn, newn, c_error), /* format args */ + @':pathname', /* file-error options */ + oldn); + } SUCCESS: ecl_enable_interrupts(); @@ -568,7 +585,7 @@ cl_delete_file(cl_object file) cl_object path = cl_pathname(file); int isdir = directory_pathname_p(path); cl_object filename = coerce_to_posix_filename(path); - int ok; + int ok, code; ecl_disable_interrupts(); ok = (isdir? rmdir : unlink)((char*)filename->base_string.self); @@ -577,9 +594,16 @@ cl_delete_file(cl_object file) if (ok < 0) { const char *msg = isdir? - "Cannot delete the file ~S." : - "Cannot delete the directory ~S."; - FElibc_error(msg, 1, file); + "Cannot delete the file ~S.~%C library error: ~S" : + "Cannot delete the directory ~S.~%C library error: ~S"; + cl_object c_error = _ecl_strerror(errno); + si_signal_simple_error + (6, @'file-error', /* condition */ + ECL_T, /* continuable */ + ecl_make_constant_base_string(msg,strlen(msg)), /* format */ + cl_list(2, file, c_error), /* format args */ + @':pathname', /* file-error options */ + file); } @(return ECL_T) } @@ -609,8 +633,18 @@ cl_file_author(cl_object file) { cl_object output, filename = coerce_to_posix_filename(file); struct stat filestatus; - if (safe_stat((char*)filename->base_string.self, &filestatus) < 0) - FElibc_error("Cannot get the file status of ~S.", 1, file); + if (safe_stat((char*)filename->base_string.self, &filestatus) < 0) { + const char *msg = "Unable to read file author for ~S." + "~%C library error: ~S"; + cl_object c_error = _ecl_strerror(errno); + si_signal_simple_error + (6, @'file-error', /* condition */ + ECL_T, /* continuable */ + ecl_make_constant_base_string(msg,strlen(msg)), /* format */ + cl_list(2, file, c_error), /* format args */ + @':pathname', /* file-error options */ + file); + } #ifdef HAVE_PWD_H { struct passwd *pwent; @@ -1002,11 +1036,21 @@ si_get_library_pathname(void) namestring = ecl_namestring(directory, ECL_NAMESTRING_TRUNCATE_IF_ERROR | ECL_NAMESTRING_FORCE_BASE_STRING); - if (safe_chdir((char*)namestring->base_string.self, ECL_NIL) < 0) - FElibc_error("Can't change the current directory to ~A", - 1, namestring); - if (change_d_p_d != ECL_NIL) + if (safe_chdir((char*)namestring->base_string.self, ECL_NIL) < 0) { + cl_object c_error = _ecl_strerror(errno); + const char *msg = "Can't change the current directory to ~A." + "~%C library error: ~S"; + si_signal_simple_error + (6, @'file-error', /* condition */ + ECL_T, /* continuable */ + /* format */ + ecl_make_constant_base_string(msg,strlen(msg)), + cl_list(2, directory, c_error), /* format args */ + @':pathname', /* file-error options */ + directory); + } else if (change_d_p_d != ECL_NIL) { ECL_SETQ(the_env, @'*default-pathname-defaults*', directory); + } @(return previous) @) @@ -1043,8 +1087,19 @@ si_mkdir(cl_object directory, cl_object mode) #endif ecl_enable_interrupts(); - if (ecl_unlikely(ok < 0)) - FElibc_error("Could not create directory ~S", 1, filename); + if (ecl_unlikely(ok < 0)) { + cl_object c_error = _ecl_strerror(errno); + const char *msg = "Could not create directory ~S" + "~%C library error: ~S"; + si_signal_simple_error + (6, @'file-error', /* condition */ + ECL_T, /* continuable */ + /* format */ + ecl_make_constant_base_string(msg,strlen(msg)), + cl_list(2, filename, c_error), /* format args */ + @':pathname', /* file-error options */ + filename); + } @(return filename) } @@ -1158,8 +1213,17 @@ si_chmod(cl_object file, cl_object mode) mode_t code = ecl_to_uint32_t(mode); cl_object filename = coerce_to_posix_filename(file); unlikely_if (chmod((char*)filename->base_string.self, code)) { - FElibc_error("Unable to change mode of file~%~S~%to value ~O", - 2, file, mode); + cl_object c_error = _ecl_strerror(errno); + const char *msg = "Unable to change mode of file ~S to value ~O" + "~%C library error: ~S"; + si_signal_simple_error + (6, @'file-error', /* condition */ + ECL_T, /* continuable */ + /* format */ + ecl_make_constant_base_string(msg,strlen(msg)), + cl_list(3, file, mode, c_error), /* format args */ + @':pathname', /* file-error options */ + file); } @(return) } diff --git a/src/h/internal.h b/src/h/internal.h index f2ba84262..00c454c77 100755 --- a/src/h/internal.h +++ b/src/h/internal.h @@ -133,6 +133,7 @@ typedef struct cl_compiler_env *cl_compiler_env_ptr; /* error.d */ extern void _ecl_unexpected_return() ecl_attr_noreturn; +extern cl_object _ecl_strerror(int code); /* eval.d */