In response to Savannah bug report #28453 [1], I am attaching a patch
which allows Patch to print the name of the file it was working on when
an error occurs. Now instead of reporting something like "patch: No
space on disk."  We  get something more helpful like "patch: Write error
when operating on /tmp/myfile. No space on disk."

- Jesse

1. https://savannah.gnu.org/bugs/?28453
diff --git a/src/inp.c b/src/inp.c
index 32d0919..05f7059 100644
--- a/src/inp.c
+++ b/src/inp.c
@@ -421,7 +421,7 @@ plan_b (char const *filename)
       char const *p0 = p;
       if (! (line % lines_per_buf))    /* new block */
        if (write (tifd, tibuf[0], tibufsize) != tibufsize)
-         write_fatal ();
+         write_fatal (TMPINNAME);
       if ((c = getc (ifp)) == EOF)
        break;
 
@@ -448,7 +448,7 @@ plan_b (char const *filename)
 
   if (line % lines_per_buf  !=  0)
     if (write (tifd, tibuf[0], tibufsize) != tibufsize)
-      write_fatal ();
+      write_fatal (TMPINNAME);
   input_lines = line - 1;
 }
 
diff --git a/src/merge.c b/src/merge.c
index 6f6205a..0f750cf 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -499,7 +499,7 @@ merge_hunk (int hunk, struct outstate *outstate, lin where, 
bool *somefailed)
          outstate->after_newline = true;
          outstate->zero_output = false;
          if (ferror (fp))
-           write_fatal ();
+           write_fatal (NULL);
 
          /* Output common suffix lines.  */
          if (common_suffix)
diff --git a/src/patch.c b/src/patch.c
index 81c7a02..c1b7235 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -622,7 +622,7 @@ main (int argc, char **argv)
 
        if (failed && ! skip_reject_file) {
            if (fstat (fileno (rejfp), &rejst) != 0 || fclose (rejfp) != 0)
-             write_fatal ();
+             write_fatal (NULL);
            rejfp = NULL;
            somefailed = true;
            say ("%d out of %d hunk%s %s", failed, hunk, "s" + (hunk == 1),
@@ -661,7 +661,7 @@ main (int argc, char **argv)
 
                        olderrno = stat_file (rej, &oldst);
                        if (olderrno && olderrno != ENOENT)
-                         write_fatal ();
+                         write_fatal (TMPREJNAME);
                        if (! olderrno && lookup_file_id (&oldst) == CREATED)
                          append_to_file (TMPREJNAME, rej);
                        else
@@ -680,7 +680,7 @@ main (int argc, char **argv)
       set_signals (true);
     }
     if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0))
-      write_fatal ();
+      write_fatal (NULL);
     output_files (NULL);
     cleanup ();
     delete_files ();
@@ -1390,7 +1390,7 @@ abort_hunk_context (bool header, bool reverse)
            fatal ("fatal internal error in abort_hunk_context");
        }
        if (ferror (rejfp))
-         write_fatal ();
+         write_fatal (NULL);
     }
 }
 
@@ -1441,7 +1441,7 @@ apply_hunk (struct outstate *outstate, lin where)
                    def_state = IN_ELSE;
                }
                if (ferror (fp))
-                 write_fatal ();
+                 write_fatal (NULL);
                outstate->after_newline = pch_write_line (old, fp);
                outstate->zero_output = false;
            }
@@ -1465,7 +1465,7 @@ apply_hunk (struct outstate *outstate, lin where)
                    def_state = IN_IFDEF;
                }
                if (ferror (fp))
-                 write_fatal ();
+                 write_fatal (NULL);
            }
            outstate->after_newline = pch_write_line (new, fp);
            outstate->zero_output = false;
@@ -1481,7 +1481,7 @@ apply_hunk (struct outstate *outstate, lin where)
            if (R_do_defines) {
               fprintf (fp, 1 + not_defined, R_do_defines);
               if (ferror (fp))
-               write_fatal ();
+               write_fatal (NULL);
               def_state = IN_IFNDEF;
            }
 
@@ -1498,7 +1498,7 @@ apply_hunk (struct outstate *outstate, lin where)
            if (R_do_defines) {
                fputs (outstate->after_newline + else_defined, fp);
                if (ferror (fp))
-                 write_fatal ();
+                 write_fatal (NULL);
                def_state = IN_ELSE;
            }
 
@@ -1517,7 +1517,7 @@ apply_hunk (struct outstate *outstate, lin where)
            if (R_do_defines && def_state != OUTSIDE) {
                fputs (outstate->after_newline + end_defined, fp);
                if (ferror (fp))
-                 write_fatal ();
+                 write_fatal (NULL);
                outstate->after_newline = true;
                def_state = OUTSIDE;
            }
@@ -1537,14 +1537,14 @@ apply_hunk (struct outstate *outstate, lin where)
                def_state = IN_ELSE;
            }
            if (ferror (fp))
-             write_fatal ();
+             write_fatal (NULL);
            outstate->zero_output = false;
        }
 
        do
          {
            if (! outstate->after_newline  &&  putc ('\n', fp) == EOF)
-             write_fatal ();
+             write_fatal (NULL);
            outstate->after_newline = pch_write_line (new, fp);
            outstate->zero_output = false;
            new++;
@@ -1554,7 +1554,7 @@ apply_hunk (struct outstate *outstate, lin where)
     if (R_do_defines && def_state != OUTSIDE) {
        fputs (outstate->after_newline + end_defined, fp);
        if (ferror (fp))
-         write_fatal ();
+         write_fatal (NULL);
        outstate->after_newline = true;
     }
     out_offset += pch_repl_lines() - pch_ptrn_lines ();
@@ -1643,7 +1643,7 @@ copy_till (struct outstate *outstate, lin lastline)
          {
            if ((! outstate->after_newline  &&  putc ('\n', fp) == EOF)
                || fwrite (s, sizeof *s, size, fp) < size)
-             write_fatal ();
+             write_fatal (NULL);
            outstate->after_newline = s[size - 1] == '\n';
            outstate->zero_output = false;
          }
@@ -1675,7 +1675,7 @@ spew_output (struct outstate *outstate, struct stat *st)
        if (fflush (outstate->ofp) != 0
            || fstat (fileno (outstate->ofp), st) != 0
            || fclose (outstate->ofp) != 0)
-         write_fatal ();
+         write_fatal (NULL);
        outstate->ofp = 0;
       }
 
