ctucx.git: stagit

ctucx' stagit fork

commit d0e36eb6abce72c587dd53dcabc35120c3cf3a81
parent 7c419a8bac26e491206953bf2646ac634296b160
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat, 19 Mar 2022 12:22:43 +0100

improve stream read and write error handling
2 files changed, 42 insertions(+), 9 deletions(-)
M
stagit-index.c
|
16
+++++++++++++++-
M
stagit.c
|
35
+++++++++++++++++++++++++++--------
diff --git a/stagit-index.c b/stagit-index.c
@@ -16,6 +16,16 @@ static char description[255] = "Repositories";
 static char *name = "";
 static char owner[255];
 
+/* Handle read or write errors for a FILE * stream */
+void
+checkfileerror(FILE *fp, const char *name, int mode)
+{
+	if (mode == 'r' && ferror(fp))
+		errx(1, "read error: %s", name);
+	else if (mode == 'w' && (fflush(fp) || ferror(fp)))
+		errx(1, "write error: %s", name);
+}
+
 void
 joinpath(char *buf, size_t bufsiz, const char *path, const char *path2)
 {

@@ -214,6 +224,7 @@ main(int argc, char *argv[])
 		if (fp) {
 			if (!fgets(description, sizeof(description), fp))
 				description[0] = '\0';
+			checkfileerror(fp, "description", 'r');
 			fclose(fp);
 		}
 

@@ -227,8 +238,9 @@ main(int argc, char *argv[])
 		if (fp) {
 			if (!fgets(owner, sizeof(owner), fp))
 				owner[0] = '\0';
-			owner[strcspn(owner, "\n")] = '\0';
+			checkfileerror(fp, "owner", 'r');
 			fclose(fp);
+			owner[strcspn(owner, "\n")] = '\0';
 		}
 		writelog(stdout);
 	}

@@ -238,5 +250,7 @@ main(int argc, char *argv[])
 	git_repository_free(repo);
 	git_libgit2_shutdown();
 
+	checkfileerror(stdout, "<stdout>", 'w');
+
 	return ret;
 }
diff --git a/stagit.c b/stagit.c
@@ -79,6 +79,16 @@ static char lastoidstr[GIT_OID_HEXSZ + 2]; /* id + newline + NUL byte */
 static FILE *rcachefp, *wcachefp;
 static const char *cachefile;
 
+/* Handle read or write errors for a FILE * stream */
+void
+checkfileerror(FILE *fp, const char *name, int mode)
+{
+	if (mode == 'r' && ferror(fp))
+		errx(1, "read error: %s", name);
+	else if (mode == 'w' && (fflush(fp) || ferror(fp)))
+		errx(1, "write error: %s", name);
+}
+
 void
 joinpath(char *buf, size_t bufsiz, const char *path, const char *path2)
 {

@@ -814,6 +824,7 @@ writelog(FILE *fp, const git_oid *oid)
 			printshowfile(fpfile, ci);
 			fputs("</pre>\n", fpfile);
 			writefooter(fpfile);
+			checkfileerror(fpfile, path, 'w');
 			fclose(fpfile);
 		}
 err:

@@ -963,14 +974,13 @@ writeblob(git_object *obj, const char *fpath, const char *filename, size_t files
 	fprintf(fp, " (%zuB)", filesize);
 	fputs("</p><hr/>", fp);
 
-	if (git_blob_is_binary((git_blob *)obj)) {
+	if (git_blob_is_binary((git_blob *)obj))
 		fputs("<p>Binary file.</p>\n", fp);
-	} else {
+	else
 		lc = writeblobhtml(fp, (git_blob *)obj);
-		if (ferror(fp))
-			err(1, "fwrite");
-	}
+
 	writefooter(fp);
+	checkfileerror(fp, fpath, 'w');
 	fclose(fp);
 
 	relpath = "";

@@ -1276,6 +1286,7 @@ main(int argc, char *argv[])
 	if (fpread) {
 		if (!fgets(description, sizeof(description), fpread))
 			description[0] = '\0';
+		checkfileerror(fpread, path, 'r');
 		fclose(fpread);
 	}
 

@@ -1288,8 +1299,9 @@ main(int argc, char *argv[])
 	if (fpread) {
 		if (!fgets(cloneurl, sizeof(cloneurl), fpread))
 			cloneurl[0] = '\0';
-		cloneurl[strcspn(cloneurl, "\n")] = '\0';
+		checkfileerror(fpread, path, 'r');
 		fclose(fpread);
+		cloneurl[strcspn(cloneurl, "\n")] = '\0';
 	}
 
 	/* check LICENSE */

@@ -1349,13 +1361,15 @@ main(int argc, char *argv[])
 			while (!feof(rcachefp)) {
 				n = fread(buf, 1, sizeof(buf), rcachefp);
 				if (ferror(rcachefp))
-					err(1, "fread");
+					break;
 				if (fwrite(buf, 1, n, fp) != n ||
 				    fwrite(buf, 1, n, wcachefp) != n)
-					err(1, "fwrite");
+					    break;
 			}
+			checkfileerror(rcachefp, cachefile, 'r');
 			fclose(rcachefp);
 		}
+		checkfileerror(wcachefp, tmppath, 'w');
 		fclose(wcachefp);
 	} else {
 		if (head)

@@ -1364,6 +1378,7 @@ main(int argc, char *argv[])
 
 	fputs("</tbody></table>", fp);
 	writefooter(fp);
+	checkfileerror(fp, "log.html", 'w');
 	fclose(fp);
 
 	/* files for HEAD */

@@ -1372,6 +1387,7 @@ main(int argc, char *argv[])
 	if (head)
 		writefiles(fp, head);
 	writefooter(fp);
+	checkfileerror(fp, "files.html", 'w');
 	fclose(fp);
 
 	/* summary page with branches and tags */

@@ -1379,16 +1395,19 @@ main(int argc, char *argv[])
 	writeheader(fp, "Refs");
 	writerefs(fp);
 	writefooter(fp);
+	checkfileerror(fp, "refs.html", 'w');
 	fclose(fp);
 
 	/* Atom feed */
 	fp = efopen("atom.xml", "w");
 	writeatom(fp, 1);
+	checkfileerror(fp, "atom.xml", 'w');
 	fclose(fp);
 
 	/* Atom feed for tags / releases */
 	fp = efopen("tags.xml", "w");
 	writeatom(fp, 0);
+	checkfileerror(fp, "tags.xml", 'w');
 	fclose(fp);
 
 	/* rename new cache file on success */