improve stream read and write error handling
2 files changed, 42 insertions(+), 9 deletions(-) | |||
---|---|---|---|
M | stagit-index.c | +15 | -1 |
M | stagit.c | +27 | -8 |
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 */