aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHiltjo Posthuma <[email protected]>2022-03-19 12:22:43 +0100
committerHiltjo Posthuma <[email protected]>2022-03-19 12:51:40 +0100
commitd0e36eb6abce72c587dd53dcabc35120c3cf3a81 (patch)
treef09f4f56b9851a61de612ab84813e1deebcad7c4
parent7c419a8bac26e491206953bf2646ac634296b160 (diff)
downloadstagit-d0e36eb6abce72c587dd53dcabc35120c3cf3a81.tar.gz
stagit-d0e36eb6abce72c587dd53dcabc35120c3cf3a81.zip
improve stream read and write error handling
-rw-r--r--stagit-index.c16
-rw-r--r--stagit.c35
2 files changed, 42 insertions, 9 deletions
diff --git a/stagit-index.c b/stagit-index.c
index 7c1f76d..26ef16d 100644
--- 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
index 0d53b72..54622a1 100644
--- 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 */