ledit

Text editor (WIP)
git clone git://lumidify.org/ledit.git (fast, but not encrypted)
git clone https://lumidify.org/git/ledit.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

commit 3da18ab09b9d07340479d8e03052c5638cd63d91
parent 91fe3763c8d446cf4039bd4bc169963c66d9ae85
Author: lumidify <nobody@lumidify.org>
Date:   Thu,  9 Feb 2023 10:43:07 +0100

Write error message to emergency dump

Diffstat:
Massert.c | 2+-
Mcleanup.h | 2+-
Mledit.c | 44++++++++++++++++++++++++++++++++++++++++----
Mmemory.c | 6+++---
Mmemory.h | 3++-
5 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/assert.c b/assert.c @@ -8,7 +8,7 @@ ledit_assert_impl(const char *file, int line, const char *func, const char *fail (void)fprintf(stderr, "assertion \"%s\" failed: file \"%s\", line %d, function \"%s\"\n", failedexpr, file, line, func); - ledit_emergencydump(); + ledit_emergencydump(file, line, func, failedexpr); abort(); /* NOTREACHED */ } diff --git a/cleanup.h b/cleanup.h @@ -4,6 +4,6 @@ /* This is here so it can be called from other places even though the function definition is in ledit.c */ void ledit_cleanup(void); -void ledit_emergencydump(void); +void ledit_emergencydump(const char *file, int line, const char *func, const char *failedexpr); #endif diff --git a/ledit.c b/ledit.c @@ -277,6 +277,7 @@ setup(int argc, char *argv[]) { } else { cfgfile = ledit_strcat(pw->pw_dir, "/.leditrc"); struct stat cfgst; + /* FIXME: maybe only when ENOENT? */ if (stat(cfgfile, &cfgst)) { free(cfgfile); cfgfile = NULL; @@ -394,8 +395,9 @@ setup(int argc, char *argv[]) { redraw(); } +/* FIXME: maybe also write diagnostic information, e.g. number of lines and metadata (line length, etc.)? */ void -ledit_emergencydump(void) { +ledit_emergencydump(const char *filename, int line, const char *func, const char *failedexpr) { /* FIXME: pre-allocate memory for template to avoid memory errors? -> probably overkill since something else will fail anyways */ if (!buffer) @@ -422,17 +424,18 @@ ledit_emergencydump(void) { "Unable to open file for emergency dump: %s\n", strerror(errno) ); + goto error; } char *errstr; + /* buffer_write_to_fd closes the file descriptor, so this has to be done */ + int dupfd = dup(fd); + /* FIXME: improve error messages here; maybe only try to write error message if file written? */ if (buffer_write_to_fd(buffer, fd, &errstr)) { fprintf( stderr, "Unable to perform emergency dump: %s\n", errstr ); - /* FIXME: maybe just leave the file in case at - least part of it was written? */ - unlink(template); } else { fprintf( stderr, @@ -440,7 +443,40 @@ ledit_emergencydump(void) { template ); } + if (dupfd == -1) { + fprintf( + stderr, + "Unable to duplicate file descriptor for emergency dump to write error message: %s\n", + strerror(errno) + ); + goto error; + } + FILE *file = fdopen(dupfd, "w"); + if (!file) { + fprintf( + stderr, + "Unable to fdopen file descriptor for emergency dump to write error message: %s\n", + strerror(errno) + ); + if (close(dupfd)) { + fprintf( + stderr, + "Unable to close duplicated file descriptor in emergency dump: %s\n", + strerror(errno) + ); + } + goto error; + } + fprintf( + file, + "ERROR MESSAGE:\n\"%s\" in \"%s\", line %d, function \"%s\"\n", + failedexpr, filename, line, func + ); + if (fclose(file)) + fprintf(stderr, "Unable to close file for emergency dump: %s\n", strerror(errno)); +error: free(template); + return; } void diff --git a/memory.c b/memory.c @@ -16,9 +16,9 @@ fatal_err(const char *msg) { } void -err_overflow(void) { - (void)fprintf(stderr, "Integer overflow.\n"); - ledit_emergencydump(); +err_overflow_impl(const char *file, int line, const char *func) { + (void)fprintf(stderr, "Integer overflow: file \"%s\", line %d, function \"%s\"\n", file, line, func); + ledit_emergencydump(file, line, func, "Integer overflow"); abort(); } diff --git a/memory.h b/memory.h @@ -61,7 +61,8 @@ void *resize_and_move_gap( ); /* FIXME: not sure if this really belongs here */ -void err_overflow(void); +void err_overflow_impl(const char *file, int line, const char *func); +#define err_overflow() err_overflow_impl(__FILE__, __LINE__, __func__) /* * Return the ideal new size for an array of size 'old' when resizing it