This source file includes following definitions.
- protect_fd
- freopen_safer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21
22 #include "stdio-safer.h"
23
24 #include "attribute.h"
25
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <stdbool.h>
29 #include <unistd.h>
30
31
32
33 static bool
34 protect_fd (int fd)
35 {
36 int value = open ("/dev/null", O_RDONLY);
37 if (value != fd)
38 {
39 if (0 <= value)
40 {
41 close (value);
42 errno = EBADF;
43 }
44 return false;
45 }
46 return true;
47 }
48
49
50
51
52
53
54
55 FILE *
56 freopen_safer (char const *name, char const *mode, FILE *f)
57 {
58
59
60
61
62
63
64 bool protect_in = false;
65 bool protect_out = false;
66 bool protect_err = false;
67 int saved_errno;
68
69 switch (fileno (f))
70 {
71 default:
72 if (dup2 (STDERR_FILENO, STDERR_FILENO) != STDERR_FILENO)
73 protect_err = true;
74 FALLTHROUGH;
75 case STDERR_FILENO:
76 if (dup2 (STDOUT_FILENO, STDOUT_FILENO) != STDOUT_FILENO)
77 protect_out = true;
78 FALLTHROUGH;
79 case STDOUT_FILENO:
80 if (dup2 (STDIN_FILENO, STDIN_FILENO) != STDIN_FILENO)
81 protect_in = true;
82 FALLTHROUGH;
83 case STDIN_FILENO:
84
85 break;
86 }
87 if (protect_in && !protect_fd (STDIN_FILENO))
88 f = NULL;
89 else if (protect_out && !protect_fd (STDOUT_FILENO))
90 f = NULL;
91 else if (protect_err && !protect_fd (STDERR_FILENO))
92 f = NULL;
93 else
94 f = freopen (name, mode, f);
95 saved_errno = errno;
96 if (protect_err)
97 close (STDERR_FILENO);
98 if (protect_out)
99 close (STDOUT_FILENO);
100 if (protect_in)
101 close (STDIN_FILENO);
102 if (!f)
103 errno = saved_errno;
104 return f;
105 }