printf( " %s\n", argv[i] );
}
- if( f != stdin ) fclose( f );
+ if( f == stdin )
+ clearerr( f );
+ else if( fclose( f ) != 0 )
+ fprintf( stderr, "Could not close `%s': %s\n", argv[i], strerror( errno ) );
}
return 0;
if (! cksum_fp (fp, file, &crc, &length))
return false;
- if (ferror (fp))
- {
- error (0, errno, "%s", quotef (file));
- if (!STREQ (file, "-"))
- fclose (fp);
- return false;
- }
-
- if (!STREQ (file, "-") && fclose (fp) == EOF)
+ int err = errno;
+ if (!ferror (fp))
+ err = 0;
+ if (STREQ (file, "-"))
+ clearerr (fp);
+ else if (fclose (fp) != 0 && !err)
+ err = errno;
+ if (err)
{
- error (0, errno, "%s", quotef (file));
+ error (0, err, "%s", quotef (file));
return false;
}
cut_stream (stream);
- if (ferror (stream))
- {
- error (0, errno, "%s", quotef (file));
- return false;
- }
+ int err = errno;
+ if (!ferror (stream))
+ err = 0;
if (STREQ (file, "-"))
clearerr (stream); /* Also clear EOF. */
else if (fclose (stream) == EOF)
+ err = errno;
+ if (err)
{
- error (0, errno, "%s", quotef (file));
+ error (0, err, "%s", quotef (file));
return false;
}
return true;
if (fp)
{
assert (prev_file);
- if (ferror (fp))
- {
- error (0, errno, "%s", quotef (prev_file));
- exit_status = EXIT_FAILURE;
- }
+ int err = errno;
+ if (!ferror (fp))
+ err = 0;
if (STREQ (prev_file, "-"))
clearerr (fp); /* Also clear EOF. */
else if (fclose (fp) != 0)
+ err = errno;
+ if (err)
{
- error (0, errno, "%s", quotef (prev_file));
+ error (0, err, "%s", quotef (prev_file));
exit_status = EXIT_FAILURE;
}
}
#include "system.h"
#include "error.h"
+#include "die.h"
#include "fadvise.h"
#include "xdectoint.h"
/* Forward declarations. */
static void set_prefix (char *p);
-static void fmt (FILE *f);
+static bool fmt (FILE *f, char const *);
static bool get_paragraph (FILE *f);
static int get_line (FILE *f, int c);
static int get_prefix (FILE *f);
goal_width = max_width * (2 * (100 - LEEWAY) + 1) / 200;
}
+ bool have_read_stdin = false;
+
if (optind == argc)
- fmt (stdin);
+ {
+ have_read_stdin = true;
+ ok = fmt (stdin, "-");
+ }
else
{
for (; optind < argc; optind++)
{
char *file = argv[optind];
if (STREQ (file, "-"))
- fmt (stdin);
+ {
+ ok &= fmt (stdin, file);
+ have_read_stdin = true;
+ }
else
{
FILE *in_stream;
in_stream = fopen (file, "r");
if (in_stream != NULL)
- {
- fmt (in_stream);
- if (fclose (in_stream) == EOF)
- {
- error (0, errno, "%s", quotef (file));
- ok = false;
- }
- }
+ ok &= fmt (in_stream, file);
else
{
error (0, errno, _("cannot open %s for reading"),
}
}
+ if (have_read_stdin && fclose (stdin) != 0)
+ die (EXIT_FAILURE, errno, "%s", _("closing standard input"));
+
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
prefix_length = s - p;
}
-/* read file F and send formatted output to stdout. */
+/* Read F and send formatted output to stdout.
+ Close F when done, unless F is stdin. Diagnose input errors, using FILE.
+ If !F, assume F resulted from an fopen failure and diagnose that.
+ Return true if successful. */
-static void
-fmt (FILE *f)
+static bool
+fmt (FILE *f, char const *file)
{
fadvise (f, FADVISE_SEQUENTIAL);
tabs = false;
fmt_paragraph ();
put_paragraph (word_limit);
}
+
+ int err = ferror (f) ? 0 : -1;
+ if (f == stdin)
+ clearerr (f);
+ else if (fclose (f) != 0 && err < 0)
+ err = errno;
+ if (0 <= err)
+ error (0, err, err ? "%s" : _("read error"), quotef (file));
+ return err < 0;
}
/* Set the global variable 'other_indent' according to SAME_PARAGRAPH
}
saved_errno = errno;
+ if (!ferror (istream))
+ saved_errno = 0;
if (offset_out)
fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
- if (ferror (istream))
+ if (STREQ (filename, "-"))
+ clearerr (istream);
+ else if (fclose (istream) != 0 && !saved_errno)
+ saved_errno = errno;
+
+ if (saved_errno)
{
error (0, saved_errno, "%s", quotef (filename));
- if (!STREQ (filename, "-"))
- fclose (istream);
- return false;
- }
- if (!STREQ (filename, "-") && fclose (istream) == EOF)
- {
- error (0, errno, "%s", quotef (filename));
return false;
}
#else
err = DIGEST_STREAM (fp, bin_result);
#endif
- if (err)
- {
- error (0, errno, "%s", quotef (filename));
- if (fp != stdin)
- fclose (fp);
- return false;
- }
+ err = err ? errno : 0;
+ if (is_stdin)
+ clearerr (fp);
+ else if (fclose (fp) != 0 && !err)
+ err = errno;
- if (!is_stdin && fclose (fp) != 0)
+ if (err)
{
- error (0, errno, "%s", quotef (filename));
+ error (0, err, "%s", quotef (filename));
return false;
}
free (line);
- if (ferror (checkfile_stream))
- {
- error (0, 0, _("%s: read error"), quotef (checkfile_name));
- return false;
- }
+ int err = ferror (checkfile_stream) ? 0 : -1;
+ if (is_stdin)
+ clearerr (checkfile_stream);
+ else if (fclose (checkfile_stream) != 0 && err < 0)
+ err = errno;
- if (!is_stdin && fclose (checkfile_stream) != 0)
+ if (0 <= err)
{
- error (0, errno, "%s", quotef (checkfile_name));
+ error (0, err, err ? "%s" : _("%s: read error"),
+ quotef (checkfile_name));
return false;
}
process_file (stream);
- if (ferror (stream))
- {
- error (0, errno, "%s", quotef (file));
- return false;
- }
+ int err = errno;
+ if (!ferror (stream))
+ err = 0;
if (STREQ (file, "-"))
clearerr (stream); /* Also clear EOF. */
- else if (fclose (stream) == EOF)
+ else if (fclose (stream) != 0 && !err)
+ err = errno;
+ if (err)
{
- error (0, errno, "%s", quotef (file));
+ error (0, err, "%s", quotef (file));
return false;
}
return true;
if (in_stream != NULL)
{
- if (ferror (in_stream))
+ if (!ferror (in_stream))
+ in_errno = 0;
+ if (STREQ (file_list[-1], "-"))
+ clearerr (in_stream);
+ else if (fclose (in_stream) != 0 && !in_errno)
+ in_errno = errno;
+ if (in_errno)
{
- error (0, in_errno, _("%s: read error"), quotef (input_filename));
- if (! STREQ (file_list[-1], "-"))
- fclose (in_stream);
- ok = false;
- }
- else if (! STREQ (file_list[-1], "-") && fclose (in_stream) != 0)
- {
- error (0, errno, "%s", quotef (input_filename));
+ error (0, in_errno, "%s", quotef (input_filename));
ok = false;
}
If an EOF or error, close the file. */
if (fileptr[i])
{
- if (ferror (fileptr[i]))
- {
- error (0, err, "%s", quotef (fnamptr[i]));
- ok = false;
- }
+ if (!ferror (fileptr[i]))
+ err = 0;
if (fileptr[i] == stdin)
clearerr (fileptr[i]); /* Also clear EOF. */
- else if (fclose (fileptr[i]) == EOF)
+ else if (fclose (fileptr[i]) == EOF && !err)
+ err = errno;
+ if (err)
{
- error (0, errno, "%s", quotef (fnamptr[i]));
+ error (0, err, "%s", quotef (fnamptr[i]));
ok = false;
}
if (charold != line_delim)
xputchar (line_delim);
- if (ferror (fileptr))
- {
- error (0, saved_errno, "%s", quotef (*fnamptr));
- ok = false;
- }
+ if (!ferror (fileptr))
+ saved_errno = 0;
if (is_stdin)
clearerr (fileptr); /* Also clear EOF. */
- else if (fclose (fileptr) == EOF)
+ else if (fclose (fileptr) != 0 && !saved_errno)
+ saved_errno = errno;
+ if (saved_errno)
{
- error (0, errno, "%s", quotef (*fnamptr));
+ error (0, saved_errno, "%s", quotef (*fnamptr));
ok = false;
}
}
if (p->status == CLOSED)
return;
- if (ferror (p->fp))
- die (EXIT_FAILURE, errno, "%s", quotef (p->name));
- if (fileno (p->fp) != STDIN_FILENO && fclose (p->fp) != 0)
- die (EXIT_FAILURE, errno, "%s", quotef (p->name));
+
+ int err = errno;
+ if (!ferror (p->fp))
+ err = 0;
+ if (fileno (p->fp) == STDIN_FILENO)
+ clearerr (p->fp);
+ else if (fclose (p->fp) != 0 && !err)
+ err = errno;
+ if (err)
+ die (EXIT_FAILURE, err, "%s", quotef (p->name));
if (!parallel_files)
{
if (!block->start)
die (EXIT_FAILURE, errno, "%s", quotef (using_stdin ? "-" : file_name));
+ if (using_stdin)
+ clearerr (stdin);
+
block->end = block->start + used_length;
}
{
case STDIN_FILENO:
/* Allow reading stdin from tty more than once. */
- if (feof (fp))
- clearerr (fp);
+ clearerr (fp);
break;
case STDOUT_FILENO:
checksum &= 0xffff; /* Keep it within bounds. */
}
- if (ferror (fp))
- {
- error (0, errno, "%s", quotef (file));
- if (!is_stdin)
- fclose (fp);
- return false;
- }
-
- if (!is_stdin && fclose (fp) != 0)
+ int err = errno;
+ if (!ferror (fp))
+ err = 0;
+ if (is_stdin)
+ clearerr (fp);
+ else if (fclose (fp) != 0 && !err)
+ err = errno;
+ if (err)
{
- error (0, errno, "%s", quotef (file));
+ error (0, err, "%s", quotef (file));
return false;
}