1 /* $OpenBSD: stdfiles.c,v 1.4 2016/09/01 10:56:45 deraadt Exp $ */
2 /* PUBLIC DOMAIN Oct 2002 Marco S Hyman <marc@snafu.org> */
3
4 #include <assert.h>
5 #include <fcntl.h>
6 #include <stdio.h>
7 #include <unistd.h>
8
9 /*
10 * test what happens to blocking/non-blocking mode on stdout/stderr when
11 * it is changed on stdin. A comment in the pthreads code implies that
12 * all three files are linked. Check it out.
13 */
14
15 int
main(int argc,char * argv[])16 main(int argc, char *argv[])
17 {
18 int dup_stdout;
19 int stdin_flags;
20 int stdout_flags;
21 int dup_flags;
22 int stderr_flags;
23 int new_flags;
24 int new_fd;
25
26 /* dup stdout for the fun of it. */
27 dup_stdout = dup(STDOUT_FILENO);
28
29 /* read std in/out/err flags */
30 stdin_flags = fcntl(STDIN_FILENO, F_GETFL);
31 assert(stdin_flags != -1);
32 stdout_flags = fcntl(STDOUT_FILENO, F_GETFL);
33 assert(stdout_flags != -1);
34 dup_flags = fcntl(dup_stdout, F_GETFL);
35 assert(dup_flags != -1);
36 stderr_flags = fcntl(STDERR_FILENO, F_GETFL);
37 assert(stderr_flags != -1);
38 printf("starting flags: in = %x, out = %x, dup = %x, err = %x\n",
39 stdin_flags, stdout_flags, dup_flags, stderr_flags);
40
41 /* set stdin to non-blocking mode and see if stdout/stderr change */
42 new_flags = stdin_flags | O_NONBLOCK;
43 printf("forcing stdin to O_NONBLOCK (flags %x)\n", new_flags);
44 assert(fcntl(STDIN_FILENO, F_SETFL, new_flags) != -1);
45
46 new_flags = fcntl(STDIN_FILENO, F_GETFL);
47 assert(new_flags != -1);
48 if (new_flags != stdin_flags) {
49 printf("stdin flags changed %x -> %x\n", stdin_flags,
50 new_flags);
51 stdin_flags = new_flags;
52 }
53
54 new_flags = fcntl(STDOUT_FILENO, F_GETFL);
55 assert(new_flags != -1);
56 if (new_flags != stdout_flags) {
57 printf("stdout flags changed %x -> %x\n", stdout_flags,
58 new_flags);
59 stdout_flags = new_flags;
60 }
61
62 new_flags = fcntl(dup_stdout, F_GETFL);
63 assert(new_flags != -1);
64 if (new_flags != dup_flags) {
65 printf("dup_stdout flags changed %x -> %x\n", dup_flags,
66 new_flags);
67 dup_flags = new_flags;
68 }
69
70 new_flags = fcntl(STDERR_FILENO, F_GETFL);
71 assert(new_flags != -1);
72 if (new_flags != stderr_flags) {
73 printf("stderr flags changed %x -> %x\n", stderr_flags,
74 new_flags);
75 stderr_flags = new_flags;
76 }
77
78 /*
79 * Close stderr and open /dev/tty. See what it's flags
80 * are. Set the file to non blocking.
81 */
82 printf("close stderr and open /dev/tty\n");
83 assert(close(STDERR_FILENO) != -1);
84 new_fd = open("/dev/tty", O_RDWR|O_CREAT, 0666);
85 assert(new_fd == STDERR_FILENO);
86 new_flags = fcntl(STDERR_FILENO, F_GETFL);
87 assert(new_flags != -1);
88 printf("/dev/tty [STDERR_FILENO] flags are %x\n", new_flags);
89 stderr_flags = new_flags | O_NONBLOCK;
90 printf("forcing /dev/tty to O_NONBLOCK (flags %x)\n", stderr_flags);
91 assert(fcntl(STDERR_FILENO, F_SETFL, stdin_flags) != -1);
92
93 /* now turn off non blocking mode on stdin */
94 stdin_flags &= ~O_NONBLOCK;
95 printf("turning off O_NONBLOCK on stdin (flags %x)\n", stdin_flags);
96 assert(fcntl(STDIN_FILENO, F_SETFL, stdin_flags) != -1);
97
98 new_flags = fcntl(STDIN_FILENO, F_GETFL);
99 assert(new_flags != -1);
100 assert(new_flags == stdin_flags);
101
102 new_flags = fcntl(STDOUT_FILENO, F_GETFL);
103 assert(new_flags != -1);
104 if (new_flags != stdout_flags) {
105 printf("stdout flags changed %x -> %x\n", stdout_flags,
106 new_flags);
107 stdout_flags = new_flags;
108 }
109
110 new_flags = fcntl(dup_stdout, F_GETFL);
111 assert(new_flags != -1);
112 if (new_flags != dup_flags) {
113 printf("dup_stdout flags changed %x -> %x\n", dup_flags,
114 new_flags);
115 dup_flags = new_flags;
116 }
117
118 new_flags = fcntl(STDERR_FILENO, F_GETFL);
119 assert(new_flags != -1);
120 if (new_flags != stderr_flags) {
121 printf("stderr flags changed %x -> %x\n", stderr_flags,
122 new_flags);
123 stderr_flags = new_flags;
124 }
125
126 return 0;
127 }
128