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);