[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
adding bulletproofing for cases where stdin, stdout, stderr are closed
From: |
Paul Eggert |
Subject: |
adding bulletproofing for cases where stdin, stdout, stderr are closed |
Date: |
Mon, 11 Apr 2005 13:31:41 -0700 |
I installed the following patch to add bulletproofing for the cases
where stdin, stdout, or stderr are closed, and where open and/or
fopen can return one of the standard descriptors unexpectedly.
Unfortunately it's tricky to come up with test cases to illustrate the
problems here, since they often rely on a weird scenario like an I/O
error causing a diagnostic to be put into a file unexpectedly.
I can't promise that I caught all the troublesome scenarios, but I
patched all the ones I found.
2005-04-11 Paul Eggert <address@hidden>
Add bulletproofing for cases where stdin, stdout, or stderr are closed.
* lib/fcntl-safer.h, lib/open-safer.c: Remove.
* lib/fd-safer.c: New file.
* lib/dup-safer.c: Include unistd-safer.h first, to test interface.
(dup_safer) [!deefined F_DUPD]: Use new fd_safer function instead of
rolling our own code.
* lib/fts.c: Include unistd-safer.h.
(fts_safe_changedir): Use fd_safer.
* lib/getloadavg.c: Include unistd-safer.h.
(getloadavg): Use fd_safer.
* lib/getusershell.c: Include stdio-safer.h.
(getusershell): Use fopen_safer.
* lib/save-cwd.c: Include unistd-safer.h.
(save_cwd): Use fd_safer.
* lib/unistd-safer.h (fd_safer): New decl.
* lib/Makefile.am (libfetish_a_SOURCES): Remove dup-safer.c,
fcntl-safer.h, fopen-safer.c, open-safer.c, stdio-safer.h,
unistd-safer.h.
* m4/fcntl-safer.m4: Remove.
* m4/stdio-safer.m4 (gl_STDIO_SAFER): Use AC_LIBSOURCES and AC_LIBOBJ.
* m4/unistd-safer.m4 (gl_UNISTD_SAFER): Likewise.
Invoke gl_PREREQ_FD_SAFER.
(gl_PREREQ_FD_SAFER): New macro.
* m4/prereq.m4 (gl_PREREQ): Don't require gl_FCNTL_SAFER.
* src/comm.c: Include stdio-safer.h.
(compare_files): Exit right away on I/O error rather than continuing
and producing confusing output and error messages.
Return void, not int; all callers changed.
Use fopen_safer to avoid confusion with file descriptors.
* src/copy.c: Include unistd-safer.h.
(copy_reg): Use fd_safer.
* src/csplit.c: Include stdio-safer.h.
(input_desc): Remove unnecessary static initialization.
(set_input_file): Use STDIN_FILENO, not 0.
(create_output_file): Use fopen_safer.
* src/dircolors.c (dc_parse_file): Don't assume fopen does not
return stdin.
* src/head.c (head_file): Don't assume open does not return 0.
* src/join.c: Include stdio-safer.h.
(main): Use fopen_safer. Simplify the resulting code.
* src/md5sum.c (digest_file, digest_check):
Don't assume that fopen does not return stdin.
* src/nohup.c: Include unistd-safer.h.
(main): Don't dup stderr to stdin or stdout by mistake.
* src/od.c (check_and_close): Don't assume fopen does not return stdin.
* src/paste.c (paste_serial): Likewise.
* src/pr.c: Include stdio-safer.h.
(open_file): Use fopen_safer.
(close_file): Don't assume fopen does not return stdin.
* src/ptx.c (main): Don't assume fopen returns stdout after closing
stdout. Use freopen instead.
* src/shred.c: Include unistd-safer.h.
(wipename): Use fd_safer on directory file descriptor.
(wipefile): Remove special case for /dev/fd/* on older hosts.
It didn't work in general, and wasn't documented.
Use fd_safer.
* src/sort.c: Include unistd-safer.h.
(create_temp_file): Use fd_safer.
(xfclose): Don't assume fileno (stdin) == STDIN_FILENO, etc.
* src/split.c: Include unistd-safer.h.
(cwrite): Use fd_safer. Replace mystery constant 0666 with symbolic
version, as POSIX requires.
* src/sum.c (bsd_sum_file, sysv_sym_file):
Use same pattern as elsewhere for checking for stdin.
* src/tac.c: Include unistd-safer.h.
(copy_to_temp): Use fd_safer.
(tac_file): Don't assume fopen cannot return stdin.
* src/tail.c: Include unistd-safer.h rather than fcntl-safer.h.
(recheck, tail_file): Use fd_safer rather than open_safer.
* src/tee.c: Include stdio-safer.h.
(tee): Use fopen_safer.
* src/touch.c: Include unistd-safer.h.
(touch): Use fd_safer.
* src/tsort.c (have_read_stdin): Remove; no longer needed. All uses
removed.
(tsort): Do not assume fopen can't return stdin.
Close stdin before returning. All uses changed.
* src/unexpand.c (next_file): Don't assume fopen cannot return stdin.
* src/uniq.c: Include stdio_safer.h.
(check_file): Don't assume fopen cannot return stdin or stdout.
Remove lib/fcntl-safer.h, lib/open-safer.c, and m4/fcntl-safer.m4 in
addition to this patch.
--- /dev/null 2003-03-18 13:55:57 -0800
+++ lib/fd-safer.c 2005-04-11 11:24:45 -0700
@@ -0,0 +1,61 @@
+/* Return a safer copy of a file descriptor.
+
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "unistd-safer.h"
+
+#include <errno.h>
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+/* Return FD, unless FD would be a copy of standard input, output, or
+ error; in that case, return a duplicate of FD, closing FD. On
+ failure to duplicate, close FD, set errno, and return -1. Preserve
+ errno if FD is negative, so that the caller can always inspect
+ errno when the returned value is negative.
+
+ This function is usefully wrapped around functions that return file
+ descriptors, e.g., fd_safer (open ("file", O_RDONLY)). */
+
+int
+fd_safer (int fd)
+{
+ if (STDIN_FILENO <= fd && fd <= STDERR_FILENO)
+ {
+ int f = dup_safer (fd);
+ int e = errno;
+ close (fd);
+ errno = e;
+ fd = f;
+ }
+
+ return fd;
+}
Index: lib/dup-safer.c
===================================================================
RCS file: /fetish/cu/lib/dup-safer.c,v
retrieving revision 1.3
diff -p -u -r1.3 dup-safer.c
--- lib/dup-safer.c 2 Aug 2004 22:47:00 -0000 1.3
+++ lib/dup-safer.c 11 Apr 2005 19:38:49 -0000
@@ -1,5 +1,5 @@
/* Invoke dup, but avoid some glitches.
- Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
# include <config.h>
#endif
-#include <errno.h>
+#include "unistd-safer.h"
#if HAVE_FCNTL_H
# include <fcntl.h>
@@ -34,8 +34,6 @@
# define STDERR_FILENO 2
#endif
-#include <unistd-safer.h>
-
/* Like dup, but do not return STDIN_FILENO, STDOUT_FILENO, or
STDERR_FILENO. */
@@ -45,15 +43,8 @@ dup_safer (int fd)
#ifdef F_DUPFD
return fcntl (fd, F_DUPFD, STDERR_FILENO + 1);
#else
- int f = dup (fd);
- if (0 <= f && f <= STDERR_FILENO)
- {
- int f1 = dup_safer (f);
- int e = errno;
- close (f);
- errno = e;
- f = f1;
- }
- return f;
+ /* fd_safer calls us back, but eventually the recursion unwinds and
+ does the right thing. */
+ return fd_safer (dup (fd));
#endif
}
Index: lib/fts.c
===================================================================
RCS file: /fetish/cu/lib/fts.c,v
retrieving revision 1.23
diff -p -u -r1.23 fts.c
--- lib/fts.c 9 Apr 2005 14:19:49 -0000 1.23
+++ lib/fts.c 11 Apr 2005 19:38:49 -0000
@@ -68,6 +68,7 @@ static char sccsid[] = "@(#)fts.c 8.6 (B
#include "dirfd.h"
#include "fts_.h"
#include "intprops.h"
+#include "unistd-safer.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -1429,7 +1430,7 @@ fts_safe_changedir(sp, p, fd, path)
newfd = fd;
if (ISSET(FTS_NOCHDIR))
return (0);
- if (fd < 0 && (newfd = diropen (path)) < 0)
+ if (fd < 0 && (newfd = fd_safer (diropen (path))) < 0)
return (-1);
if (fstat(newfd, &sb)) {
ret = -1;
Index: lib/getloadavg.c
===================================================================
RCS file: /fetish/cu/lib/getloadavg.c,v
retrieving revision 1.27
diff -p -u -r1.27 getloadavg.c
--- lib/getloadavg.c 9 Mar 2005 19:21:43 -0000 1.27
+++ lib/getloadavg.c 11 Apr 2005 19:38:50 -0000
@@ -452,6 +452,8 @@
# else
# include <sys/file.h>
# endif
+
+# include "unistd-safer.h"
/* Avoid static vars inside a function since in HPUX they dump as pure. */
@@ -911,7 +913,7 @@ getloadavg (double loadavg[], int nelem)
if (!getloadavg_initialized)
{
# ifndef SUNOS_5
- channel = open ("/dev/kmem", 0);
+ channel = fd_safer (open ("/dev/kmem", O_RDONLY));
if (channel >= 0)
{
/* Set the channel to close on exec, so it does not
Index: lib/getusershell.c
===================================================================
RCS file: /fetish/cu/lib/getusershell.c,v
retrieving revision 1.18
diff -p -u -r1.18 getusershell.c
--- lib/getusershell.c 4 Oct 2004 20:18:43 -0000 1.18
+++ lib/getusershell.c 11 Apr 2005 19:38:50 -0000
@@ -1,6 +1,6 @@
/* getusershell.c -- Return names of valid user shells.
- Copyright (C) 1991, 1997, 2000, 2001, 2003, 2004 Free Software
+ Copyright (C) 1991, 1997, 2000, 2001, 2003, 2004, 2005 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -37,6 +37,7 @@
#include <stdlib.h>
#include <ctype.h>
+#include "stdio-safer.h"
#include "xalloc.h"
#if USE_UNLOCKED_IO
@@ -98,7 +99,7 @@ getusershell (void)
if (shellstream == NULL)
{
- shellstream = fopen (SHELLS_FILE, "r");
+ shellstream = fopen_safer (SHELLS_FILE, "r");
if (shellstream == NULL)
{
/* No shells file. Use the default list. */
Index: lib/save-cwd.c
===================================================================
RCS file: /fetish/cu/lib/save-cwd.c,v
retrieving revision 1.25
diff -p -u -r1.25 save-cwd.c
--- lib/save-cwd.c 9 Mar 2005 23:21:00 -0000 1.25
+++ lib/save-cwd.c 11 Apr 2005 19:38:50 -0000
@@ -42,6 +42,7 @@
#include <errno.h>
#include "chdir-long.h"
+#include "unistd-safer.h"
#include "xgetcwd.h"
/* On systems without the fchdir function (WOE), pretend that open
@@ -49,7 +50,7 @@
Since chdir_long requires fchdir, use chdir instead. */
#if !HAVE_FCHDIR
# undef open
-# define open(File, Flags) -1
+# define open(File, Flags) (-1)
# undef fchdir
# define fchdir(Fd) (abort (), -1)
# undef chdir_long
@@ -81,10 +82,10 @@ save_cwd (struct saved_cwd *cwd)
{
cwd->name = NULL;
- cwd->desc = open (".", O_RDONLY);
+ cwd->desc = fd_safer (open (".", O_RDONLY));
if (cwd->desc < 0)
{
- cwd->desc = open (".", O_WRONLY);
+ cwd->desc = fd_safer (open (".", O_WRONLY));
if (cwd->desc < 0)
{
cwd->name = xgetcwd ();
Index: lib/unistd-safer.h
===================================================================
RCS file: /fetish/cu/lib/unistd-safer.h,v
retrieving revision 1.3
diff -p -u -r1.3 unistd-safer.h
--- lib/unistd-safer.h 18 Aug 2003 09:44:49 -0000 1.3
+++ lib/unistd-safer.h 11 Apr 2005 19:38:50 -0000
@@ -1,6 +1,6 @@
-/* Invoke unistd functions, but avoid some glitches.
+/* Invoke unistd-like functions, but avoid some glitches.
- Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,3 +19,4 @@
/* Written by Paul Eggert. */
int dup_safer (int);
+int fd_safer (int);
Index: lib/Makefile.am
===================================================================
RCS file: /fetish/cu/lib/Makefile.am,v
retrieving revision 1.217
diff -p -u -r1.217 Makefile.am
--- lib/Makefile.am 21 Mar 2005 22:31:05 -0000 1.217
+++ lib/Makefile.am 11 Apr 2005 19:38:50 -0000
@@ -29,24 +29,18 @@ libfetish_a_SOURCES = \
allocsa.c allocsa.h \
dev-ino.h \
diacrit.c diacrit.h \
- dup-safer.c \
euidaccess.h \
exit.h \
- fcntl-safer.h \
- fopen-safer.c \
full-read.c full-read.h \
full-write.c full-write.h \
gettext.h \
localcharset.c localcharset.h \
mbswidth.c mbswidth.h \
- open-safer.c \
readtokens0.c readtokens0.h \
regex.h \
root-dev-ino.c root-dev-ino.h \
- stdio-safer.h \
time_r.c time_r.h \
unicodeio.c unicodeio.h \
- unistd-safer.h \
version-etc.c version-etc.h version-etc-fsf.c \
xalloc-die.c \
xfts.c xfts.h \
Index: m4/stdio-safer.m4
===================================================================
RCS file: /fetish/cu/m4/stdio-safer.m4,v
retrieving revision 1.2
diff -p -u -r1.2 stdio-safer.m4
--- m4/stdio-safer.m4 23 Jan 2005 09:07:57 -0000 1.2
+++ m4/stdio-safer.m4 11 Apr 2005 19:38:50 -0000
@@ -1,11 +1,14 @@
-# stdio-safer.m4 serial 2
-dnl Copyright (C) 2002 Free Software Foundation, Inc.
+# stdio-safer.m4 serial 3
+dnl Copyright (C) 2002, 2005 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_STDIO_SAFER],
[
+ AC_LIBSOURCES([fopen-safer.c, stdio-safer.h])
+ AC_LIBOBJ([fopen-safer])
+
dnl Prerequisites of lib/fopen-safer.c.
AC_CHECK_HEADERS_ONCE(unistd.h)
])
Index: m4/unistd-safer.m4
===================================================================
RCS file: /fetish/cu/m4/unistd-safer.m4,v
retrieving revision 1.2
diff -p -u -r1.2 unistd-safer.m4
--- m4/unistd-safer.m4 23 Jan 2005 09:07:57 -0000 1.2
+++ m4/unistd-safer.m4 11 Apr 2005 19:38:50 -0000
@@ -1,15 +1,25 @@
-# unistd-safer.m4 serial 2
-dnl Copyright (C) 2002 Free Software Foundation, Inc.
+# unistd-safer.m4 serial 3
+dnl Copyright (C) 2002, 2005 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_UNISTD_SAFER],
[
+ AC_LIBSOURCES([dup-safer.c, fd-safer.c, unistd-safer.h])
+ AC_LIBOBJ([dup-safer])
+ AC_LIBOBJ([fd-safer])
+
gl_PREREQ_DUP_SAFER
+ gl_PREREQ_FD_SAFER
])
# Prerequisites of lib/dup-safer.c.
AC_DEFUN([gl_PREREQ_DUP_SAFER], [
AC_CHECK_HEADERS_ONCE(fcntl.h unistd.h)
])
+
+# Prerequisites of lib/fd-safer.c.
+AC_DEFUN([gl_PREREQ_FD_SAFER], [
+ AC_CHECK_HEADERS_ONCE(unistd.h)
+])
Index: m4/prereq.m4
===================================================================
RCS file: /fetish/cu/m4/prereq.m4,v
retrieving revision 1.106
diff -p -u -r1.106 prereq.m4
--- m4/prereq.m4 21 Mar 2005 20:15:18 -0000 1.106
+++ m4/prereq.m4 11 Apr 2005 19:38:50 -0000
@@ -1,4 +1,4 @@
-#serial 51
+#serial 52
dnl We use gl_ for non Autoconf macros.
m4_pattern_forbid([^gl_[ABCDEFGHIJKLMNOPQRSTUVXYZ]])dnl
@@ -26,7 +26,6 @@ AC_DEFUN([gl_PREREQ],
AC_REQUIRE([gl_ERROR])
AC_REQUIRE([gl_EXCLUDE])
AC_REQUIRE([gl_EXITFAIL])
- AC_REQUIRE([gl_FCNTL_SAFER])
AC_REQUIRE([gl_FILEBLOCKS])
AC_REQUIRE([gl_FILEMODE])
AC_REQUIRE([gl_FILE_TYPE])
Index: src/comm.c
===================================================================
RCS file: /fetish/cu/src/comm.c,v
retrieving revision 1.79
diff -p -u -r1.79 comm.c
--- src/comm.c 28 Mar 2005 17:54:13 -0000 1.79
+++ src/comm.c 11 Apr 2005 19:38:50 -0000
@@ -27,6 +27,7 @@
#include "error.h"
#include "hard-locale.h"
#include "quote.h"
+#include "stdio-safer.h"
#include "xmemcoll.h"
/* The official name of this program (e.g., no `g' prefix). */
@@ -137,10 +138,9 @@ writeline (const struct linebuffer *line
/* Compare INFILES[0] and INFILES[1].
If either is "-", use the standard input for that file.
Assume that each input file is sorted;
- merge them and output the result.
- Return true if successful. */
+ merge them and output the result. */
-static bool
+static void
compare_files (char **infiles)
{
/* For each file, we have one linebuffer in lb1. */
@@ -153,9 +153,6 @@ compare_files (char **infiles)
/* streams[i] holds the input stream for file i. */
FILE *streams[2];
- /* errno values for each stream. */
- int saved_errno[2];
-
int i;
bool ret = true;
@@ -164,15 +161,15 @@ compare_files (char **infiles)
{
initbuffer (&lb1[i]);
thisline[i] = &lb1[i];
- streams[i] = (STREQ (infiles[i], "-") ? stdin : fopen (infiles[i], "r"));
+ streams[i] = (STREQ (infiles[i], "-")
+ ? stdin
+ : fopen_safer (infiles[i], "r"));
if (!streams[i])
- {
- error (0, errno, "%s", infiles[i]);
- return false;
- }
+ error (EXIT_FAILURE, errno, "%s", infiles[i]);
thisline[i] = readlinebuffer (thisline[i], streams[i]);
- saved_errno[i] = errno;
+ if (ferror (streams[i]))
+ error (EXIT_FAILURE, errno, "%s", infiles[i]);
}
while (thisline[0] || thisline[1])
@@ -214,31 +211,20 @@ compare_files (char **infiles)
if (order >= 0)
{
thisline[1] = readlinebuffer (thisline[1], streams[1]);
- saved_errno[1] = errno;
+ if (ferror (streams[1]))
+ error (EXIT_FAILURE, errno, "%s", infiles[1]);
}
if (order <= 0)
{
thisline[0] = readlinebuffer (thisline[0], streams[0]);
- saved_errno[0] = errno;
+ if (ferror (streams[0]))
+ error (EXIT_FAILURE, errno, "%s", infiles[0]);
}
}
- /* Free all storage and close all input streams. */
for (i = 0; i < 2; i++)
- {
- free (lb1[i].buffer);
- if (ferror (streams[i]))
- {
- error (0, saved_errno[i], "%s", infiles[i]);
- ret = false;
- }
- if (fclose (streams[i]) != 0)
- {
- error (0, errno, "%s", infiles[i]);
- ret = false;
- }
- }
- return ret;
+ if (fclose (streams[i]) != 0)
+ error (EXIT_FAILURE, errno, "%s", infiles[i]);
}
int
@@ -297,6 +283,7 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- exit (compare_files (argv + optind)
- ? EXIT_SUCCESS : EXIT_FAILURE);
+ compare_files (argv + optind);
+
+ exit (EXIT_SUCCESS);
}
Index: src/copy.c
===================================================================
RCS file: /fetish/cu/src/copy.c,v
retrieving revision 1.178
diff -p -u -r1.178 copy.c
--- src/copy.c 28 Mar 2005 17:55:43 -0000 1.178
+++ src/copy.c 11 Apr 2005 19:38:50 -0000
@@ -41,6 +41,7 @@
#include "quote.h"
#include "same.h"
#include "savedir.h"
+#include "unistd-safer.h"
#include "utimecmp.h"
#include "utimens.h"
#include "xreadlink.h"
@@ -216,6 +217,7 @@ copy_reg (const char *src_path, const ch
bool make_holes = false;
source_desc = open (src_path, O_RDONLY);
+ source_desc = fd_safer (source_desc);
if (source_desc < 0)
{
error (0, errno, _("cannot open %s for reading"), quote (src_path));
@@ -267,6 +269,7 @@ copy_reg (const char *src_path, const ch
}
}
+ dest_desc = fd_safer (dest_desc);
if (dest_desc < 0)
{
error (0, errno, _("cannot create regular file %s"), quote (dst_path));
Index: src/csplit.c
===================================================================
RCS file: /fetish/cu/src/csplit.c,v
retrieving revision 1.136
diff -p -u -r1.136 csplit.c
--- src/csplit.c 9 Apr 2005 04:55:05 -0000 1.136
+++ src/csplit.c 11 Apr 2005 19:38:51 -0000
@@ -31,8 +31,9 @@
#include "error.h"
#include "inttostr.h"
-#include "safe-read.h"
#include "quote.h"
+#include "safe-read.h"
+#include "stdio-safer.h"
#include "xstrtol.h"
/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is
@@ -130,7 +131,7 @@ void usage (int status);
char *program_name;
/* Input file descriptor. */
-static int input_desc = 0;
+static int input_desc;
/* Start of buffer list. */
static struct buffer_record *head = NULL;
@@ -643,7 +644,7 @@ static void
set_input_file (const char *name)
{
if (STREQ (name, "-"))
- input_desc = 0;
+ input_desc = STDIN_FILENO;
else
{
input_desc = open (name, O_RDONLY);
@@ -939,7 +940,7 @@ create_output_file (void)
/* Create the output file in a critical section, to avoid races. */
sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
- output_stream = fopen (output_filename, "w");
+ output_stream = fopen_safer (output_filename, "w");
fopen_ok = (output_stream != NULL);
fopen_errno = errno;
files_created += fopen_ok;
Index: src/dircolors.c
===================================================================
RCS file: /fetish/cu/src/dircolors.c,v
retrieving revision 1.84
diff -p -u -r1.84 dircolors.c
--- src/dircolors.c 26 Mar 2005 17:39:17 -0000 1.84
+++ src/dircolors.c 11 Apr 2005 19:38:51 -0000
@@ -376,8 +376,9 @@ dc_parse_file (const char *filename)
{
FILE *fp;
bool ok;
+ bool is_stdin = STREQ (filename, "-");
- if (STREQ (filename, "-"))
+ if (is_stdin)
{
have_read_stdin = true;
fp = stdin;
@@ -398,7 +399,7 @@ dc_parse_file (const char *filename)
ok = dc_parse_stream (fp, filename);
- if (fp != stdin && fclose (fp) == EOF)
+ if (!is_stdin && fclose (fp) != 0)
{
error (0, errno, "%s", quote (filename));
return false;
Index: src/head.c
===================================================================
RCS file: /fetish/cu/src/head.c,v
retrieving revision 1.97
diff -p -u -r1.97 head.c
--- src/head.c 30 Jan 2005 17:57:24 -0000 1.97
+++ src/head.c 11 Apr 2005 19:38:51 -0000
@@ -851,8 +851,9 @@ head_file (const char *filename, uintmax
{
int fd;
bool ok;
+ bool is_stdin = STREQ (filename, "-");
- if (STREQ (filename, "-"))
+ if (is_stdin)
{
have_read_stdin = true;
fd = STDIN_FILENO;
@@ -869,7 +870,7 @@ head_file (const char *filename, uintmax
}
ok = head (filename, fd, n_units, count_lines, elide_from_end);
- if (fd != STDIN_FILENO && close (fd) == -1)
+ if (!is_stdin && close (fd) != 0)
{
error (0, errno, _("closing %s"), quote (filename));
return false;
Index: src/join.c
===================================================================
RCS file: /fetish/cu/src/join.c,v
retrieving revision 1.134
diff -p -u -r1.134 join.c
--- src/join.c 8 Dec 2004 23:05:13 -0000 1.134
+++ src/join.c 11 Apr 2005 19:38:51 -0000
@@ -1,5 +1,5 @@
/* join - join lines of two files on a common field
- Copyright (C) 91, 1995-2004 Free Software Foundation, Inc.
+ Copyright (C) 91, 1995-2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@
#include "memcasecmp.h"
#include "posixver.h"
#include "quote.h"
+#include "stdio-safer.h"
#include "xmemcoll.h"
#include "xstrtol.h"
@@ -852,22 +853,20 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- fp1 = STREQ (names[0], "-") ? stdin : fopen (names[0], "r");
+ fp1 = STREQ (names[0], "-") ? stdin : fopen_safer (names[0], "r");
if (!fp1)
error (EXIT_FAILURE, errno, "%s", names[0]);
- fp2 = STREQ (names[1], "-") ? stdin : fopen (names[1], "r");
+ fp2 = STREQ (names[1], "-") ? stdin : fopen_safer (names[1], "r");
if (!fp2)
error (EXIT_FAILURE, errno, "%s", names[1]);
if (fp1 == fp2)
error (EXIT_FAILURE, errno, _("both files cannot be standard input"));
join (fp1, fp2);
- if (fp1 != stdin && fclose (fp1) == EOF)
+ if (fclose (fp1) != 0)
error (EXIT_FAILURE, errno, "%s", names[0]);
- if (fp2 != stdin && fclose (fp2) == EOF)
+ if (fclose (fp2) != 0)
error (EXIT_FAILURE, errno, "%s", names[1]);
- if ((fp1 == stdin || fp2 == stdin) && fclose (stdin) == EOF)
- error (EXIT_FAILURE, errno, "-");
exit (EXIT_SUCCESS);
}
Index: src/md5sum.c
===================================================================
RCS file: /fetish/cu/src/md5sum.c,v
retrieving revision 1.130
diff -p -u -r1.130 md5sum.c
--- src/md5sum.c 7 Apr 2005 20:09:46 -0000 1.130
+++ src/md5sum.c 11 Apr 2005 19:38:51 -0000
@@ -335,8 +335,9 @@ digest_file (const char *filename, bool
{
FILE *fp;
int err;
+ bool is_stdin = STREQ (filename, "-");
- if (STREQ (filename, "-"))
+ if (is_stdin)
{
have_read_stdin = true;
fp = stdin;
@@ -370,7 +371,7 @@ digest_file (const char *filename, bool
return false;
}
- if (fp != stdin && fclose (fp) == EOF)
+ if (!is_stdin && fclose (fp) != 0)
{
error (0, errno, "%s", filename);
return false;
@@ -390,8 +391,9 @@ digest_check (const char *checkfile_name
uintmax_t line_number;
char *line;
size_t line_chars_allocated;
+ bool is_stdin = STREQ (checkfile_name, "-");
- if (STREQ (checkfile_name, "-"))
+ if (is_stdin)
{
have_read_stdin = true;
checkfile_name = _("standard input");
@@ -505,7 +507,7 @@ digest_check (const char *checkfile_name
return false;
}
- if (checkfile_stream != stdin && fclose (checkfile_stream) == EOF)
+ if (!is_stdin && fclose (checkfile_stream) != 0)
{
error (0, errno, "%s", checkfile_name);
return false;
Index: src/nohup.c
===================================================================
RCS file: /fetish/cu/src/nohup.c,v
retrieving revision 1.21
diff -p -u -r1.21 nohup.c
--- src/nohup.c 5 Apr 2005 11:53:38 -0000 1.21
+++ src/nohup.c 11 Apr 2005 19:38:51 -0000
@@ -25,11 +25,12 @@
#include "system.h"
+#include "cloexec.h"
#include "error.h"
#include "long-options.h"
#include "path-concat.h"
#include "quote.h"
-#include "cloexec.h"
+#include "unistd-safer.h"
#define PROGRAM_NAME "nohup"
@@ -145,7 +146,7 @@ main (int argc, char **argv)
if execve fails. It's no big deal if this dup fails. It might
not change anything, and at worst, it'll lead to suppression of
the post-failed-execve diagnostic. */
- saved_stderr_fd = dup (STDERR_FILENO);
+ saved_stderr_fd = dup_safer (STDERR_FILENO);
if (0 <= saved_stderr_fd
&& set_cloexec_flag (saved_stderr_fd, true) != 0)
Index: src/od.c
===================================================================
RCS file: /fetish/cu/src/od.c,v
retrieving revision 1.153
diff -p -u -r1.153 od.c
--- src/od.c 17 Mar 2005 14:34:23 -0000 1.153
+++ src/od.c 11 Apr 2005 19:38:52 -0000
@@ -240,7 +240,7 @@ static size_t n_specs_allocated;
static size_t bytes_per_block;
/* Human-readable representation of *file_list (for error messages).
- It differs from *file_list only when *file_list is "-". */
+ It differs from file_list[-1] only when file_list[-1] is "-". */
static char const *input_filename;
/* A NULL-terminated list of the file-arguments from the command line. */
@@ -937,11 +937,11 @@ check_and_close (int in_errno)
if (ferror (in_stream))
{
error (0, in_errno, _("%s: read error"), input_filename);
- if (in_stream != stdin)
+ if (! STREQ (file_list[-1], "-"))
fclose (in_stream);
ok = false;
}
- else if (in_stream != stdin && fclose (in_stream) == EOF)
+ else if (! STREQ (file_list[-1], "-") && fclose (in_stream) != 0)
{
error (0, errno, "%s", input_filename);
ok = false;
Index: src/paste.c
===================================================================
RCS file: /fetish/cu/src/paste.c,v
retrieving revision 1.78
diff -p -u -r1.78 paste.c
--- src/paste.c 28 Mar 2005 18:05:53 -0000 1.78
+++ src/paste.c 11 Apr 2005 19:38:52 -0000
@@ -336,7 +336,8 @@ paste_serial (size_t nfiles, char **fnam
for (; nfiles; nfiles--, fnamptr++)
{
int saved_errno;
- if (STREQ (*fnamptr, "-"))
+ bool is_stdin = STREQ (*fnamptr, "-");
+ if (is_stdin)
{
have_read_stdin = true;
fileptr = stdin;
@@ -394,7 +395,7 @@ paste_serial (size_t nfiles, char **fnam
error (0, saved_errno, "%s", *fnamptr);
ok = false;
}
- if (fileptr == stdin)
+ if (is_stdin)
clearerr (fileptr); /* Also clear EOF. */
else if (fclose (fileptr) == EOF)
{
Index: src/pr.c
===================================================================
RCS file: /fetish/cu/src/pr.c,v
retrieving revision 1.142
diff -p -u -r1.142 pr.c
--- src/pr.c 9 Apr 2005 07:23:50 -0000 1.142
+++ src/pr.c 11 Apr 2005 19:38:52 -0000
@@ -320,6 +320,7 @@
#include "inttostr.h"
#include "mbswidth.h"
#include "posixver.h"
+#include "stdio-safer.h"
#include "strftime.h"
#include "xstrtol.h"
@@ -1513,7 +1514,7 @@ open_file (char *name, COLUMN *p)
else
{
p->name = name;
- p->fp = fopen (name, "r");
+ p->fp = fopen_safer (name, "r");
}
if (p->fp == NULL)
{
@@ -1543,7 +1544,7 @@ close_file (COLUMN *p)
return;
if (ferror (p->fp))
error (EXIT_FAILURE, errno, "%s", p->name);
- if (p->fp != stdin && fclose (p->fp) == EOF)
+ if (fileno (p->fp) != STDIN_FILENO && fclose (p->fp) != 0)
error (EXIT_FAILURE, errno, "%s", p->name);
if (!parallel_files)
Index: src/ptx.c
===================================================================
RCS file: /fetish/cu/src/ptx.c,v
retrieving revision 1.46
diff -p -u -r1.46 ptx.c
--- src/ptx.c 28 Mar 2005 18:08:12 -0000 1.46
+++ src/ptx.c 11 Apr 2005 19:38:53 -0000
@@ -2154,9 +2154,7 @@ Inc., 59 Temple Place - Suite 330, Bosto
if (optind < argc)
{
- /* FIXME: don't fclose here? */
- fclose (stdout);
- if (fopen (argv[optind], "w") == NULL)
+ if (! freopen (argv[optind], "w", stdout))
error (EXIT_FAILURE, errno, "%s", argv[optind]);
optind++;
}
Index: src/shred.c
===================================================================
RCS file: /fetish/cu/src/shred.c,v
retrieving revision 1.109
diff -p -u -r1.109 shred.c
--- src/shred.c 9 Apr 2005 04:57:15 -0000 1.109
+++ src/shred.c 11 Apr 2005 19:38:53 -0000
@@ -108,6 +108,7 @@
#include "inttostr.h"
#include "quotearg.h" /* For quotearg_colon */
#include "quote.h" /* For quotearg_colon */
+#include "unistd-safer.h"
#define DEFAULT_PASSES 25 /* Default */
@@ -1345,6 +1346,7 @@ wipename (char *oldname, char const *qol
int dir_fd = open (dir, O_WRONLY | O_NOCTTY);
if (dir_fd < 0)
dir_fd = open (dir, O_RDONLY | O_NOCTTY);
+ dir_fd = fd_safer (dir_fd);
if (flags->verbose)
error (0, 0, _("%s: removing"), qoldname);
@@ -1434,32 +1436,11 @@ wipefile (char *name, char const *qname,
int fd;
fd = open (name, O_WRONLY | O_NOCTTY);
- if (fd < 0)
- {
- if (errno == EACCES && flags->force)
- {
- if (chmod (name, S_IWUSR) >= 0) /* 0200, user-write-only */
- fd = open (name, O_WRONLY | O_NOCTTY);
- }
- else if ((errno == ENOENT || errno == ENOTDIR)
- && strncmp (name, "/dev/fd/", 8) == 0)
- {
- /* We accept /dev/fd/# even if the OS doesn't support it */
- int errnum = errno;
- unsigned long int num;
- char *p;
- errno = 0;
- num = strtoul (name + 8, &p, 10);
- /* If it's completely decimal with no leading zeros... */
- if (errno == 0 && !*p && num <= INT_MAX &&
- (('1' <= name[8] && name[8] <= '9')
- || (name[8] == '0' && !name[9])))
- {
- return wipefd (num, qname, s, flags);
- }
- errno = errnum;
- }
- }
+ if (fd < 0
+ && (errno == EACCES && flags->force)
+ && chmod (name, S_IWUSR) == 0)
+ fd = open (name, O_WRONLY | O_NOCTTY);
+ fd = fd_safer (fd);
if (fd < 0)
{
error (0, errno, _("%s: failed to open for writing"), qname);
Index: src/sort.c
===================================================================
RCS file: /fetish/cu/src/sort.c,v
retrieving revision 1.306
diff -p -u -r1.306 sort.c
--- src/sort.c 9 Apr 2005 04:57:37 -0000 1.306
+++ src/sort.c 11 Apr 2005 19:38:53 -0000
@@ -35,6 +35,7 @@
#include "posixver.h"
#include "quote.h"
#include "stdio-safer.h"
+#include "unistd-safer.h"
#include "xmemcoll.h"
#include "xstrtol.h"
@@ -438,6 +439,7 @@ create_temp_file (FILE **pfp)
sigprocmask (SIG_SETMASK, &oldset, NULL);
errno = saved_errno;
+ fd = fd_safer (fd);
if (fd < 0 || (*pfp = fdopen (fd, "w")) == NULL)
die (_("cannot create temporary file"), file);
@@ -447,7 +449,8 @@ create_temp_file (FILE **pfp)
/* Return a stream for FILE, opened with mode HOW. A null FILE means
standard output; HOW should be "w". When opening for input, "-"
means standard input. To avoid confusion, do not return file
- descriptors 0, 1, or 2. */
+ descriptors STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO when
+ opening an ordinary FILE. */
static FILE *
xfopen (const char *file, const char *how)
@@ -475,22 +478,24 @@ xfopen (const char *file, const char *ho
static void
xfclose (FILE *fp, char const *file)
{
- if (fp == stdin)
+ switch (fileno (fp))
{
- /* Allow reading stdin from tty more than once. */
+ case STDIN_FILENO:
+ /* Allow reading stdin from tty more than once. */
if (feof (fp))
clearerr (fp);
- }
- else if (fp == stdout)
- {
+ break;
+
+ case STDOUT_FILENO:
/* Don't close stdout just yet. close_stdout does that. */
if (fflush (fp) != 0)
die (_("fflush failed"), file);
- }
- else
- {
+ break;
+
+ default:
if (fclose (fp) != 0)
die (_("close failed"), file);
+ break;
}
}
@@ -1953,11 +1958,11 @@ avoid_trashing_input (char **files, size
for (i = ntemps; i < nfiles; i++)
{
- bool standard_input = STREQ (files[i], "-");
+ bool is_stdin = STREQ (files[i], "-");
bool same;
struct stat instat;
- if (outfile && STREQ (outfile, files[i]) && ! standard_input)
+ if (outfile && STREQ (outfile, files[i]) && !is_stdin)
same = true;
else
{
@@ -1971,7 +1976,7 @@ avoid_trashing_input (char **files, size
got_outstat = true;
}
- same = (((standard_input
+ same = (((is_stdin
? fstat (STDIN_FILENO, &instat)
: stat (files[i], &instat))
== 0)
Index: src/split.c
===================================================================
RCS file: /fetish/cu/src/split.c,v
retrieving revision 1.104
diff -p -u -r1.104 split.c
--- src/split.c 25 Mar 2005 20:59:48 -0000 1.104
+++ src/split.c 11 Apr 2005 19:38:54 -0000
@@ -37,6 +37,7 @@
#include "posixver.h"
#include "quote.h"
#include "safe-read.h"
+#include "unistd-safer.h"
#include "xstrtol.h"
/* The official name of this program (e.g., no `g' prefix). */
@@ -212,8 +213,10 @@ cwrite (bool new_file_flag, const char *
next_file_name ();
if (verbose)
fprintf (stderr, _("creating file `%s'\n"), outfile);
- output_desc = open (outfile,
- O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ output_desc = fd_safer (open (outfile,
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+ (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
+ | S_IROTH | S_IWOTH)));
if (output_desc < 0)
error (EXIT_FAILURE, errno, "%s", outfile);
}
Index: src/sum.c
===================================================================
RCS file: /fetish/cu/src/sum.c,v
retrieving revision 1.76
diff -p -u -r1.76 sum.c
--- src/sum.c 6 Mar 2005 16:32:23 -0000 1.76
+++ src/sum.c 11 Apr 2005 19:38:54 -0000
@@ -91,8 +91,9 @@ bsd_sum_file (const char *file, int prin
uintmax_t total_bytes = 0; /* The number of bytes. */
int ch; /* Each character read. */
char hbuf[LONGEST_HUMAN_READABLE + 1];
+ bool is_stdin = STREQ (file, "-");
- if (STREQ (file, "-"))
+ if (is_stdin)
{
fp = stdin;
have_read_stdin = true;
@@ -120,12 +121,12 @@ bsd_sum_file (const char *file, int prin
if (ferror (fp))
{
error (0, errno, "%s", file);
- if (!STREQ (file, "-"))
+ if (!is_stdin)
fclose (fp);
return false;
}
- if (!STREQ (file, "-") && fclose (fp) == EOF)
+ if (!is_stdin && fclose (fp) != 0)
{
error (0, errno, "%s", file);
return false;
@@ -158,9 +159,11 @@ sysv_sum_file (const char *file, int pri
/* The sum of all the input bytes, modulo (UINT_MAX + 1). */
unsigned int s = 0;
- if (STREQ (file, "-"))
+ bool is_stdin = STREQ (file, "-");
+
+ if (is_stdin)
{
- fd = 0;
+ fd = STDIN_FILENO;
have_read_stdin = true;
}
else
@@ -186,7 +189,7 @@ sysv_sum_file (const char *file, int pri
if (bytes_read == SAFE_READ_ERROR)
{
error (0, errno, "%s", file);
- if (!STREQ (file, "-"))
+ if (!is_stdin)
close (fd);
return false;
}
@@ -196,7 +199,7 @@ sysv_sum_file (const char *file, int pri
total_bytes += bytes_read;
}
- if (!STREQ (file, "-") && close (fd) == -1)
+ if (!is_stdin && close (fd) != 0)
{
error (0, errno, "%s", file);
return false;
Index: src/tac.c
===================================================================
RCS file: /fetish/cu/src/tac.c,v
retrieving revision 1.118
diff -p -u -r1.118 tac.c
--- src/tac.c 28 Mar 2005 18:11:18 -0000 1.118
+++ src/tac.c 11 Apr 2005 19:38:54 -0000
@@ -48,6 +48,7 @@ tac -r -s '.\|
#include "quote.h"
#include "quotearg.h"
#include "safe-read.h"
+#include "unistd-safer.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "tac"
@@ -448,14 +449,13 @@ copy_to_temp (FILE **g_tmp, char **g_tem
tempfile = template;
fd = mkstemp (template);
- if (fd == -1)
+ if (fd < 0)
{
error (0, errno, _("cannot create temporary file %s"), quote (tempfile));
return false;
}
- tmp = fdopen (fd, "w+");
- if (tmp == NULL)
+ if ((fd = fd_safer (fd)) < 0 || ! (tmp = fdopen (fd, "w+")))
{
error (0, errno, _("cannot open %s for writing"), quote (tempfile));
close (fd);
@@ -521,8 +521,9 @@ tac_file (const char *filename)
bool ok;
off_t file_size;
int fd;
+ bool is_stdin = STREQ (filename, "-");
- if (STREQ (filename, "-"))
+ if (is_stdin)
{
have_read_stdin = true;
fd = STDIN_FILENO;
@@ -554,7 +555,7 @@ tac_file (const char *filename)
? tac_seekable (fd, filename)
: tac_nonseekable (fd, filename));
- if (fd != STDIN_FILENO && close (fd) == -1)
+ if (!is_stdin && close (fd) != 0)
{
error (0, errno, _("%s: read error"), quotearg_colon (filename));
ok = false;
Index: src/tail.c
===================================================================
RCS file: /fetish/cu/src/tail.c,v
retrieving revision 1.233
diff -p -u -r1.233 tail.c
--- src/tail.c 28 Mar 2005 18:18:21 -0000 1.233
+++ src/tail.c 11 Apr 2005 19:38:54 -0000
@@ -35,11 +35,11 @@
#include "argmatch.h"
#include "c-strtod.h"
#include "error.h"
-#include "fcntl-safer.h"
#include "inttostr.h"
#include "posixver.h"
#include "quote.h"
#include "safe-read.h"
+#include "unistd-safer.h"
#include "xnanosleep.h"
#include "xstrtol.h"
#include "xstrtod.h"
@@ -856,7 +856,8 @@ recheck (struct File_spec *f, bool block
bool new_file;
int fd = (is_stdin
? STDIN_FILENO
- : open_safer (f->name, O_RDONLY | (blocking ? 0 : O_NONBLOCK)));
+ : fd_safer (open (f->name,
+ O_RDONLY | (blocking ? 0 : O_NONBLOCK))));
assert (valid_file_spec (f));
@@ -1286,7 +1287,7 @@ tail_file (struct File_spec *f, uintmax_
}
else
{
- fd = open_safer (f->name, O_RDONLY);
+ fd = fd_safer (open (f->name, O_RDONLY));
}
f->tailable = !(reopen_inaccessible_files && fd == -1);
Index: src/tee.c
===================================================================
RCS file: /fetish/cu/src/tee.c,v
retrieving revision 1.77
diff -p -u -r1.77 tee.c
--- src/tee.c 5 Apr 2005 11:40:53 -0000 1.77
+++ src/tee.c 11 Apr 2005 19:38:54 -0000
@@ -1,5 +1,5 @@
/* tee - read from standard input and write to standard output and files.
- Copyright (C) 85,1990-2004 Free Software Foundation, Inc.
+ Copyright (C) 85,1990-2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
#include "system.h"
#include "error.h"
+#include "stdio-safer.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "tee"
@@ -161,7 +162,7 @@ tee (int nfiles, const char **files)
{
descriptors[i] = (STREQ (files[i], "-")
? stdout
- : fopen (files[i], mode_string));
+ : fopen_safer (files[i], mode_string));
if (descriptors[i] == NULL)
{
error (0, errno, "%s", files[i]);
Index: src/touch.c
===================================================================
RCS file: /fetish/cu/src/touch.c,v
retrieving revision 1.128
diff -p -u -r1.128 touch.c
--- src/touch.c 28 Mar 2005 18:13:40 -0000 1.128
+++ src/touch.c 11 Apr 2005 19:38:54 -0000
@@ -31,6 +31,7 @@
#include "posixver.h"
#include "quote.h"
#include "safe-read.h"
+#include "unistd-safer.h"
#include "utimens.h"
/* The official name of this program (e.g., no `g' prefix). */
@@ -128,6 +129,7 @@ touch (const char *file)
/* Try to open FILE, creating it if necessary. */
fd = open (file, O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+ fd = fd_safer (fd);
/* Don't save a copy of errno if it's EISDIR, since that would lead
touch to give a bogus diagnostic for e.g., `touch /' (assuming
Index: src/tsort.c
===================================================================
RCS file: /fetish/cu/src/tsort.c,v
retrieving revision 1.46
diff -p -u -r1.46 tsort.c
--- src/tsort.c 6 Mar 2005 16:33:28 -0000 1.46
+++ src/tsort.c 11 Apr 2005 19:38:54 -0000
@@ -63,9 +63,6 @@ struct item
/* The name this program was run with. */
char *program_name;
-/* True if any of the input files are the standard input. */
-static bool have_read_stdin;
-
/* The head of the sorted list. */
static struct item *head = NULL;
@@ -442,30 +439,21 @@ tsort (const char *file)
struct item *root;
struct item *j = NULL;
struct item *k = NULL;
- FILE *fp;
token_buffer tokenbuffer;
+ bool is_stdin = STREQ (file, "-");
/* Intialize the head of the tree will hold the strings we're sorting. */
root = new_item (NULL);
- if (STREQ (file, "-"))
- {
- fp = stdin;
- have_read_stdin = true;
- }
- else
- {
- fp = fopen (file, "r");
- if (fp == NULL)
- error (EXIT_FAILURE, errno, "%s", file);
- }
+ if (!is_stdin && ! freopen (file, "r", stdin))
+ error (EXIT_FAILURE, errno, "%s", file);
init_tokenbuffer (&tokenbuffer);
while (1)
{
/* T2. Next Relation. */
- size_t len = readtoken (fp, DELIM, sizeof (DELIM) - 1, &tokenbuffer);
+ size_t len = readtoken (stdin, DELIM, sizeof (DELIM) - 1, &tokenbuffer);
if (len == (size_t) -1)
break;
@@ -534,6 +522,10 @@ tsort (const char *file)
}
}
+ if (fclose (stdin) != 0)
+ error (EXIT_FAILURE, errno,
+ is_stdin ? _("standard input") : file);
+
return ok;
}
@@ -555,8 +547,6 @@ main (int argc, char **argv)
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
usage (EXIT_FAILURE);
- have_read_stdin = false;
-
if (1 < argc - optind)
{
error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
@@ -565,8 +555,5 @@ main (int argc, char **argv)
ok = tsort (optind == argc ? "-" : argv[optind]);
- if (have_read_stdin && fclose (stdin) == EOF)
- error (EXIT_FAILURE, errno, _("standard input"));
-
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
}
Index: src/unexpand.c
===================================================================
RCS file: /fetish/cu/src/unexpand.c,v
retrieving revision 1.88
diff -p -u -r1.88 unexpand.c
--- src/unexpand.c 25 Mar 2005 20:59:35 -0000 1.88
+++ src/unexpand.c 11 Apr 2005 19:38:54 -0000
@@ -257,7 +257,7 @@ next_file (FILE *fp)
error (0, errno, "%s", prev_file);
exit_status = EXIT_FAILURE;
}
- if (fp == stdin)
+ if (STREQ (prev_file, "-"))
clearerr (fp); /* Also clear EOF. */
else if (fclose (fp) != 0)
{
@@ -268,7 +268,7 @@ next_file (FILE *fp)
while ((file = *file_list++) != NULL)
{
- if (file[0] == '-' && file[1] == '\0')
+ if (STREQ (file, "-"))
{
have_read_stdin = true;
prev_file = file;
Index: src/uniq.c
===================================================================
RCS file: /fetish/cu/src/uniq.c,v
retrieving revision 1.120
diff -p -u -r1.120 uniq.c
--- src/uniq.c 28 Mar 2005 18:14:15 -0000 1.120
+++ src/uniq.c 11 Apr 2005 19:38:54 -0000
@@ -30,6 +30,7 @@
#include "hard-locale.h"
#include "posixver.h"
#include "quote.h"
+#include "stdio-safer.h"
#include "xmemcoll.h"
#include "xstrtol.h"
#include "memcasecmp.h"
@@ -261,24 +262,22 @@ writeline (struct linebuffer const *line
static void
check_file (const char *infile, const char *outfile)
{
- FILE *istream;
FILE *ostream;
struct linebuffer lb1, lb2;
struct linebuffer *thisline, *prevline;
+ bool is_stdin = STREQ (infile, "-");
+ bool is_stdout = STREQ (outfile, "-");
- if (STREQ (infile, "-"))
- istream = stdin;
- else
- istream = fopen (infile, "r");
- if (istream == NULL)
+ if (!is_stdin && ! freopen (infile, "r", stdin))
error (EXIT_FAILURE, errno, "%s", infile);
-
- if (STREQ (outfile, "-"))
+ if (is_stdout)
ostream = stdout;
else
- ostream = fopen (outfile, "w");
- if (ostream == NULL)
- error (EXIT_FAILURE, errno, "%s", outfile);
+ {
+ ostream = fopen_safer (outfile, "w");
+ if (! ostream)
+ error (EXIT_FAILURE, errno, "%s", outfile);
+ }
thisline = &lb1;
prevline = &lb2;
@@ -298,11 +297,11 @@ check_file (const char *infile, const ch
char *prevfield IF_LINT (= NULL);
size_t prevlen IF_LINT (= 0);
- while (!feof (istream))
+ while (!feof (stdin))
{
char *thisfield;
size_t thislen;
- if (readlinebuffer (thisline, istream) == 0)
+ if (readlinebuffer (thisline, stdin) == 0)
break;
thisfield = find_field (thisline);
thislen = thisline->length - 1 - (thisfield - thisline->buffer);
@@ -325,19 +324,19 @@ check_file (const char *infile, const ch
uintmax_t match_count = 0;
bool first_delimiter = true;
- if (readlinebuffer (prevline, istream) == 0)
+ if (readlinebuffer (prevline, stdin) == 0)
goto closefiles;
prevfield = find_field (prevline);
prevlen = prevline->length - 1 - (prevfield - prevline->buffer);
- while (!feof (istream))
+ while (!feof (stdin))
{
bool match;
char *thisfield;
size_t thislen;
- if (readlinebuffer (thisline, istream) == 0)
+ if (readlinebuffer (thisline, stdin) == 0)
{
- if (ferror (istream))
+ if (ferror (stdin))
goto closefiles;
break;
}
@@ -384,18 +383,13 @@ check_file (const char *infile, const ch
}
closefiles:
- if (ferror (istream) || fclose (istream) == EOF)
- error (EXIT_FAILURE, errno, _("error reading %s"), infile);
+ if (ferror (stdin) || fclose (stdin) != 0)
+ error (EXIT_FAILURE, 0, _("error reading %s"), infile);
/* Check for errors and close ostream only if it's not stdout --
stdout is handled via the atexit-invoked close_stdout function. */
- if (ostream != stdout)
- {
- if (ferror (ostream))
- error (EXIT_FAILURE, 0, _("error writing %s"), outfile);
- if (ostream != stdout && fclose (ostream) != 0)
- error (EXIT_FAILURE, errno, _("error writing %s"), outfile);
- }
+ if (!is_stdout && (ferror (ostream) || fclose (ostream) != 0))
+ error (EXIT_FAILURE, 0, _("error writing %s"), outfile);
free (lb1.buffer);
free (lb2.buffer);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- adding bulletproofing for cases where stdin, stdout, stderr are closed,
Paul Eggert <=