mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-20 11:32:35 -08:00
delete-file, rename-file, chdir, mkdir and chmod now signal file-errors
This commit is contained in:
parent
5f4c7eee93
commit
dfc94901c4
4 changed files with 98 additions and 23 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
100
src/c/unixfsys.d
100
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue