improve stream read and write error handling
authorHiltjo Posthuma <hiltjo@codemadness.org>
Sat, 19 Mar 2022 11:22:43 +0000 (12:22 +0100)
committerHiltjo Posthuma <hiltjo@codemadness.org>
Sat, 19 Mar 2022 11:51:40 +0000 (12:51 +0100)
stagit-index.c
stagit.c

index 7c1f76da0f015bf04e940d413bc670ad25423831..26ef16d93302b5314b16cc2d495802638b8ef4d2 100644 (file)
@@ -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;
 }
index 0d53b72e637a96302e0975cd095826b4e2a6948e..54622a116824e9e980774ac3bf1ad376a1dcf744 100644 (file)
--- 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 */