URI: 
       tWrite error message to emergency dump - ledit - Text editor (WIP)
  HTML git clone git://lumidify.org/ledit.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/git/ledit.git (encrypted, but very slow)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 3da18ab09b9d07340479d8e03052c5638cd63d91
   DIR parent 91fe3763c8d446cf4039bd4bc169963c66d9ae85
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Thu,  9 Feb 2023 10:43:07 +0100
       
       Write error message to emergency dump
       
       Diffstat:
         M assert.c                            |       2 +-
         M cleanup.h                           |       2 +-
         M ledit.c                             |      44 ++++++++++++++++++++++++++++---
         M memory.c                            |       6 +++---
         M memory.h                            |       3 ++-
       
       5 files changed, 47 insertions(+), 10 deletions(-)
       ---
   DIR diff --git a/assert.c b/assert.c
       t@@ -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 */
        }
   DIR diff --git a/cleanup.h b/cleanup.h
       t@@ -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
   DIR diff --git a/ledit.c b/ledit.c
       t@@ -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;
       t@@ -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)
       t@@ -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,
       t@@ -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
   DIR diff --git a/memory.c b/memory.c
       t@@ -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();
        }
        
   DIR diff --git a/memory.h b/memory.h
       t@@ -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