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:
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