1 /* 2 * Copyright (c) Ulrich Drepper <drepper (at) redhat.com> 3 * Copyright (c) International Business Machines Corp., 2009 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. 17 */ 18 19 /* 20 * Test Name: socketpair02 21 * 22 * Description: 23 * This Program tests the new flag SOCK_CLOEXEC and SOCK_NONBLOCK introduced 24 * in socketpair() in kernel 2.6.27. 25 */ 26 27 #include <errno.h> 28 #include <fcntl.h> 29 #include <pthread.h> 30 #include <stdio.h> 31 #include <unistd.h> 32 #include <netinet/in.h> 33 #include <sys/socket.h> 34 #include <sys/syscall.h> 35 #include "lapi/fcntl.h" 36 #include "tst_test.h" 37 38 static int fds[2]; 39 40 static struct tcase { 41 int type; 42 int flag; 43 int fl_flag; 44 char *des; 45 } tcases[] = { 46 {SOCK_STREAM, 0, F_GETFD, "no close-on-exec"}, 47 {SOCK_STREAM | SOCK_CLOEXEC, FD_CLOEXEC, F_GETFD, "close-on-exec"}, 48 {SOCK_STREAM, 0, F_GETFL, "no non-blocking"}, 49 {SOCK_STREAM | SOCK_NONBLOCK, O_NONBLOCK, F_GETFL, "non-blocking"} 50 }; 51 52 static void verify_socketpair(unsigned int n) 53 { 54 int res, i; 55 struct tcase *tc = &tcases[n]; 56 57 TEST(socketpair(PF_UNIX, tc->type, 0, fds)); 58 59 if (TST_RET == -1) 60 tst_brk(TFAIL | TTERRNO, "socketpair() failed"); 61 62 for (i = 0; i < 2; i++) { 63 res = SAFE_FCNTL(fds[i], tc->fl_flag); 64 65 if (tc->flag != 0 && (res & tc->flag) == 0) { 66 tst_res(TFAIL, "socketpair() failed to set %s flag for fds[%d]", 67 tc->des, i); 68 goto ret; 69 } 70 71 if (tc->flag == 0 && (res & tc->flag) != 0) { 72 tst_res(TFAIL, "socketpair() failed to set %s flag for fds[%d]", 73 tc->des, i); 74 goto ret; 75 } 76 } 77 78 tst_res(TPASS, "socketpair() passed to set %s flag", tc->des); 79 80 ret: 81 SAFE_CLOSE(fds[0]); 82 SAFE_CLOSE(fds[1]); 83 } 84 85 static void cleanup(void) 86 { 87 if (fds[0] > 0) 88 SAFE_CLOSE(fds[0]); 89 90 if (fds[1] > 0) 91 SAFE_CLOSE(fds[1]); 92 } 93 94 static struct tst_test test = { 95 .tcnt = ARRAY_SIZE(tcases), 96 .test = verify_socketpair, 97 .min_kver = "2.6.27", 98 .cleanup = cleanup 99 }; 100