1 #include <sys/types.h> 2 #include <sys/wait.h> 3 #include <sys/syslimits.h> 4 #include <errno.h> 5 #include <fcntl.h> 6 #include <signal.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 11 int max_error = 5; 12 #include "common.h" 13 14 15 void copy_subtests(void); 16 void test_pipe_cloexec(void); 17 void test_pipe_flag_setting(void); 18 void test_pipe_nonblock(void); 19 void test_pipe_normal(void); 20 void test_pipe_nosigpipe(void); 21 void alarm_handler(int sig); 22 void pipe_handler(int sig); 23 24 static int seen_pipe_signal = 0; 25 static int seen_alarm_signal = 0; 26 27 void 28 alarm_handler(int sig) 29 { 30 if (seen_pipe_signal == 0) 31 seen_pipe_signal = -1; 32 seen_alarm_signal = 1; 33 } 34 35 void 36 pipe_handler(int sig) 37 { 38 seen_pipe_signal = 1; 39 } 40 41 void 42 copy_subtests() 43 { 44 char *subtests[] = { "t68a", "t68b" }; 45 char copy_cmd[8 + PATH_MAX + 1]; 46 int i, no_tests; 47 48 no_tests = sizeof(subtests) / sizeof(char *); 49 50 for (i = 0; i < no_tests; i++) { 51 snprintf(copy_cmd, 8 + PATH_MAX, "cp ../%s .", subtests[i]); 52 system(copy_cmd); 53 } 54 } 55 56 void 57 test_pipe_normal() 58 { 59 /* Verify pipe2 creates pipes that behave like a normal pipe */ 60 61 int pipes[2]; 62 char buf_in[1], buf_out[1]; 63 pid_t pid; 64 65 subtest = 2; 66 67 if (pipe2(pipes, 0) != 0) e(1); 68 69 buf_out[0] = 'T'; 70 if (write(pipes[1], buf_out, sizeof(buf_out)) != sizeof(buf_out)) e(2); 71 if (read(pipes[0], buf_in, sizeof(buf_in)) != sizeof(buf_in)) e(3); 72 if (buf_out[0] != buf_in[0]) e(4); 73 74 /* When we close the write end, reading should fail */ 75 if (close(pipes[1]) != 0) e(5); 76 if (read(pipes[0], buf_in, sizeof(buf_in)) != 0) e(6); 77 78 /* Let's retry that experiment the other way around. Install a signal 79 * handler to catch SIGPIPE. Install an alarm handler to make sure 80 * this test finishes in finite time. */ 81 if (pipe2(pipes, 0) != 0) e(7); 82 signal(SIGPIPE, pipe_handler); 83 signal(SIGALRM, alarm_handler); 84 seen_pipe_signal = 0; 85 seen_alarm_signal = 0; 86 alarm(1); 87 if (close(pipes[0]) != 0) e(8); 88 if (write(pipes[1], buf_out, sizeof(buf_out)) != -1) e(9); 89 while (seen_pipe_signal == 0) 90 ; 91 if (seen_pipe_signal != 1) e(10); 92 if (close(pipes[1]) != 0) e(11); 93 94 /* Collect alarm signal */ 95 while (seen_alarm_signal == 0) 96 ; 97 98 if (pipe2(pipes, 0) != 0) e(12); 99 100 /* Now fork and verify we can write to the pipe */ 101 pid = fork(); 102 if (pid < 0) e(13); 103 if (pid == 0) { 104 /* We're the child */ 105 char fd_buf[2]; 106 107 /* Verify we can still write a byte into the pipe */ 108 if (write(pipes[1], buf_out, sizeof(buf_out)) != 1) e(14); 109 110 snprintf(fd_buf, sizeof(fd_buf), "%d", pipes[1]); 111 execl("./t68a", "t68a", fd_buf, NULL); 112 113 exit(1); /* Should not be reached */ 114 } else { 115 /* We're the parent */ 116 int result; 117 118 if (waitpid(pid, &result, 0) == -1) e(15); 119 if (WEXITSTATUS(result) != 0) e(16); 120 } 121 122 if (close(pipes[0]) != 0) e(17); 123 if (close(pipes[1]) != 0) e(18); 124 } 125 126 void 127 test_pipe_cloexec() 128 { 129 /* Open a pipe with O_CLOEXEC */ 130 int flags; 131 int pipes[2]; 132 pid_t pid; 133 char buf_in[1], buf_out[1]; 134 135 subtest = 3; 136 137 if (pipe2(pipes, O_CLOEXEC) != 0) e(1); 138 139 /* Verify O_CLOEXEC flag is set */ 140 flags = fcntl(pipes[0], F_GETFD); 141 if (flags < 0) e(2); 142 if (!(flags & FD_CLOEXEC)) e(3); 143 144 pid = fork(); 145 if (pid < 0) e(4); 146 if (pid == 0) { 147 /* We're the child */ 148 char fd_buf[2]; 149 150 /* Verify we can still write a byte into the pipe */ 151 buf_in[0] = 0; 152 buf_out[0] = 'T'; 153 if (write(pipes[1], buf_out, sizeof(buf_out)) != 1) e(5); 154 if (read(pipes[0], buf_in, sizeof(buf_in)) != 1) e(6); 155 if (buf_out[0] != buf_in[0]) e(7); 156 157 /* Verify FD_CLOEXEC flag is still set */ 158 flags = fcntl(pipes[0], F_GETFD); 159 if (flags < 0) e(8); 160 if (!(flags & FD_CLOEXEC)) e(9); 161 162 snprintf(fd_buf, sizeof(fd_buf), "%d", pipes[0]); 163 execl("./t68b", "t68b", fd_buf, NULL); 164 165 exit(1); /* Should not be reached */ 166 } else { 167 /* We're the parent */ 168 int result; 169 170 if (waitpid(pid, &result, 0) == -1) e(10); 171 if (WEXITSTATUS(result) != 0) e(11); 172 } 173 174 /* Eventhough our child's pipe should've been closed upon exec, our 175 * pipe should still be functioning. 176 */ 177 buf_in[0] = 0; 178 buf_out[0] = 't'; 179 if (write(pipes[1], buf_out, sizeof(buf_out)) != sizeof(buf_out)) e(12); 180 if (read(pipes[0], buf_in, sizeof(buf_in)) != sizeof(buf_in)) e(13); 181 if (buf_out[0] != buf_in[0]) e(14); 182 183 if (close(pipes[0]) != 0) e(15); 184 if (close(pipes[1]) != 0) e(16); 185 } 186 187 void 188 test_pipe_nonblock() 189 { 190 /* Open a pipe with O_NONBLOCK */ 191 char *buf_in, *buf_out; 192 int pipes[2]; 193 size_t pipe_size; 194 195 subtest = 4; 196 197 if (pipe2(pipes, O_NONBLOCK) != 0) e(1); 198 if ((pipe_size = fpathconf(pipes[0], _PC_PIPE_BUF)) == -1) e(2); 199 buf_in = calloc(2, pipe_size); /* Allocate twice the buffer size */ 200 if (buf_in == NULL) e(3); 201 buf_out = calloc(2, pipe_size); /* Idem dito for output buffer */ 202 if (buf_out == NULL) e(4); 203 204 /* According to POSIX, a pipe with O_NONBLOCK set shall never block. 205 * When we attempt to write PIPE_BUF or less bytes, and there is 206 * sufficient space available, write returns nbytes. Else write will 207 * return -1 and not transfer any data. 208 */ 209 if (write(pipes[1], buf_out, 1) != 1) e(5); /* Write 1 byte */ 210 if (write(pipes[1], buf_out, pipe_size) != -1) e(6); /* Can't fit */ 211 if (errno != EAGAIN) e(7); 212 213 /* When writing more than PIPE_BUF bytes and when at least 1 byte can 214 * be tranferred, return the number of bytes written. We've written 1 215 * byte, so there are PIPE_BUF - 1 bytes left. */ 216 if (write(pipes[1], buf_out, pipe_size + 1) != pipe_size - 1) e(8); 217 218 /* Read out all data and try again. This time we should be able to 219 * write PIPE_BUF bytes. */ 220 if (read(pipes[0], buf_in, pipe_size) != pipe_size) e(9); 221 if (read(pipes[0], buf_in, 1) != -1) e(10); /* Empty, can't read */ 222 if (errno != EAGAIN) e(11); 223 if (write(pipes[1], buf_out, pipe_size + 1) != pipe_size) e(12); 224 if (close(pipes[0]) != 0) e(13); 225 if (close(pipes[1]) != 0) e(14); 226 free(buf_in); 227 free(buf_out); 228 } 229 230 void 231 test_pipe_nosigpipe(void) 232 { 233 /* Let's retry the writing to pipe without readers experiment. This time we set 234 * the O_NOSIGPIPE flag to prevent getting a signal. */ 235 int pipes[2]; 236 char buf_out[1]; 237 238 subtest = 5; 239 240 if (pipe2(pipes, O_NOSIGPIPE) != 0) e(7); 241 signal(SIGPIPE, pipe_handler); 242 signal(SIGALRM, alarm_handler); 243 seen_pipe_signal = 0; 244 seen_alarm_signal = 0; 245 alarm(1); 246 if (close(pipes[0]) != 0) e(8); 247 if (write(pipes[1], buf_out, sizeof(buf_out)) != -1) e(9); 248 249 /* Collect alarm signal */ 250 while (seen_alarm_signal == 0) 251 ; 252 if (errno != EPIPE) e(10); 253 if (seen_pipe_signal != -1) e(11); /* Alarm sig handler set it to -1 */ 254 if (close(pipes[1]) != 0) e(12); 255 } 256 257 void 258 test_pipe_flag_setting() 259 { 260 int pipes[2]; 261 262 subtest = 1; 263 264 /* Create standard pipe with no flags and verify they're off */ 265 if (pipe2(pipes, 0) != 0) e(1); 266 if (fcntl(pipes[0], F_GETFD) != 0) e(2); 267 if (fcntl(pipes[1], F_GETFD) != 0) e(3); 268 if (fcntl(pipes[0], F_GETFL) & O_NONBLOCK) e(4); 269 if (fcntl(pipes[1], F_GETFL) & O_NONBLOCK) e(5); 270 if (fcntl(pipes[0], F_GETNOSIGPIPE) != -1) e(6); 271 if (fcntl(pipes[1], F_GETNOSIGPIPE) != -1) e(7); 272 if (close(pipes[0]) != 0) e(8); 273 if (close(pipes[1]) != 0) e(9); 274 275 /* Create pipe with all flags and verify they're on */ 276 if (pipe2(pipes, O_CLOEXEC|O_NONBLOCK|O_NOSIGPIPE) != 0) e(10); 277 if (fcntl(pipes[0], F_GETFD) != FD_CLOEXEC) e(11); 278 if (fcntl(pipes[1], F_GETFD) != FD_CLOEXEC) e(12); 279 if (!(fcntl(pipes[0], F_GETFL) & O_NONBLOCK)) e(13); 280 if (!(fcntl(pipes[1], F_GETFL) & O_NONBLOCK)) e(14); 281 if (fcntl(pipes[0], F_GETNOSIGPIPE) == -1) e(15); 282 if (fcntl(pipes[1], F_GETNOSIGPIPE) == -1) e(16); 283 if (close(pipes[0]) != 0) e(17); 284 if (close(pipes[1]) != 0) e(18); 285 } 286 287 int 288 main(int argc, char *argv[]) 289 { 290 start(68); 291 copy_subtests(); 292 test_pipe_flag_setting(); 293 test_pipe_normal(); 294 test_pipe_cloexec(); 295 test_pipe_nonblock(); 296 test_pipe_nosigpipe(); 297 quit(); 298 return(-1); /* Unreachable */ 299 } 300 301