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 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