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