Home | History | Annotate | Download | only in socketpair
      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