diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-09-07 23:24:04 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-09-07 23:24:04 -0700 |
commit | 7f32442862bfc785e613af33d48d1a4a4dae8835 (patch) | |
tree | 95d693bbecd8193f9bb91b2667ec7d3613a74373 /unwind.c | |
parent | e9c5a283537e9d7a0722189dbaf295d9f684a7e8 (diff) | |
download | txr-7f32442862bfc785e613af33d48d1a4a4dae8835.tar.gz txr-7f32442862bfc785e613af33d48d1a4a4dae8835.tar.bz2 txr-7f32442862bfc785e613af33d48d1a4a4dae8835.zip |
exceptions: hack to store errno in string object.
Basic idea: when we throw an exception that pertains to a
system error which has an errno code, we can stick the errno
into the memory area of the character string, into the wchar_t
that immediately follows the null terminator. We can do this
because strings track their actual allocation size.
A pair of setter/getter functions to set and retrieve this
value are provided, and all functions in the code which can
set such a code are updated to do so, simply by calling the
newly added uw_ethrowf that drop-in replaces for uw_throwf.
* lib.[ch] (string_set_code, string_get_code): New functions.
* unwind.[ch] (uw_ethrowf): New function.
* eval.c (eval_init): Register string-set-code and
string-get-code intrinsics.
* ftw.c (ftw_wrap): Switch to uw_ethrowf.
* parser.c (open_txr_file): Likewise.
* socket.c (dgram_overflow): Store the ENOBUFS error in errno,
and use uw_ethrowf instead uw_throwf.
(dgram_get_byte_callback, dgram_flush, sock_bind, to_connect,
open_sockfd, sock_connect, sock_listen, sock_accept,
sock_shutdown, sock_timeout, socketpair_wrap): Switch to
uw_ethrowf.
* stream.c (dev_null_get_fd, stdio_maybe_read_error,
stdio_maybe_error, stdio_close, pipe_close, open_directory,
open_file, open_fileno, open_tail, fds_subst,
open_subprocess, open_command, remove_path, rename_path,
tmpfile_wrap, mkdtemp_wrap, mkstemp_wrap): Switch to uw_ethrowf.
* sysif.c (mkdir_wrap, ensure_dir, chdir_wrap, getcwd_wrap,
rmdir_wrap, mknod_wrap, mkfifo_wrap, chmod_wrap, do_chown,
symlink_wrap, link_wrap, readlink_wrap, close_wrap, val
exec_wrap, stat_impl, do_utimes, pipe_wrap, poll_wrap,
getgroups_wrap, setuid_wrap, seteuid_wrap, setgid_wrap,
setegid_wrap, setgroups_wrap, getresuid_wrap, setresuid_wrap,
setresgid_wrap, crypt_wrap, uname_wrap, opendir_wrap,
getrlimit_wrap, setrlimit_wrap): Likewise.
* termios.c (tcgetattr_wrap, tcsetattr_wrap, tcsendbreak_wrap,
tcdrain_wrap, tcflush_wrap, tcflow_wrap): Likewise.
* tests/018/errno.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
Diffstat (limited to 'unwind.c')
-rw-r--r-- | unwind.c | 15 |
1 files changed, 15 insertions, 0 deletions
@@ -33,6 +33,7 @@ #include <assert.h> #include <stdarg.h> #include <signal.h> +#include <errno.h> #include "config.h" #if HAVE_VALGRIND #include <valgrind/memcheck.h> @@ -803,6 +804,20 @@ val uw_throwf(val sym, val fmt, ...) abort(); } +val uw_ethrowf(val sym, val fmt, ...) +{ + va_list vl; + val eno = num(errno); + val stream = make_string_output_stream(); + + va_start (vl, fmt); + (void) vformat(stream, fmt, vl); + va_end (vl); + + uw_throw(sym, string_set_code(get_string_from_stream(stream), eno)); + abort(); +} + val uw_errorfv(val fmt, struct args *args) { val stream = make_string_output_stream(); |