{ echo '$(ME): do not end "SEE ALSO" section with a period' \
1>&2; exit 1; } || :
+sc_prohibit_exit_write_error:
+ @prohibit='error.*EXIT_FAILURE.*write error' \
+ in_vc_files='\.c$$' \
+ halt='Use write_error() instead' \
+ $(_sc_search_regexp)
+
# Don't use "indent-tabs-mode: nil" anymore. No longer needed.
sc_prohibit_emacs__indent_tabs_mode__setting:
@prohibit='^( *[*#] *)?indent-tabs-mode:' \
sc_some_programs_must_avoid_exit_failure:
@cd $(srcdir) \
&& grep -nw EXIT_FAILURE \
- $$(git grep -El '[^T]_FAILURE|EXIT_CANCELED' $(srcdir)/src) \
+ $$(git grep -El '[^T]_FAILURE|EXIT_CANCELED' src/) \
+ | grep -v '^src/system\.h:' \
| grep -vE '= EXIT_FAILURE|return .* \?' | grep . \
&& { echo '$(ME): do not use EXIT_FAILURE in the above' \
1>&2; exit 1; } || :
{
/* Simple write. */
if (fwrite (buffer, 1, len, stdout) < len)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
}
else
for (idx_t written = 0; written < len; )
if (to_write == 0)
{
if (fputc ('\n', out) == EOF)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
*current_column = 0;
}
else
{
if (fwrite (buffer + written, 1, to_write, stdout) < to_write)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
*current_column += to_write;
written += to_write;
}
/* When wrapping, terminate last line. */
if (wrap_column && current_column > 0 && fputc ('\n', out) == EOF)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
if (ferror (in))
error (EXIT_FAILURE, errno, _("read error"));
ok = base_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n);
if (fwrite (outbuf, 1, n, out) < n)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
if (!ok)
error (EXIT_FAILURE, 0, _("invalid input"));
/* Write this block out. */
if (full_write (STDOUT_FILENO, buf, n_read) != n_read)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
}
}
if (0 < n_write)
{
if (full_write (STDOUT_FILENO, outbuf, n_write) != n_write)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
*bpout = outbuf;
}
}
do
{
if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
wp += outsize;
remaining_bytes = bpout - wp;
}
if (pending_cr)
{
if (full_write (STDOUT_FILENO, "\r", 1) != 1)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
}
if (have_read_stdin && close (STDIN_FILENO) < 0)
while (++column < next_tab_column)
if (putchar (' ') < 0)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
c = ' ';
}
return;
if (putchar (c) < 0)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
}
while (c != '\n');
}
{
size_t size = lbuf.end - lbuf.buf;
if (full_write (STDOUT_FILENO, lbuf.buf, size) != size)
- error (EXIT_FAILURE, errno, "%s", _("write error"));
+ write_error ();
lbuf.end = lbuf.buf;
}
return backslash_at_end ? 1 : 0;
}
-/* Report a write error and exit. */
-
-static void
-write_error (void)
-{
- error (EXIT_FAILURE, errno, _("write error"));
-}
-
/* Output a single byte, reporting any write errors. */
static inline void
}
}
-static void
-io_error (void)
-{
- /* FIXME: consider option to silently ignore errno=EPIPE */
- clearerr (stdout);
- error (EXIT_FAILURE, errno, _("write error"));
-}
-
/* Actually print the sequence of numbers in the specified range, with the
given or default stepping and format. */
{
long double x0 = x;
if (printf (fmt, x) < 0)
- io_error ();
+ write_error ();
if (out_of_range)
break;
x = first + i * step;
}
if (fputs (separator, stdout) == EOF)
- io_error ();
+ write_error ();
}
if (fputs (terminator, stdout) == EOF)
- io_error ();
+ write_error ();
}
}
if (buf_end - (p_len + 1) < bufp)
{
if (fwrite (buf, bufp - buf, 1, stdout) != 1)
- io_error ();
+ write_error ();
bufp = buf;
}
}
/* Write any remaining buffered output, and the terminator. */
*bufp++ = *terminator;
if (fwrite (buf, bufp - buf, 1, stdout) != 1)
- io_error ();
+ write_error ();
}
if (ok)
}
if (i != 0)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
main_exit (EXIT_SUCCESS);
}
large chunks from an existing file, so it's more efficient
to write out directly. */
if (full_write (STDOUT_FILENO, bp, to_write) != to_write)
- error (EXIT_FAILURE, errno, "%s", _("write error"));
+ write_error ();
}
else if (! k)
cwrite (new_file_flag, bp, to_write);
if (line_no == k && unbuffered)
{
if (full_write (STDOUT_FILENO, bp, to_write) != to_write)
- error (EXIT_FAILURE, errno, "%s", _("write error"));
+ write_error ();
}
else if (line_no == k && fwrite (bp, to_write, 1, stdout) != 1)
{
- clearerr (stdout); /* To silence close_stdout(). */
- error (EXIT_FAILURE, errno, "%s", _("write error"));
+ write_error ();
}
if (next)
line_no = (line_no == n) ? 1 : line_no + 1;
} \
while (0)
+/* exit with a _single_ "write error" diagnostic. */
+
+static inline void
+write_error (void)
+{
+ int saved_errno = errno;
+ fflush (stdout); /* Ensure nothing buffered that might induce an error. */
+ clearerr (stdout); /* To avoid extraneous diagnostic from close_stdout. */
+ error (EXIT_FAILURE, saved_errno, _("write error"));
+}
+
/* Like stpncpy, but do ensure that the result is NUL-terminated,
and do not NUL-pad out to LEN. I.e., when strnlen (src, len) == len,
this function writes a NUL byte into dest[len]. Thus, the length
}
if ((!any_input || blocking) && fflush (stdout) != 0)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
check_output_alive ();
{
*prev_fspec = fspec;
if (fflush (stdout) != 0)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
}
}
tail_forever_inotify flushes only after writing,
not before reading. */
if (fflush (stdout) != 0)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
Hash_table *ht;
tail_forever_inotify (wd, F, n_files, sleep_interval, &ht);
}
if (out_len > 0
&& fwrite (&buf[begin], 1, out_len, stdout) != out_len)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
}
if (char_to_squeeze != NOT_A_CHAR)
if (nr == 0)
break;
if (fwrite (io_buf, 1, nr, stdout) != nr)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
}
}
else if (squeeze_repeats && delete && non_option_args == 2)
if (bytes_read == 0)
break;
if (fwrite (io_buf, 1, bytes_read, stdout) != bytes_read)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
}
}
}
if (pending > 1 && one_blank_before_tab_stop)
pending_blank[0] = '\t';
if (fwrite (pending_blank, 1, pending, stdout) != pending)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
pending = 0;
one_blank_before_tab_stop = false;
}
}
if (putchar (c) < 0)
- error (EXIT_FAILURE, errno, _("write error"));
+ write_error ();
}
while (c != '\n');
}
# TODO: cut -z -c1- /dev/zero
dd if=/dev/zero
expand /dev/zero
-# TODO: avoid double error from expand
factor --version; yes 1 | factor
-# TODO: avoid double error from factor
# TODO: fmt /dev/zero
# TODO: fold -b /dev/zero
head -z -n-1 /dev/zero
# TODO: numfmt --version; yes 1 | numfmt
# TODO: od -v /dev/zero
paste /dev/zero
-# TODO: avoid double error from paste
# TODO: pr /dev/zero
seq inf
-# TODO: avoid double error from shuf
tail -n+1 -z /dev/zero
tee < /dev/zero
tr . . < /dev/zero
-# TODO: avoid double error from tr
unexpand /dev/zero
-# TODO: avoid double error from unexpand
# TODO: uniq -z -D /dev/zero
yes
" |