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