diff --git a/src/pch.c b/src/pch.c
index a500ad9..9f3072b 100644
--- a/src/pch.c
+++ b/src/pch.c
@@ -153,12 +153,12 @@ open_patch_file (char const *filename)
             (charsread = fread (buf, 1, bufsize, read_pfp)) != 0;
             st.st_size += charsread)
          if (fwrite (buf, 1, charsread, pfp) != charsread)
-           write_fatal ();
+           write_fatal (TMPPATNAME);
        if (ferror (read_pfp) || fclose (read_pfp) != 0)
          read_fatal ();
        if (fflush (pfp) != 0
            || file_seek (pfp, (file_offset) 0, SEEK_SET) != 0)
-         write_fatal ();
+         write_fatal (TMPPATNAME);
       }
     p_filesize = st.st_size;
     if (p_filesize != (file_offset) p_filesize)
@@ -2290,7 +2290,7 @@ pch_write_line (lin line, FILE *file)
 
   if (fwrite (p_line[line], sizeof (*p_line[line]), p_len[line], file)
       < p_len[line])
-    write_fatal ();
+    write_fatal (NULL);
   return after_newline;
 }
 
@@ -2437,14 +2437,14 @@ do_ed_script (char const *inname, char const *outname,
        if (ed_command_letter) {
            if (tmpfp)
                if (fwrite (buf, sizeof *buf, chars_read, tmpfp) < chars_read)
-                   write_fatal ();
+                   write_fatal (outname);
            if (ed_command_letter != 'd' && ed_command_letter != 's') {
                p_pass_comments_through = true;
                while ((chars_read = get_line ()) != 0) {
                    if (tmpfp)
                        if (fwrite (buf, sizeof *buf, chars_read, tmpfp)
                            < chars_read)
-                           write_fatal ();
+                           write_fatal (TMPEDNAME);
                    if (chars_read == 2  &&  strEQ (buf, ".\n"))
                        break;
                }
@@ -2460,7 +2460,7 @@ do_ed_script (char const *inname, char const *outname,
       return;
     if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, tmpfp) < (size_t) 4
        || fflush (tmpfp) != 0)
-      write_fatal ();
+      write_fatal (TMPEDNAME);
 
     if (lseek (tmpfd, 0, SEEK_SET) == -1)
       pfatal ("Can't rewind to the beginning of file %s", quotearg 
(TMPEDNAME));
@@ -2499,7 +2499,7 @@ do_ed_script (char const *inname, char const *outname,
          pfatal ("can't open '%s'", outname);
        while ((c = getc (ifp)) != EOF)
          if (putc (c, ofp) == EOF)
-           write_fatal ();
+           write_fatal (outname);
        if (ferror (ifp) || fclose (ifp) != 0)
          read_fatal ();
       }
diff --git a/src/util.c b/src/util.c
index 1cc08ba..e4ef9ff 100644
--- a/src/util.c
+++ b/src/util.c
@@ -589,7 +589,7 @@ copy_to_fd (const char *from, int tofd)
       if (i == (ssize_t) -1)
        read_fatal ();
       if (full_write (tofd, buf, i) != i)
-       write_fatal ();
+       write_fatal (NULL);
     }
   if (close (fromfd) != 0)
     read_fatal ();
@@ -631,7 +631,7 @@ copy_file (char const *from, char const *to, struct stat 
*tost,
       if (tost && fstat (tofd, tost) != 0)
        pfatal ("Can't get file attributes of %s %s", "file", to);
       if (close (tofd) != 0)
-       write_fatal ();
+       write_fatal (to);
     }
 }
 
@@ -646,7 +646,7 @@ append_to_file (char const *from, char const *to)
     pfatal ("Can't reopen file %s", quotearg (to));
   copy_to_fd (from, tofd);
   if (close (tofd) != 0)
-    write_fatal ();
+    write_fatal (to);
 }
 
 static char const DEV_NULL[] = NULL_DEVICE;
@@ -937,9 +937,12 @@ read_fatal (void)
 }
 
 void
-write_fatal (void)
+write_fatal (const char *current_file)
 {
-  pfatal ("write error");
+  if (current_file)
+    pfatal("write error when operating on %s", current_file);
+  else
+    pfatal ("write error");
 }
 
 /* Say something from patch, something from the system, then silence . . . */
diff --git a/src/util.h b/src/util.h
index f4936ec..cff68ab 100644
--- a/src/util.h
+++ b/src/util.h
@@ -62,7 +62,7 @@ void read_fatal (void) __attribute__ ((noreturn));
 void remove_prefix (char *, size_t);
 void removedirs (char const *);
 void set_signals (bool);
-void write_fatal (void) __attribute__ ((noreturn));
+void write_fatal (const char *) __attribute__ ((noreturn));
 void insert_file_id (struct stat const *, enum file_id_type);
 enum file_id_type lookup_file_id (struct stat const *);
 void set_queued_output (struct stat const *, bool);

Reply via email to