socketpair.c revision 281974
1/*-
2 * Copyright (c) 2004 Robert N. M. Watson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: stable/10/tools/regression/sockets/socketpair/socketpair.c 281974 2015-04-25 05:31:52Z ngie $
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31
32#include <errno.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>
37
38/*
39 * Open, then close a set of UNIX domain socket pairs for datagram and
40 * stream.
41 *
42 * Confirm that we can't open INET datagram or stream socket pairs.
43 *
44 * More tests should be added, including confirming that sending on either
45 * endpoint results in data at the other, that the right kind of socket was
46 * created (stream vs. datagram), and that message boundaries fall in the
47 * right places.
48 */
49int
50main(void)
51{
52	int fd1, fd2, fd3;
53	int sv[2];
54
55	/*
56	 * UNIX domain socket pair, datagram.
57	 */
58	if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) != 0) {
59		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM): %s\n",
60		    strerror(errno));
61		fprintf(stderr, "FAIL\n");
62		exit(-1);
63	}
64	if (close(sv[0]) != 0) {
65		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM) close 0: %s\n",
66		    strerror(errno));
67		fprintf(stderr, "FAIL\n");
68		exit(-1);
69	}
70	if (close(sv[1]) != 0) {
71		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM) close 1: %s\n",
72		    strerror(errno));
73		fprintf(stderr, "FAIL\n");
74		exit(-1);
75	}
76
77	/*
78	 * UNIX domain socket pair, stream.
79	 */
80	if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) != 0) {
81		fprintf(stderr, "socketpair(PF_UNIX, SOCK_STREAM): %s\n",
82		    strerror(errno));
83		fprintf(stderr, "FAIL\n");
84		exit(-1);
85	}
86	if (close(sv[0]) != 0) {
87		fprintf(stderr, "socketpair(PF_UNIX, SOCK_STREAM) close 0: %s\n",
88		    strerror(errno));
89		fprintf(stderr, "FAIL\n");
90		exit(-1);
91	}
92	if (close(sv[1]) != 0) {
93		fprintf(stderr, "socketpair(PF_UNIX, SOCK_STREAM) close 1: "
94		    "%s\n", strerror(errno));
95		fprintf(stderr, "FAIL\n");
96		exit(-1);
97	}
98
99	/*
100	 * Confirm that PF_INET datagram socket pair creation fails.
101	 */
102	if (socketpair(PF_INET, SOCK_DGRAM, 0, sv) == 0) {
103		fprintf(stderr, "socketpair(PF_INET, SOCK_DGRAM): opened\n");
104		fprintf(stderr, "FAIL\n");
105		exit(-1);
106	}
107	if (errno != EOPNOTSUPP) {
108		fprintf(stderr, "socketpair(PF_INET, SOCK_DGRAM): %s\n",
109		    strerror(errno));
110		fprintf(stderr, "FAIL\n");
111	}
112
113	/*
114	 * Confirm that PF_INET stream socket pair creation fails.
115	 */
116	if (socketpair(PF_INET, SOCK_STREAM, 0, sv) == 0) {
117		fprintf(stderr, "socketpair(PF_INET, SOCK_STREAM): opened\n");
118		fprintf(stderr, "FAIL\n");
119		exit(-1);
120	}
121	if (errno != EOPNOTSUPP) {
122		fprintf(stderr, "socketpair(PF_INET, SOCK_STREAM): %s\n",
123		    strerror(errno));
124		fprintf(stderr, "FAIL\n");
125	}
126
127	/*
128	 * Check for sequential fd allocation, and give up early if not.
129	 */
130	fd1 = dup(STDIN_FILENO);
131	fd2 = dup(STDIN_FILENO);
132	if (fd2 != fd1 + 1) {
133		fprintf(stderr, "Non-sequential fd allocation\n");
134		fprintf(stderr, "FAIL\n");
135		exit(-1);
136	}
137
138	/* Allocate a socketpair using a bad destination address. */
139	if (socketpair(PF_UNIX, SOCK_DGRAM, 0, NULL) == 0) {
140		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM, NULL): opened\n");
141		fprintf(stderr, "FAIL\n");
142		exit(-1);
143	}
144	if (errno != EFAULT) {
145		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM, NULL): %s\n",
146		    strerror(errno));
147		fprintf(stderr, "FAIL\n");
148		exit(-1);
149	}
150
151	/* Allocate a file descriptor and make sure it's fd2+1. */
152	fd3 = dup(STDIN_FILENO);
153	if (fd3 != fd2 + 1) {
154		fprintf(stderr, "socketpair(..., NULL) allocated descriptors\n");
155		fprintf(stderr, "FAIL\n");
156		exit(-1);
157	}
158
159	fprintf(stderr, "PASS\n");
160	exit(0);
161}
162