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