summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib.c4
-rw-r--r--lib.h1
-rw-r--r--parser.c3
-rw-r--r--socket.c5
-rw-r--r--stream.c58
-rw-r--r--sysif.c129
-rw-r--r--sysif.h1
-rw-r--r--txr.16
-rw-r--r--unwind.c3
9 files changed, 144 insertions, 66 deletions
diff --git a/lib.c b/lib.c
index 342e4837..2446bf17 100644
--- a/lib.c
+++ b/lib.c
@@ -108,6 +108,7 @@ val error_s, type_error_s, internal_error_s, panic_s;
val numeric_error_s, range_error_s;
val query_error_s, file_error_s, process_error_s, syntax_error_s;
val timeout_error_s, system_error_s, alloc_error_s;
+val path_not_found_s, path_exists_s, path_permission_s;
val warning_s, defr_warning_s, restart_s, continue_s;
val gensym_counter_s, nullify_s, from_list_s, lambda_set_s, length_s;
val rplaca_s, rplacd_s, seq_iter_s;
@@ -10844,6 +10845,9 @@ static void obj_init(void)
system_error_s = intern(lit("system-error"), user_package);
timeout_error_s = intern(lit("timeout-error"), user_package);
alloc_error_s = intern(lit("alloc-error"), user_package);
+ path_not_found_s = intern(lit("path-not-found"), user_package);
+ path_exists_s = intern(lit("path-exists"), user_package);
+ path_permission_s = intern(lit("path-permission"), user_package);
assert_s = intern(lit("assert"), user_package);
warning_s = intern(lit("warning"), user_package);
defr_warning_s = intern(lit("defr-warning"), user_package);
diff --git a/lib.h b/lib.h
index 79137610..e836b190 100644
--- a/lib.h
+++ b/lib.h
@@ -497,6 +497,7 @@ extern val error_s, type_error_s, internal_error_s, panic_s;
extern val numeric_error_s, range_error_s;
extern val query_error_s, file_error_s, process_error_s, syntax_error_s;
extern val timeout_error_s, system_error_s, alloc_error_s;
+extern val path_not_found_s, path_exists_s, path_permission_s;
extern val warning_s, defr_warning_s, restart_s, continue_s;
extern val gensym_counter_s;
extern val rplaca_s, rplacd_s, seq_iter_s;
diff --git a/parser.c b/parser.c
index 7662614e..89efaca4 100644
--- a/parser.c
+++ b/parser.c
@@ -498,7 +498,8 @@ void open_txr_file(val spec_file, val *txr_lisp_p, val *name, val *stream)
#ifdef ENOENT
except:
#endif
- uw_throwf(file_error_s, lit("unable to open ~a"), spec_file_try, nao);
+ uw_throwf(errno_to_file_error(errno),
+ lit("unable to open ~a"), spec_file_try, nao);
}
*stream = make_stdio_stream(in, spec_file_try);
diff --git a/socket.c b/socket.c
index 7c68b057..79df7b7e 100644
--- a/socket.c
+++ b/socket.c
@@ -770,9 +770,10 @@ static val open_sockfd(val fd, val family, val type, val mode_str)
FILE *f = (errno = 0, w_fdopen(c_num(fd), c_str(normalize_mode(&m, mode_str, m_rpb))));
if (!f) {
+ int eno = errno;
close(c_num(fd));
- uw_throwf(file_error_s, lit("error creating stream for socket ~a: ~d/~s"),
- fd, num(errno), string_utf8(strerror(errno)), nao);
+ uw_throwf(errno_to_file_error(eno), lit("error creating stream for socket ~a: ~d/~s"),
+ fd, num(eno), string_utf8(strerror(eno)), nao);
}
return set_mode_props(m, make_sock_stream(f, family, type));
diff --git a/stream.c b/stream.c
index 1289af9a..5381024c 100644
--- a/stream.c
+++ b/stream.c
@@ -3881,9 +3881,12 @@ val open_directory(val path)
{
DIR *d = w_opendir(c_str(path));
- if (!d)
- uw_throwf(file_error_s, lit("error opening directory ~a: ~d/~s"),
- path, num(errno), string_utf8(strerror(errno)), nao);
+ if (!d) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno),
+ lit("error opening directory ~a: ~d/~s"),
+ path, num(eno), string_utf8(strerror(eno)), nao);
+ }
return make_dir_stream(d);
}
@@ -3893,9 +3896,11 @@ val open_file(val path, val mode_str)
struct stdio_mode m, m_r = stdio_mode_init_r;
FILE *f = w_fopen(c_str(path), c_str(normalize_mode(&m, mode_str, m_r)));
- if (!f)
- uw_throwf(file_error_s, lit("error opening ~a: ~d/~s"),
- path, num(errno), string_utf8(strerror(errno)), nao);
+ if (!f) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("error opening ~a: ~d/~s"),
+ path, num(eno), string_utf8(strerror(eno)), nao);
+ }
return set_mode_props(m, make_stdio_stream(f, path));
}
@@ -3906,9 +3911,10 @@ val open_fileno(val fd, val mode_str)
FILE *f = (errno = 0, w_fdopen(c_num(fd), c_str(normalize_mode(&m, mode_str, m_r))));
if (!f) {
+ int eno = errno;
close(c_num(fd));
- uw_throwf(file_error_s, lit("error opening descriptor ~a: ~d/~s"),
- fd, num(errno), string_utf8(strerror(errno)), nao);
+ uw_throwf(errno_to_file_error(eno), lit("error opening descriptor ~a: ~d/~s"),
+ fd, num(eno), string_utf8(strerror(eno)), nao);
}
return set_mode_props(m, make_stdio_stream(f, format(nil,
@@ -4020,9 +4026,11 @@ val open_command(val path, val mode_str)
f = w_popen(c_str(path), c_str(mode));
- if (!f)
- uw_throwf(file_error_s, lit("error opening pipe ~a: ~d/~s"),
- path, num(errno), string_utf8(strerror(errno)), nao);
+ if (!f) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("error opening pipe ~a: ~d/~s"),
+ path, num(eno), string_utf8(strerror(eno)), nao);
+ }
uw_unwind {
fds_restore(&sfds);
@@ -4063,9 +4071,11 @@ val open_process(val name, val mode_str, val args)
argv = coerce(char **, chk_xalloc(nargs + 1, sizeof *argv, self));
if (pipe(fd) == -1) {
+ int eno = errno;
free(argv);
- uw_throwf(file_error_s, lit("opening pipe ~a, pipe syscall failed: ~d/~s"),
- name, num(errno), string_utf8(strerror(errno)), nao);
+ uw_throwf(errno_to_file_error(eno),
+ lit("opening pipe ~a, pipe syscall failed: ~d/~s"),
+ name, num(eno), string_utf8(strerror(eno)), nao);
}
for (i = 0, iter = cons(name, args); iter; i++, iter = cdr(iter)) {
@@ -4080,7 +4090,7 @@ val open_process(val name, val mode_str, val args)
for (i = 0; i < nargs; i++)
free(argv[i]);
free(argv);
- uw_throwf(file_error_s, lit("opening pipe ~a, fork syscall failed: ~d/~s"),
+ uw_throwf(process_error_s, lit("opening pipe ~a, fork syscall failed: ~d/~s"),
name, num(errno), string_utf8(strerror(errno)), nao);
}
@@ -4276,7 +4286,7 @@ static val run(val name, val args)
for (i = 0; i < nargs; i++)
free(argv[i]);
free(argv);
- uw_throwf(file_error_s, lit("opening process ~a, fork syscall failed: ~d/~s"),
+ uw_throwf(process_error_s, lit("opening process ~a, fork syscall failed: ~d/~s"),
name, num(errno), string_utf8(strerror(errno)), nao);
}
@@ -4369,9 +4379,11 @@ static val sh(val command)
val remove_path(val path, val throw_on_error)
{
if (w_remove(c_str(path)) < 0) {
- if (default_null_arg(throw_on_error) || errno != ENOENT)
- uw_throwf(file_error_s, lit("trying to remove ~a: ~d/~s"),
- path, num(errno), string_utf8(strerror(errno)), nao);
+ if (default_null_arg(throw_on_error) || errno != ENOENT) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("trying to remove ~a: ~d/~s"),
+ path, num(eno), string_utf8(strerror(eno)), nao);
+ }
return nil;
}
@@ -4380,9 +4392,13 @@ val remove_path(val path, val throw_on_error)
val rename_path(val from, val to)
{
- if (w_rename(c_str(from), c_str(to)) < 0)
- uw_throwf(file_error_s, lit("trying to rename ~a to ~a: ~d/~s"),
- from, to, num(errno), string_utf8(strerror(errno)), nao);
+ if (w_rename(c_str(from), c_str(to)) < 0) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno),
+ lit("trying to rename ~a to ~a: ~d/~s"),
+ from, to, num(eno), string_utf8(strerror(eno)), nao);
+ }
+
return t;
}
diff --git a/sysif.c b/sysif.c
index 04ed6ea5..3556b262 100644
--- a/sysif.c
+++ b/sysif.c
@@ -235,6 +235,25 @@ static val env_hash(void)
return hash;
}
+val errno_to_file_error(int err)
+{
+ switch (err) {
+#ifdef ENOENT
+ case ENOENT: return path_not_found_s;
+#endif
+#ifdef EEXIST
+ case EEXIST: return path_exists_s;
+#endif
+#ifdef EPERM
+ case EPERM: return path_permission_s;
+#endif
+#ifdef EACCES
+ case EACCES: return path_permission_s;
+#endif
+ default: return file_error_s;
+ }
+}
+
#if HAVE_MKDIR
static val mkdir_wrap(val path, val mode)
{
@@ -243,9 +262,11 @@ static val mkdir_wrap(val path, val mode)
int err = mkdir(u8path, cmode);
free(u8path);
- if (err < 0)
- uw_throwf(file_error_s, lit("mkdir ~a: ~d/~s"),
- path, num(errno), string_utf8(strerror(errno)), nao);
+ if (err < 0) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("mkdir ~a: ~d/~s"),
+ path, num(eno), string_utf8(strerror(eno)), nao);
+ }
return t;
}
@@ -255,9 +276,11 @@ static val mkdir_wrap(val path, val mode)
int err = _wmkdir(c_str(path));
(void) mode;
- if (err < 0)
- uw_throwf(file_error_s, lit("mkdir ~a: ~d/~s"),
- path, num(errno), string_utf8(strerror(errno)), nao);
+ if (err < 0) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("mkdir ~a: ~d/~s"),
+ path, num(eno), string_utf8(strerror(eno)), nao);
+ }
return t;
}
@@ -316,10 +339,12 @@ static val ensure_dir(val path, val mode)
partial_path, sep, pop(&split_path), nao);
}
- if (ret != t)
- uw_throwf(file_error_s,
+ if (ret != t) {
+ int eno = c_num(ret);
+ uw_throwf(errno_to_file_error(eno),
lit("ensure-dir: ~a: ~d/~s"), path, ret,
- string_utf8(strerror(c_num(ret))), nao);
+ string_utf8(strerror(eno)), nao);
+ }
return ret;
}
@@ -332,9 +357,12 @@ static val chdir_wrap(val path)
int err = chdir(u8path);
free(u8path);
- if (err < 0)
- uw_throwf(file_error_s, lit("chdir ~a: ~d/~s"),
- path, num(errno), string_utf8(strerror(errno)), nao);
+ if (err < 0) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("chdir ~a: ~d/~s"),
+ path, num(eno), string_utf8(strerror(eno)), nao);
+ }
+
return t;
}
@@ -346,9 +374,10 @@ val getcwd_wrap(void)
char *u8buf = coerce(char *, chk_malloc(guess));
if (getcwd(u8buf, guess) == 0) {
+ int eno = errno;
free(u8buf);
- if (errno != ERANGE) {
- uw_throwf(file_error_s, lit("getcwd: ~d/~s"),
+ if (eno != ERANGE) {
+ uw_throwf(errno_to_file_error(eno), lit("getcwd: ~d/~s"),
num(errno), string_utf8(strerror(errno)), nao);
}
if (2 * guess > guess)
@@ -393,16 +422,18 @@ static val mknod_wrap(val path, val mode, val dev)
int err = mknod(u8path, cmode, cdev);
free(u8path);
- if (err < 0)
+ if (err < 0) {
+ int eno = errno;
#if HAVE_MAKEDEV
- uw_throwf(file_error_s, lit("mknod ~a ~a ~a (~d:~d): ~d/~s"),
- path, mode, dev, major_wrap(dev), minor_wrap(dev), num(errno),
- string_utf8(strerror(errno)), nao);
+ uw_throwf(errno_to_file_error(eno), lit("mknod ~a ~a ~a (~d:~d): ~d/~s"),
+ path, mode, dev, major_wrap(dev), minor_wrap(dev), num(eno),
+ string_utf8(strerror(eno)), nao);
#else
- uw_throwf(file_error_s, lit("mknod ~a ~a ~a: ~d/~s"),
- path, mode, dev, num(errno),
- string_utf8(strerror(errno)), nao);
+ uw_throwf(errno_to_file_error(eno), lit("mknod ~a ~a ~a: ~d/~s"),
+ path, mode, dev, num(eno),
+ string_utf8(strerror(eno)), nao);
#endif
+ }
return t;
}
@@ -418,9 +449,12 @@ static val chmod_wrap(val path, val mode)
int err = chmod(u8path, cmode);
free(u8path);
- if (err < 0)
- uw_throwf(file_error_s, lit("chmod ~a #o~o: ~d/~s"),
- path, mode, num(errno), string_utf8(strerror(errno)), nao);
+ if (err < 0) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("chmod ~a #o~o: ~d/~s"),
+ path, mode, num(eno), string_utf8(strerror(eno)), nao);
+ }
+
return t;
}
@@ -437,9 +471,13 @@ static val symlink_wrap(val target, val to)
int err = symlink(u8target, u8to);
free(u8target);
free(u8to);
- if (err < 0)
- uw_throwf(file_error_s, lit("symlink ~a ~a: ~d/~s"),
- target, to, num(errno), string_utf8(strerror(errno)), nao);
+
+ if (err < 0) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("symlink ~a ~a: ~d/~s"),
+ target, to, num(eno), string_utf8(strerror(eno)), nao);
+ }
+
return t;
}
@@ -452,9 +490,13 @@ static val link_wrap(val target, val to)
int err = link(u8target, u8to);
free(u8target);
free(u8to);
- if (err < 0)
- uw_throwf(file_error_s, lit("link ~a ~a: ~d/~s"),
- target, to, num(errno), string_utf8(strerror(errno)), nao);
+
+ if (err < 0) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("link ~a ~a: ~d/~s"),
+ target, to, num(eno), string_utf8(strerror(eno)), nao);
+ }
+
return t;
}
@@ -474,9 +516,10 @@ static val readlink_wrap(val path)
else
uw_throwf(file_error_s, lit("readlink: weird problem"), nao);
} else if (bytes <= 0) {
+ int eno = errno;
free(u8buf);
- uw_throwf(file_error_s, lit("readlink ~a: ~d/~s"),
- path, num(errno), string_utf8(strerror(errno)), nao);
+ uw_throwf(errno_to_file_error(eno), lit("readlink ~a: ~d/~s"),
+ path, num(eno), string_utf8(strerror(eno)), nao);
} else {
val out;
u8buf[bytes] = 0;
@@ -572,7 +615,7 @@ val exec_wrap(val file, val args_opt)
val args = default_null_arg(args_opt);
int nargs = c_num(length(args)) + 1;
char **argv = if3(nargs < 0 || nargs == INT_MAX,
- (uw_throwf(file_error_s, lit("~a: argument list overflow"),
+ (uw_throwf(process_error_s, lit("~a: argument list overflow"),
self, nao), convert(char **, 0)),
coerce(char **, chk_xalloc(nargs + 1, sizeof *argv, self)));
val iter;
@@ -585,9 +628,9 @@ val exec_wrap(val file, val args_opt)
argv[i] = 0;
if (execvp(argv[0], argv) < 0)
- uw_throwf(file_error_s, lit("~s ~a: ~d/~s"),
+ uw_throwf(process_error_s, lit("~s ~a: ~d/~s"),
self, file, num(errno), string_utf8(strerror(errno)), nao);
- uw_throwf(file_error_s, lit("~s ~a returned"), self, file, nao);
+ uw_throwf(process_error_s, lit("~s ~a returned"), self, file, nao);
}
static val exit_star_wrap(val status)
@@ -704,9 +747,11 @@ static val stat_impl(val obj, int (*statfn)(val, struct stat *),
struct stat st;
int res = statfn(obj, &st);
- if (res == -1)
- uw_throwf(file_error_s, lit("unable to ~a ~a: ~d/~s"),
- name, obj, num(errno), string_utf8(strerror(errno)), nao);
+ if (res == -1) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("unable to ~a ~a: ~d/~s"),
+ name, obj, num(eno), string_utf8(strerror(eno)), nao);
+ }
return if3(opt_compat && opt_compat <= 113,
stat_to_list(st), stat_to_struct(st, path));
@@ -749,9 +794,11 @@ static val umask_wrap(val mask)
static val pipe_wrap(void)
{
int fd[2];
- if (pipe(fd) < 0)
- uw_throwf(file_error_s, lit("pipe failed: ~d/~s"),
- num(errno), string_utf8(strerror(errno)), nao);
+ if (pipe(fd) < 0) {
+ int eno = errno;
+ uw_throwf(errno_to_file_error(eno), lit("pipe failed: ~d/~s"),
+ num(eno), string_utf8(strerror(eno)), nao);
+ }
return cons(num(fd[0]), num(fd[1]));
}
diff --git a/sysif.h b/sysif.h
index 4e971e3d..15625b24 100644
--- a/sysif.h
+++ b/sysif.h
@@ -43,6 +43,7 @@ typedef long off_t;
#define OFF_T_MIN (-OFF_T_MAX)
#endif
+val errno_to_file_error(int err);
val getenv_wrap(val name);
val at_exit_call(val func);
val at_exit_do_not_call(val func);
diff --git a/txr.1 b/txr.1
index 640c1e16..e2529d9b 100644
--- a/txr.1
+++ b/txr.1
@@ -38478,7 +38478,11 @@ subtype of every exception type:
|
+--- query-error
|
- +--- file-error
+ +--- file-error -------+--- path-not-found
+ | |
+ | +--- path-exists
+ | |
+ | +--- path-permission
|
+--- process-error
|
diff --git a/unwind.c b/unwind.c
index ca8762fd..0f362c4b 100644
--- a/unwind.c
+++ b/unwind.c
@@ -1177,6 +1177,9 @@ void uw_init(void)
uw_register_subtype(timeout_error_s, error_s);
uw_register_subtype(assert_s, error_s);
uw_register_subtype(syntax_error_s, error_s);
+ uw_register_subtype(path_not_found_s, file_error_s);
+ uw_register_subtype(path_exists_s, file_error_s);
+ uw_register_subtype(path_permission_s, file_error_s);
}
void uw_late_init(void)