stagit

improve stream read and write error handling

Hiltjo Posthuma contact@arjunchoudhary.com

commit: b108ab7 parent: f5e1441
2 files changed, 42 insertions(+), 9 deletions(-)
Mstagit-index.c+15-1
Mstagit.c+27-8
M · stagit-index.c +15, -1
 1@@ -16,6 +16,16 @@ static char description[255] = "Repositories";
 2 static char *name = "";
 3 static char owner[255];
 4 
 5+/* Handle read or write errors for a FILE * stream */
 6+void
 7+checkfileerror(FILE *fp, const char *name, int mode)
 8+{
 9+	if (mode == 'r' && ferror(fp))
10+		errx(1, "read error: %s", name);
11+	else if (mode == 'w' && (fflush(fp) || ferror(fp)))
12+		errx(1, "write error: %s", name);
13+}
14+
15 void
16 joinpath(char *buf, size_t bufsiz, const char *path, const char *path2)
17 {
18@@ -214,6 +224,7 @@ main(int argc, char *argv[])
19 		if (fp) {
20 			if (!fgets(description, sizeof(description), fp))
21 				description[0] = '\0';
22+			checkfileerror(fp, "description", 'r');
23 			fclose(fp);
24 		}
25 
26@@ -227,8 +238,9 @@ main(int argc, char *argv[])
27 		if (fp) {
28 			if (!fgets(owner, sizeof(owner), fp))
29 				owner[0] = '\0';
30-			owner[strcspn(owner, "\n")] = '\0';
31+			checkfileerror(fp, "owner", 'r');
32 			fclose(fp);
33+			owner[strcspn(owner, "\n")] = '\0';
34 		}
35 		writelog(stdout);
36 	}
37@@ -238,5 +250,7 @@ main(int argc, char *argv[])
38 	git_repository_free(repo);
39 	git_libgit2_shutdown();
40 
41+	checkfileerror(stdout, "<stdout>", 'w');
42+
43 	return ret;
44 }
M · stagit.c +27, -8
  1@@ -79,6 +79,16 @@ static char lastoidstr[GIT_OID_HEXSZ + 2]; /* id + newline + NUL byte */
  2 static FILE *rcachefp, *wcachefp;
  3 static const char *cachefile;
  4 
  5+/* Handle read or write errors for a FILE * stream */
  6+void
  7+checkfileerror(FILE *fp, const char *name, int mode)
  8+{
  9+	if (mode == 'r' && ferror(fp))
 10+		errx(1, "read error: %s", name);
 11+	else if (mode == 'w' && (fflush(fp) || ferror(fp)))
 12+		errx(1, "write error: %s", name);
 13+}
 14+
 15 void
 16 joinpath(char *buf, size_t bufsiz, const char *path, const char *path2)
 17 {
 18@@ -814,6 +824,7 @@ writelog(FILE *fp, const git_oid *oid)
 19 			printshowfile(fpfile, ci);
 20 			fputs("</pre>\n", fpfile);
 21 			writefooter(fpfile);
 22+			checkfileerror(fpfile, path, 'w');
 23 			fclose(fpfile);
 24 		}
 25 err:
 26@@ -963,14 +974,13 @@ writeblob(git_object *obj, const char *fpath, const char *filename, size_t files
 27 	fprintf(fp, " (%zuB)", filesize);
 28 	fputs("</p><hr/>", fp);
 29 
 30-	if (git_blob_is_binary((git_blob *)obj)) {
 31+	if (git_blob_is_binary((git_blob *)obj))
 32 		fputs("<p>Binary file.</p>\n", fp);
 33-	} else {
 34+	else
 35 		lc = writeblobhtml(fp, (git_blob *)obj);
 36-		if (ferror(fp))
 37-			err(1, "fwrite");
 38-	}
 39+
 40 	writefooter(fp);
 41+	checkfileerror(fp, fpath, 'w');
 42 	fclose(fp);
 43 
 44 	relpath = "";
 45@@ -1276,6 +1286,7 @@ main(int argc, char *argv[])
 46 	if (fpread) {
 47 		if (!fgets(description, sizeof(description), fpread))
 48 			description[0] = '\0';
 49+		checkfileerror(fpread, path, 'r');
 50 		fclose(fpread);
 51 	}
 52 
 53@@ -1288,8 +1299,9 @@ main(int argc, char *argv[])
 54 	if (fpread) {
 55 		if (!fgets(cloneurl, sizeof(cloneurl), fpread))
 56 			cloneurl[0] = '\0';
 57-		cloneurl[strcspn(cloneurl, "\n")] = '\0';
 58+		checkfileerror(fpread, path, 'r');
 59 		fclose(fpread);
 60+		cloneurl[strcspn(cloneurl, "\n")] = '\0';
 61 	}
 62 
 63 	/* check LICENSE */
 64@@ -1349,13 +1361,15 @@ main(int argc, char *argv[])
 65 			while (!feof(rcachefp)) {
 66 				n = fread(buf, 1, sizeof(buf), rcachefp);
 67 				if (ferror(rcachefp))
 68-					err(1, "fread");
 69+					break;
 70 				if (fwrite(buf, 1, n, fp) != n ||
 71 				    fwrite(buf, 1, n, wcachefp) != n)
 72-					err(1, "fwrite");
 73+					    break;
 74 			}
 75+			checkfileerror(rcachefp, cachefile, 'r');
 76 			fclose(rcachefp);
 77 		}
 78+		checkfileerror(wcachefp, tmppath, 'w');
 79 		fclose(wcachefp);
 80 	} else {
 81 		if (head)
 82@@ -1364,6 +1378,7 @@ main(int argc, char *argv[])
 83 
 84 	fputs("</tbody></table>", fp);
 85 	writefooter(fp);
 86+	checkfileerror(fp, "log.html", 'w');
 87 	fclose(fp);
 88 
 89 	/* files for HEAD */
 90@@ -1372,6 +1387,7 @@ main(int argc, char *argv[])
 91 	if (head)
 92 		writefiles(fp, head);
 93 	writefooter(fp);
 94+	checkfileerror(fp, "files.html", 'w');
 95 	fclose(fp);
 96 
 97 	/* summary page with branches and tags */
 98@@ -1379,16 +1395,19 @@ main(int argc, char *argv[])
 99 	writeheader(fp, "Refs");
100 	writerefs(fp);
101 	writefooter(fp);
102+	checkfileerror(fp, "refs.html", 'w');
103 	fclose(fp);
104 
105 	/* Atom feed */
106 	fp = efopen("atom.xml", "w");
107 	writeatom(fp, 1);
108+	checkfileerror(fp, "atom.xml", 'w');
109 	fclose(fp);
110 
111 	/* Atom feed for tags / releases */
112 	fp = efopen("tags.xml", "w");
113 	writeatom(fp, 0);
114+	checkfileerror(fp, "tags.xml", 'w');
115 	fclose(fp);
116 
117 	/* rename new cache file on success */