annotate lib/freopen-safer.c @ 17363:5a51fb7777a9

sys_select, sys_time: port 2013-01-30 Solaris 2.6 fix to Cygwin Problem reported by Marco Atzeri in <http://lists.gnu.org/archive/html/bug-gnulib/2013-03/msg00000.html>. * lib/sys_select.in.h [HAVE_SYS_SELECT_H && _CYGWIN_SYS_TIME_H]: Simply delegate to the system <sys/select.h> in this case too. Also, pay attention to _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H only if OSF/1, since otherwise Cygwin breaks, and it doesn't seem to be needed on Solaris either. * lib/sys_time.in.h [_CYGWIN_SYS_TIME_H]: Simply delgate to the system <sys/time.h> in this case.
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 19 Mar 2013 09:08:47 -0700
parents e542fd46ad6f
children 344018b6e5d7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12246
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
1 /* Invoke freopen, but avoid some glitches.
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
2
17249
e542fd46ad6f maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents: 16201
diff changeset
3 Copyright (C) 2009-2013 Free Software Foundation, Inc.
12246
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
4
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
8 (at your option) any later version.
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
9
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
13 GNU General Public License for more details.
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
14
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
17
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
18 /* Written by Eric Blake. */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
19
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
20 #include <config.h>
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
21
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
22 #include "stdio-safer.h"
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
23
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
24 #include <errno.h>
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
25 #include <fcntl.h>
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
26 #include <stdbool.h>
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
27 #include <unistd.h>
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
28
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
29 /* Guarantee that FD is open; all smaller FDs must already be open.
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
30 Return true if successful. */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
31 static bool
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
32 protect_fd (int fd)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
33 {
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
34 int value = open ("/dev/null", O_RDONLY);
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
35 if (value != fd)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
36 {
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
37 if (0 <= value)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
38 {
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
39 close (value);
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
40 errno = EBADF; /* Unexpected; this is as good as anything else. */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
41 }
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
42 return false;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
43 }
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
44 return true;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
45 }
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
46
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
47 /* Like freopen, but guarantee that reopening stdin, stdout, or stderr
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
48 preserves the invariant that STDxxx_FILENO==fileno(stdxxx), and
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
49 that no other stream will interfere with the standard streams.
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
50 This is necessary because most freopen implementations will change
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
51 the associated fd of a stream to the lowest available slot. */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
52
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
53 FILE *
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
54 freopen_safer (char const *name, char const *mode, FILE *f)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
55 {
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
56 /* Unfortunately, we cannot use the fopen_safer approach of using
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
57 fdopen (dup_safer (fileno (freopen (cmd, mode, f)))), because we
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
58 need to return f itself. The implementation of freopen(NULL,m,f)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
59 is system-dependent, so the best we can do is guarantee that all
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
60 lower-valued standard fds are open prior to the freopen call,
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
61 even though this puts more pressure on open fds. */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
62 bool protect_in = false;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
63 bool protect_out = false;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
64 bool protect_err = false;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
65 int saved_errno;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
66
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
67 switch (fileno (f))
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
68 {
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
69 default: /* -1 or not a standard stream. */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
70 if (dup2 (STDERR_FILENO, STDERR_FILENO) != STDERR_FILENO)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
71 protect_err = true;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
72 /* fall through */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
73 case STDERR_FILENO:
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
74 if (dup2 (STDOUT_FILENO, STDOUT_FILENO) != STDOUT_FILENO)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
75 protect_out = true;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
76 /* fall through */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
77 case STDOUT_FILENO:
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
78 if (dup2 (STDIN_FILENO, STDIN_FILENO) != STDIN_FILENO)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
79 protect_in = true;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
80 /* fall through */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
81 case STDIN_FILENO:
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
82 /* Nothing left to protect. */
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
83 break;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
84 }
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
85 if (protect_in && !protect_fd (STDIN_FILENO))
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
86 f = NULL;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
87 else if (protect_out && !protect_fd (STDOUT_FILENO))
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
88 f = NULL;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
89 else if (protect_err && !protect_fd (STDERR_FILENO))
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
90 f = NULL;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
91 else
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
92 f = freopen (name, mode, f);
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
93 saved_errno = errno;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
94 if (protect_err)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
95 close (STDERR_FILENO);
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
96 if (protect_out)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
97 close (STDOUT_FILENO);
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
98 if (protect_in)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
99 close (STDIN_FILENO);
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
100 if (!f)
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
101 errno = saved_errno;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
102 return f;
b156d2d1b827 freopen-safer: new module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
103 }