1133105Srwatson/*-
2133105Srwatson * Copyright (c) 2004 Robert N. M. Watson
3133105Srwatson * All rights reserved.
4133105Srwatson *
5133105Srwatson * Redistribution and use in source and binary forms, with or without
6133105Srwatson * modification, are permitted provided that the following conditions
7133105Srwatson * are met:
8133105Srwatson * 1. Redistributions of source code must retain the above copyright
9133105Srwatson *    notice, this list of conditions and the following disclaimer.
10133105Srwatson * 2. Redistributions in binary form must reproduce the above copyright
11133105Srwatson *    notice, this list of conditions and the following disclaimer in the
12133105Srwatson *    documentation and/or other materials provided with the distribution.
13133105Srwatson *
14133105Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15133105Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16133105Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17133105Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18133105Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19133105Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20133105Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21133105Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22133105Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23133105Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24133105Srwatson * SUCH DAMAGE.
25133105Srwatson *
26133105Srwatson * $FreeBSD$
27133105Srwatson */
28133105Srwatson
29133105Srwatson#include <sys/types.h>
30133105Srwatson#include <sys/socket.h>
31133105Srwatson
32133105Srwatson#include <errno.h>
33133105Srwatson#include <stdio.h>
34133105Srwatson#include <stdlib.h>
35133105Srwatson#include <string.h>
36133105Srwatson#include <unistd.h>
37133105Srwatson
38133105Srwatson/*
39133105Srwatson * Open, then close a set of UNIX domain socket pairs for datagram and
40133105Srwatson * stream.
41133105Srwatson *
42133105Srwatson * Confirm that we can't open INET datagram or stream socket pairs.
43133105Srwatson *
44133105Srwatson * More tests should be added, including confirming that sending on either
45133105Srwatson * endpoint results in data at the other, that the right kind of socket was
46133105Srwatson * created (stream vs. datagram), and that message boundaries fall in the
47133105Srwatson * right places.
48133105Srwatson */
49133105Srwatsonint
50281974Sngiemain(void)
51133105Srwatson{
52168278Sjhb	int fd1, fd2, fd3;
53133105Srwatson	int sv[2];
54133105Srwatson
55133105Srwatson	/*
56133105Srwatson	 * UNIX domain socket pair, datagram.
57133105Srwatson	 */
58133105Srwatson	if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) != 0) {
59133105Srwatson		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM): %s\n",
60133105Srwatson		    strerror(errno));
61133105Srwatson		fprintf(stderr, "FAIL\n");
62133105Srwatson		exit(-1);
63133105Srwatson	}
64133105Srwatson	if (close(sv[0]) != 0) {
65133105Srwatson		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM) close 0: %s\n",
66133105Srwatson		    strerror(errno));
67133105Srwatson		fprintf(stderr, "FAIL\n");
68133105Srwatson		exit(-1);
69133105Srwatson	}
70133105Srwatson	if (close(sv[1]) != 0) {
71133105Srwatson		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM) close 1: %s\n",
72133105Srwatson		    strerror(errno));
73133105Srwatson		fprintf(stderr, "FAIL\n");
74133105Srwatson		exit(-1);
75133105Srwatson	}
76133105Srwatson
77133105Srwatson	/*
78133105Srwatson	 * UNIX domain socket pair, stream.
79133105Srwatson	 */
80133105Srwatson	if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) != 0) {
81133105Srwatson		fprintf(stderr, "socketpair(PF_UNIX, SOCK_STREAM): %s\n",
82133105Srwatson		    strerror(errno));
83133105Srwatson		fprintf(stderr, "FAIL\n");
84133105Srwatson		exit(-1);
85133105Srwatson	}
86133105Srwatson	if (close(sv[0]) != 0) {
87133105Srwatson		fprintf(stderr, "socketpair(PF_UNIX, SOCK_STREAM) close 0: %s\n",
88133105Srwatson		    strerror(errno));
89133105Srwatson		fprintf(stderr, "FAIL\n");
90133105Srwatson		exit(-1);
91133105Srwatson	}
92133105Srwatson	if (close(sv[1]) != 0) {
93133105Srwatson		fprintf(stderr, "socketpair(PF_UNIX, SOCK_STREAM) close 1: "
94133105Srwatson		    "%s\n", strerror(errno));
95133105Srwatson		fprintf(stderr, "FAIL\n");
96133105Srwatson		exit(-1);
97133105Srwatson	}
98133105Srwatson
99133105Srwatson	/*
100133105Srwatson	 * Confirm that PF_INET datagram socket pair creation fails.
101133105Srwatson	 */
102133105Srwatson	if (socketpair(PF_INET, SOCK_DGRAM, 0, sv) == 0) {
103133105Srwatson		fprintf(stderr, "socketpair(PF_INET, SOCK_DGRAM): opened\n");
104133105Srwatson		fprintf(stderr, "FAIL\n");
105133105Srwatson		exit(-1);
106133105Srwatson	}
107133105Srwatson	if (errno != EOPNOTSUPP) {
108133105Srwatson		fprintf(stderr, "socketpair(PF_INET, SOCK_DGRAM): %s\n",
109133105Srwatson		    strerror(errno));
110133105Srwatson		fprintf(stderr, "FAIL\n");
111133105Srwatson	}
112133105Srwatson
113133105Srwatson	/*
114133105Srwatson	 * Confirm that PF_INET stream socket pair creation fails.
115133105Srwatson	 */
116133105Srwatson	if (socketpair(PF_INET, SOCK_STREAM, 0, sv) == 0) {
117133105Srwatson		fprintf(stderr, "socketpair(PF_INET, SOCK_STREAM): opened\n");
118133105Srwatson		fprintf(stderr, "FAIL\n");
119133105Srwatson		exit(-1);
120133105Srwatson	}
121133105Srwatson	if (errno != EOPNOTSUPP) {
122133105Srwatson		fprintf(stderr, "socketpair(PF_INET, SOCK_STREAM): %s\n",
123133105Srwatson		    strerror(errno));
124133105Srwatson		fprintf(stderr, "FAIL\n");
125133105Srwatson	}
126133105Srwatson
127168278Sjhb	/*
128168278Sjhb	 * Check for sequential fd allocation, and give up early if not.
129168278Sjhb	 */
130168278Sjhb	fd1 = dup(STDIN_FILENO);
131168278Sjhb	fd2 = dup(STDIN_FILENO);
132168278Sjhb	if (fd2 != fd1 + 1) {
133168278Sjhb		fprintf(stderr, "Non-sequential fd allocation\n");
134168278Sjhb		fprintf(stderr, "FAIL\n");
135168278Sjhb		exit(-1);
136168278Sjhb	}
137168278Sjhb
138168278Sjhb	/* Allocate a socketpair using a bad destination address. */
139168278Sjhb	if (socketpair(PF_UNIX, SOCK_DGRAM, 0, NULL) == 0) {
140168278Sjhb		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM, NULL): opened\n");
141168278Sjhb		fprintf(stderr, "FAIL\n");
142168278Sjhb		exit(-1);
143168278Sjhb	}
144168278Sjhb	if (errno != EFAULT) {
145168278Sjhb		fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM, NULL): %s\n",
146168278Sjhb		    strerror(errno));
147168278Sjhb		fprintf(stderr, "FAIL\n");
148168278Sjhb		exit(-1);
149168278Sjhb	}
150168278Sjhb
151168278Sjhb	/* Allocate a file descriptor and make sure it's fd2+1. */
152168278Sjhb	fd3 = dup(STDIN_FILENO);
153168278Sjhb	if (fd3 != fd2 + 1) {
154168278Sjhb		fprintf(stderr, "socketpair(..., NULL) allocated descriptors\n");
155168278Sjhb		fprintf(stderr, "FAIL\n");
156168278Sjhb		exit(-1);
157168278Sjhb	}
158168278Sjhb
159133105Srwatson	fprintf(stderr, "PASS\n");
160133105Srwatson	exit(0);
161133105Srwatson}
162