xref: /illumos-gate/usr/src/test/os-tests/tests/sockfs/rights.c (revision d865fc92e4b640c73c2957a20b3d82622c741be5)
1*d865fc92SAndy Fiddaman /*
2*d865fc92SAndy Fiddaman  * This file and its contents are supplied under the terms of the
3*d865fc92SAndy Fiddaman  * Common Development and Distribution License ("CDDL"), version 1.0.
4*d865fc92SAndy Fiddaman  * You may only use this file in accordance with the terms of version
5*d865fc92SAndy Fiddaman  * 1.0 of the CDDL.
6*d865fc92SAndy Fiddaman  *
7*d865fc92SAndy Fiddaman  * A full copy of the text of the CDDL should have accompanied this
8*d865fc92SAndy Fiddaman  * source.  A copy of the CDDL is also available via the Internet at
9*d865fc92SAndy Fiddaman  * http://www.illumos.org/license/CDDL.
10*d865fc92SAndy Fiddaman  */
11*d865fc92SAndy Fiddaman 
12*d865fc92SAndy Fiddaman /*
13*d865fc92SAndy Fiddaman  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
14*d865fc92SAndy Fiddaman  */
15*d865fc92SAndy Fiddaman 
16*d865fc92SAndy Fiddaman /*
17*d865fc92SAndy Fiddaman  * Test file descriptor passing via SCM_RIGHTS, and in particular what happens
18*d865fc92SAndy Fiddaman  * on message truncation in terms of the represented size of the data in the
19*d865fc92SAndy Fiddaman  * control message. Ensure that no file descriptors are leaked - the kernel
20*d865fc92SAndy Fiddaman  * must close any that would not fit in the available buffer space and the
21*d865fc92SAndy Fiddaman  * userland application must close the rest.
22*d865fc92SAndy Fiddaman  */
23*d865fc92SAndy Fiddaman 
24*d865fc92SAndy Fiddaman #include <stdio.h>
25*d865fc92SAndy Fiddaman #include <errno.h>
26*d865fc92SAndy Fiddaman #include <fcntl.h>
27*d865fc92SAndy Fiddaman #include <signal.h>
28*d865fc92SAndy Fiddaman #include <stdlib.h>
29*d865fc92SAndy Fiddaman #include <string.h>
30*d865fc92SAndy Fiddaman #include <strings.h>
31*d865fc92SAndy Fiddaman #include <unistd.h>
32*d865fc92SAndy Fiddaman #include <libproc.h>
33*d865fc92SAndy Fiddaman 
34*d865fc92SAndy Fiddaman #include <sys/types.h>
35*d865fc92SAndy Fiddaman #include <sys/param.h>
36*d865fc92SAndy Fiddaman #include <sys/socket.h>
37*d865fc92SAndy Fiddaman #include <sys/stat.h>
38*d865fc92SAndy Fiddaman #include <sys/un.h>
39*d865fc92SAndy Fiddaman #include <sys/wait.h>
40*d865fc92SAndy Fiddaman #include <assert.h>
41*d865fc92SAndy Fiddaman #include <alloca.h>
42*d865fc92SAndy Fiddaman #include <err.h>
43*d865fc92SAndy Fiddaman 
44*d865fc92SAndy Fiddaman static boolean_t debug;
45*d865fc92SAndy Fiddaman 
46*d865fc92SAndy Fiddaman typedef struct cmsg_test {
47*d865fc92SAndy Fiddaman 	char *name;		/* Name of the test */
48*d865fc92SAndy Fiddaman 	uint_t send;		/* Number of FDs to send */
49*d865fc92SAndy Fiddaman 	uint_t recv;		/* Size receive buffer for this number of FDs */
50*d865fc92SAndy Fiddaman 	size_t predata;		/* Prepend dummy cmsg of this size */
51*d865fc92SAndy Fiddaman 	int bufsize;		/* Explicitly set receive buffer size. */
52*d865fc92SAndy Fiddaman 				/* Overrides 'recv' if non-zero */
53*d865fc92SAndy Fiddaman 	uint_t x_controllen;	/* Expected received msg_controllen */
54*d865fc92SAndy Fiddaman 	uint_t x_cmsg_datalen;	/* Expected received cmsg data length */
55*d865fc92SAndy Fiddaman 	uint32_t x_flags;	/* Expected received msf_flags */
56*d865fc92SAndy Fiddaman } cmsg_test_t;
57*d865fc92SAndy Fiddaman 
58*d865fc92SAndy Fiddaman static cmsg_test_t tests[] = {
59*d865fc92SAndy Fiddaman 	{
60*d865fc92SAndy Fiddaman 		.name = "send 1, recv 1",
61*d865fc92SAndy Fiddaman 		.send = 1,
62*d865fc92SAndy Fiddaman 		.recv = 1,
63*d865fc92SAndy Fiddaman 		.predata = 0,
64*d865fc92SAndy Fiddaman 		.bufsize = 0,
65*d865fc92SAndy Fiddaman 		.x_controllen = 16,
66*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 4,
67*d865fc92SAndy Fiddaman 		.x_flags = 0,
68*d865fc92SAndy Fiddaman 	},
69*d865fc92SAndy Fiddaman 	{
70*d865fc92SAndy Fiddaman 		.name = "send 10, recv 10",
71*d865fc92SAndy Fiddaman 		.send = 10,
72*d865fc92SAndy Fiddaman 		.recv = 10,
73*d865fc92SAndy Fiddaman 		.predata = 0,
74*d865fc92SAndy Fiddaman 		.bufsize = 0,
75*d865fc92SAndy Fiddaman 		.x_controllen = 52,
76*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 40,
77*d865fc92SAndy Fiddaman 		.x_flags = 0,
78*d865fc92SAndy Fiddaman 	},
79*d865fc92SAndy Fiddaman 	{
80*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1",
81*d865fc92SAndy Fiddaman 		.send = 2,
82*d865fc92SAndy Fiddaman 		.recv = 1,
83*d865fc92SAndy Fiddaman 		.predata = 0,
84*d865fc92SAndy Fiddaman 		.bufsize = 0,
85*d865fc92SAndy Fiddaman 		.x_controllen = 16,
86*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 4,
87*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
88*d865fc92SAndy Fiddaman 	},
89*d865fc92SAndy Fiddaman 	{
90*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, buffer 5",
91*d865fc92SAndy Fiddaman 		.send = 2,
92*d865fc92SAndy Fiddaman 		.recv = 1,
93*d865fc92SAndy Fiddaman 		.predata = 0,
94*d865fc92SAndy Fiddaman 		.bufsize = sizeof (int) * 2 - 3,
95*d865fc92SAndy Fiddaman 		.x_controllen = 17,
96*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 5,
97*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
98*d865fc92SAndy Fiddaman 	},
99*d865fc92SAndy Fiddaman 	{
100*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, buffer 6",
101*d865fc92SAndy Fiddaman 		.send = 2,
102*d865fc92SAndy Fiddaman 		.recv = 1,
103*d865fc92SAndy Fiddaman 		.predata = 0,
104*d865fc92SAndy Fiddaman 		.bufsize = sizeof (int) * 2 - 2,
105*d865fc92SAndy Fiddaman 		.x_controllen = 18,
106*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 6,
107*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
108*d865fc92SAndy Fiddaman 	},
109*d865fc92SAndy Fiddaman 	{
110*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, buffer 7",
111*d865fc92SAndy Fiddaman 		.send = 2,
112*d865fc92SAndy Fiddaman 		.recv = 1,
113*d865fc92SAndy Fiddaman 		.predata = 0,
114*d865fc92SAndy Fiddaman 		.bufsize = sizeof (int) * 2 - 1,
115*d865fc92SAndy Fiddaman 		.x_controllen = 19,
116*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 7,
117*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
118*d865fc92SAndy Fiddaman 	},
119*d865fc92SAndy Fiddaman 
120*d865fc92SAndy Fiddaman 	/* Tests where there is no room allowed for data */
121*d865fc92SAndy Fiddaman 
122*d865fc92SAndy Fiddaman 	{
123*d865fc92SAndy Fiddaman 		.name = "send 2, recv 0, hdronly",
124*d865fc92SAndy Fiddaman 		.send = 2,
125*d865fc92SAndy Fiddaman 		.recv = 0,
126*d865fc92SAndy Fiddaman 		.predata = 0,
127*d865fc92SAndy Fiddaman 		.bufsize = 0,
128*d865fc92SAndy Fiddaman 		.x_controllen = 12,
129*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 0,
130*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
131*d865fc92SAndy Fiddaman 	},
132*d865fc92SAndy Fiddaman 
133*d865fc92SAndy Fiddaman 	{
134*d865fc92SAndy Fiddaman 		.name = "send 2, recv 0, hdr - 1",
135*d865fc92SAndy Fiddaman 		.send = 2,
136*d865fc92SAndy Fiddaman 		.recv = 0,
137*d865fc92SAndy Fiddaman 		.predata = 0,
138*d865fc92SAndy Fiddaman 		.bufsize = -1,
139*d865fc92SAndy Fiddaman 		.x_controllen = 11,
140*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 0,
141*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
142*d865fc92SAndy Fiddaman 	},
143*d865fc92SAndy Fiddaman 
144*d865fc92SAndy Fiddaman 	{
145*d865fc92SAndy Fiddaman 		.name = "send 2, recv 0, hdr - 5",
146*d865fc92SAndy Fiddaman 		.send = 2,
147*d865fc92SAndy Fiddaman 		.recv = 0,
148*d865fc92SAndy Fiddaman 		.predata = 0,
149*d865fc92SAndy Fiddaman 		.bufsize = -5,
150*d865fc92SAndy Fiddaman 		.x_controllen = 7,
151*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 0,
152*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
153*d865fc92SAndy Fiddaman 	},
154*d865fc92SAndy Fiddaman 
155*d865fc92SAndy Fiddaman 	/* Tests where SCM_RIGHTS is not the first message */
156*d865fc92SAndy Fiddaman 
157*d865fc92SAndy Fiddaman 	{
158*d865fc92SAndy Fiddaman 		.name = "send 1, recv 1, pre 8",
159*d865fc92SAndy Fiddaman 		.send = 1,
160*d865fc92SAndy Fiddaman 		.recv = 1,
161*d865fc92SAndy Fiddaman 		.predata = 8,
162*d865fc92SAndy Fiddaman 		.bufsize = 0,
163*d865fc92SAndy Fiddaman 		.x_controllen = 36,
164*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 4,
165*d865fc92SAndy Fiddaman 		.x_flags = 0,
166*d865fc92SAndy Fiddaman 	},
167*d865fc92SAndy Fiddaman 	{
168*d865fc92SAndy Fiddaman 		.name = "send 1, recv 1, pre 7",
169*d865fc92SAndy Fiddaman 		.send = 1,
170*d865fc92SAndy Fiddaman 		.recv = 1,
171*d865fc92SAndy Fiddaman 		.predata = 7,
172*d865fc92SAndy Fiddaman 		.bufsize = 0,
173*d865fc92SAndy Fiddaman 		.x_controllen = 35,
174*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 4,
175*d865fc92SAndy Fiddaman 		.x_flags = 0,
176*d865fc92SAndy Fiddaman 	},
177*d865fc92SAndy Fiddaman 	{
178*d865fc92SAndy Fiddaman 		.name = "send 1, recv 1, pre 6",
179*d865fc92SAndy Fiddaman 		.send = 1,
180*d865fc92SAndy Fiddaman 		.recv = 1,
181*d865fc92SAndy Fiddaman 		.predata = 6,
182*d865fc92SAndy Fiddaman 		.bufsize = 0,
183*d865fc92SAndy Fiddaman 		.x_controllen = 34,
184*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 4,
185*d865fc92SAndy Fiddaman 		.x_flags = 0,
186*d865fc92SAndy Fiddaman 	},
187*d865fc92SAndy Fiddaman 	{
188*d865fc92SAndy Fiddaman 		.name = "send 1, recv 1, pre 5",
189*d865fc92SAndy Fiddaman 		.send = 1,
190*d865fc92SAndy Fiddaman 		.recv = 1,
191*d865fc92SAndy Fiddaman 		.predata = 5,
192*d865fc92SAndy Fiddaman 		.bufsize = 0,
193*d865fc92SAndy Fiddaman 		.x_controllen = 33,
194*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 4,
195*d865fc92SAndy Fiddaman 		.x_flags = 0,
196*d865fc92SAndy Fiddaman 	},
197*d865fc92SAndy Fiddaman 
198*d865fc92SAndy Fiddaman 	{
199*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 8",
200*d865fc92SAndy Fiddaman 		.send = 2,
201*d865fc92SAndy Fiddaman 		.recv = 1,
202*d865fc92SAndy Fiddaman 		.predata = 8,
203*d865fc92SAndy Fiddaman 		.bufsize = 0,
204*d865fc92SAndy Fiddaman 		.x_controllen = 36,
205*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
206*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
207*d865fc92SAndy Fiddaman 	},
208*d865fc92SAndy Fiddaman 	{
209*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 7",
210*d865fc92SAndy Fiddaman 		.send = 2,
211*d865fc92SAndy Fiddaman 		.recv = 1,
212*d865fc92SAndy Fiddaman 		.predata = 7,
213*d865fc92SAndy Fiddaman 		.bufsize = 0,
214*d865fc92SAndy Fiddaman 		.x_controllen = 36,
215*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
216*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
217*d865fc92SAndy Fiddaman 	},
218*d865fc92SAndy Fiddaman 	{
219*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 6",
220*d865fc92SAndy Fiddaman 		.send = 2,
221*d865fc92SAndy Fiddaman 		.recv = 1,
222*d865fc92SAndy Fiddaman 		.predata = 6,
223*d865fc92SAndy Fiddaman 		.bufsize = 0,
224*d865fc92SAndy Fiddaman 		.x_controllen = 36,
225*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
226*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
227*d865fc92SAndy Fiddaman 	},
228*d865fc92SAndy Fiddaman 	{
229*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 5",
230*d865fc92SAndy Fiddaman 		.send = 2,
231*d865fc92SAndy Fiddaman 		.recv = 1,
232*d865fc92SAndy Fiddaman 		.predata = 5,
233*d865fc92SAndy Fiddaman 		.bufsize = 0,
234*d865fc92SAndy Fiddaman 		.x_controllen = 36,
235*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
236*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
237*d865fc92SAndy Fiddaman 	},
238*d865fc92SAndy Fiddaman 	{
239*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 4",
240*d865fc92SAndy Fiddaman 		.send = 2,
241*d865fc92SAndy Fiddaman 		.recv = 1,
242*d865fc92SAndy Fiddaman 		.predata = 4,
243*d865fc92SAndy Fiddaman 		.bufsize = 0,
244*d865fc92SAndy Fiddaman 		.x_controllen = 32,
245*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
246*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
247*d865fc92SAndy Fiddaman 	},
248*d865fc92SAndy Fiddaman 	{
249*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 3",
250*d865fc92SAndy Fiddaman 		.send = 2,
251*d865fc92SAndy Fiddaman 		.recv = 1,
252*d865fc92SAndy Fiddaman 		.predata = 3,
253*d865fc92SAndy Fiddaman 		.bufsize = 0,
254*d865fc92SAndy Fiddaman 		.x_controllen = 32,
255*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
256*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
257*d865fc92SAndy Fiddaman 	},
258*d865fc92SAndy Fiddaman 	{
259*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 2",
260*d865fc92SAndy Fiddaman 		.send = 2,
261*d865fc92SAndy Fiddaman 		.recv = 1,
262*d865fc92SAndy Fiddaman 		.predata = 2,
263*d865fc92SAndy Fiddaman 		.bufsize = 0,
264*d865fc92SAndy Fiddaman 		.x_controllen = 32,
265*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
266*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
267*d865fc92SAndy Fiddaman 	},
268*d865fc92SAndy Fiddaman 	{
269*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 1",
270*d865fc92SAndy Fiddaman 		.send = 2,
271*d865fc92SAndy Fiddaman 		.recv = 1,
272*d865fc92SAndy Fiddaman 		.predata = 1,
273*d865fc92SAndy Fiddaman 		.bufsize = 0,
274*d865fc92SAndy Fiddaman 		.x_controllen = 32,
275*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
276*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
277*d865fc92SAndy Fiddaman 	},
278*d865fc92SAndy Fiddaman 
279*d865fc92SAndy Fiddaman 	{
280*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 8, buffer 5",
281*d865fc92SAndy Fiddaman 		.send = 2,
282*d865fc92SAndy Fiddaman 		.recv = 1,
283*d865fc92SAndy Fiddaman 		.predata = 8,
284*d865fc92SAndy Fiddaman 		.bufsize = sizeof (int) * 2 - 3,
285*d865fc92SAndy Fiddaman 		.x_controllen = 37,
286*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
287*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
288*d865fc92SAndy Fiddaman 	},
289*d865fc92SAndy Fiddaman 	{
290*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 8, buffer 6",
291*d865fc92SAndy Fiddaman 		.send = 2,
292*d865fc92SAndy Fiddaman 		.recv = 1,
293*d865fc92SAndy Fiddaman 		.predata = 8,
294*d865fc92SAndy Fiddaman 		.bufsize = sizeof (int) * 2 - 2,
295*d865fc92SAndy Fiddaman 		.x_controllen = 38,
296*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
297*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
298*d865fc92SAndy Fiddaman 	},
299*d865fc92SAndy Fiddaman 	{
300*d865fc92SAndy Fiddaman 		.name = "send 2, recv 1, pre 8, buffer 7",
301*d865fc92SAndy Fiddaman 		.send = 2,
302*d865fc92SAndy Fiddaman 		.recv = 1,
303*d865fc92SAndy Fiddaman 		.predata = 8,
304*d865fc92SAndy Fiddaman 		.bufsize = sizeof (int) * 2 - 1,
305*d865fc92SAndy Fiddaman 		.x_controllen = 39,
306*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 8,
307*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
308*d865fc92SAndy Fiddaman 	},
309*d865fc92SAndy Fiddaman 	{
310*d865fc92SAndy Fiddaman 		.name = "send 10, recv 1, pre 8",
311*d865fc92SAndy Fiddaman 		.send = 10,
312*d865fc92SAndy Fiddaman 		.recv = 1,
313*d865fc92SAndy Fiddaman 		.predata = 8,
314*d865fc92SAndy Fiddaman 		.bufsize = 0,
315*d865fc92SAndy Fiddaman 		.x_controllen = 36,
316*d865fc92SAndy Fiddaman 		.x_cmsg_datalen = 24,
317*d865fc92SAndy Fiddaman 		.x_flags = MSG_CTRUNC,
318*d865fc92SAndy Fiddaman 	},
319*d865fc92SAndy Fiddaman 
320*d865fc92SAndy Fiddaman 	/* End of tests */
321*d865fc92SAndy Fiddaman 
322*d865fc92SAndy Fiddaman 	{
323*d865fc92SAndy Fiddaman 		.name = NULL
324*d865fc92SAndy Fiddaman 	}
325*d865fc92SAndy Fiddaman };
326*d865fc92SAndy Fiddaman 
327*d865fc92SAndy Fiddaman static int sock = -1, testfd = -1, cfd = -1;
328*d865fc92SAndy Fiddaman static int fdcount;
329*d865fc92SAndy Fiddaman 
330*d865fc92SAndy Fiddaman static int
331*d865fc92SAndy Fiddaman fdwalkcb(const prfdinfo_t *info, void *arg)
332*d865fc92SAndy Fiddaman {
333*d865fc92SAndy Fiddaman 	if (!S_ISDIR(info->pr_mode) && info->pr_fd > 2 &&
334*d865fc92SAndy Fiddaman 	    info->pr_fd != sock && info->pr_fd != testfd &&
335*d865fc92SAndy Fiddaman 	    info->pr_fd != cfd) {
336*d865fc92SAndy Fiddaman 		if (debug) {
337*d865fc92SAndy Fiddaman 			fprintf(stderr, "%s: unexpected fd: %d\n",
338*d865fc92SAndy Fiddaman 			    (char *)arg, info->pr_fd);
339*d865fc92SAndy Fiddaman 		}
340*d865fc92SAndy Fiddaman 		fdcount++;
341*d865fc92SAndy Fiddaman 	}
342*d865fc92SAndy Fiddaman 
343*d865fc92SAndy Fiddaman 	return (0);
344*d865fc92SAndy Fiddaman 
345*d865fc92SAndy Fiddaman }
346*d865fc92SAndy Fiddaman 
347*d865fc92SAndy Fiddaman static void
348*d865fc92SAndy Fiddaman check_fds(char *tag)
349*d865fc92SAndy Fiddaman {
350*d865fc92SAndy Fiddaman 	fdcount = 0;
351*d865fc92SAndy Fiddaman 	proc_fdwalk(getpid(), fdwalkcb, tag);
352*d865fc92SAndy Fiddaman }
353*d865fc92SAndy Fiddaman 
354*d865fc92SAndy Fiddaman static void
355*d865fc92SAndy Fiddaman send_and_wait(pid_t pid, sigset_t *set, int osig, int isig)
356*d865fc92SAndy Fiddaman {
357*d865fc92SAndy Fiddaman 	int sig;
358*d865fc92SAndy Fiddaman 
359*d865fc92SAndy Fiddaman 	if (osig > 0)
360*d865fc92SAndy Fiddaman 		kill(pid, osig);
361*d865fc92SAndy Fiddaman 
362*d865fc92SAndy Fiddaman 	if (isig > 0) {
363*d865fc92SAndy Fiddaman 		if (sigwait(set, &sig) != 0) {
364*d865fc92SAndy Fiddaman 			err(EXIT_FAILURE,
365*d865fc92SAndy Fiddaman 			    "sigwait failed waiting for %d", isig);
366*d865fc92SAndy Fiddaman 		}
367*d865fc92SAndy Fiddaman 		if (sig == SIGINT) {
368*d865fc92SAndy Fiddaman 			exit(1);
369*d865fc92SAndy Fiddaman 		}
370*d865fc92SAndy Fiddaman 		if (sig != isig) {
371*d865fc92SAndy Fiddaman 			err(EXIT_FAILURE,
372*d865fc92SAndy Fiddaman 			    "sigwait returned unexpected signal %d", sig);
373*d865fc92SAndy Fiddaman 		}
374*d865fc92SAndy Fiddaman 	}
375*d865fc92SAndy Fiddaman }
376*d865fc92SAndy Fiddaman 
377*d865fc92SAndy Fiddaman static void
378*d865fc92SAndy Fiddaman sendtest(cmsg_test_t *t)
379*d865fc92SAndy Fiddaman {
380*d865fc92SAndy Fiddaman 	struct msghdr msg;
381*d865fc92SAndy Fiddaman 	struct cmsghdr *cm;
382*d865fc92SAndy Fiddaman 	struct iovec iov;
383*d865fc92SAndy Fiddaman 	ssize_t nbytes;
384*d865fc92SAndy Fiddaman 	char c = '*';
385*d865fc92SAndy Fiddaman 	int i, *p;
386*d865fc92SAndy Fiddaman 
387*d865fc92SAndy Fiddaman 	bzero(&msg, sizeof (msg));
388*d865fc92SAndy Fiddaman 
389*d865fc92SAndy Fiddaman 	msg.msg_name = NULL;
390*d865fc92SAndy Fiddaman 	msg.msg_namelen = 0;
391*d865fc92SAndy Fiddaman 
392*d865fc92SAndy Fiddaman 	iov.iov_base = &c;
393*d865fc92SAndy Fiddaman 	iov.iov_len = sizeof (c);
394*d865fc92SAndy Fiddaman 	msg.msg_iov = &iov;
395*d865fc92SAndy Fiddaman 	msg.msg_iovlen = 1;
396*d865fc92SAndy Fiddaman 
397*d865fc92SAndy Fiddaman 	msg.msg_flags = 0;
398*d865fc92SAndy Fiddaman 
399*d865fc92SAndy Fiddaman 	msg.msg_controllen = CMSG_SPACE(sizeof (int) * t->send);
400*d865fc92SAndy Fiddaman 
401*d865fc92SAndy Fiddaman 	if (t->predata > 0) {
402*d865fc92SAndy Fiddaman 		/* A dummy cmsg will be inserted at the head of the data */
403*d865fc92SAndy Fiddaman 		msg.msg_controllen += CMSG_SPACE(t->predata);
404*d865fc92SAndy Fiddaman 	}
405*d865fc92SAndy Fiddaman 
406*d865fc92SAndy Fiddaman 	msg.msg_control = alloca(msg.msg_controllen);
407*d865fc92SAndy Fiddaman 	bzero(msg.msg_control, msg.msg_controllen);
408*d865fc92SAndy Fiddaman 
409*d865fc92SAndy Fiddaman 	cm = CMSG_FIRSTHDR(&msg);
410*d865fc92SAndy Fiddaman 
411*d865fc92SAndy Fiddaman 	if (t->predata > 0) {
412*d865fc92SAndy Fiddaman 		/* Insert the dummy cmsg */
413*d865fc92SAndy Fiddaman 		cm->cmsg_len = CMSG_LEN(t->predata);
414*d865fc92SAndy Fiddaman 		cm->cmsg_level = SOL_SOCKET;
415*d865fc92SAndy Fiddaman 		cm->cmsg_type = 0;
416*d865fc92SAndy Fiddaman 		cm = CMSG_NXTHDR(&msg, cm);
417*d865fc92SAndy Fiddaman 	}
418*d865fc92SAndy Fiddaman 
419*d865fc92SAndy Fiddaman 	cm->cmsg_len = CMSG_LEN(sizeof (int) * t->send);
420*d865fc92SAndy Fiddaman 	cm->cmsg_level = SOL_SOCKET;
421*d865fc92SAndy Fiddaman 	cm->cmsg_type = SCM_RIGHTS;
422*d865fc92SAndy Fiddaman 
423*d865fc92SAndy Fiddaman 	p = (int *)CMSG_DATA(cm);
424*d865fc92SAndy Fiddaman 	for (i = 0; i < t->send; i++) {
425*d865fc92SAndy Fiddaman 		int s = dup(testfd);
426*d865fc92SAndy Fiddaman 		if (s == -1)
427*d865fc92SAndy Fiddaman 			err(EXIT_FAILURE, "dup()");
428*d865fc92SAndy Fiddaman 		*p++ = s;
429*d865fc92SAndy Fiddaman 	}
430*d865fc92SAndy Fiddaman 
431*d865fc92SAndy Fiddaman 	if (debug)
432*d865fc92SAndy Fiddaman 		printf("Sending: controllen=%u\n", msg.msg_controllen);
433*d865fc92SAndy Fiddaman 
434*d865fc92SAndy Fiddaman 	nbytes = sendmsg(cfd, &msg, 0);
435*d865fc92SAndy Fiddaman 	if (nbytes == -1)
436*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "sendmsg()");
437*d865fc92SAndy Fiddaman 
438*d865fc92SAndy Fiddaman 	p = (int *)CMSG_DATA(cm);
439*d865fc92SAndy Fiddaman 	for (i = 0; i < t->send; i++)
440*d865fc92SAndy Fiddaman 		(void) close(*p++);
441*d865fc92SAndy Fiddaman }
442*d865fc92SAndy Fiddaman 
443*d865fc92SAndy Fiddaman static int
444*d865fc92SAndy Fiddaman server(const char *sockpath, pid_t pid)
445*d865fc92SAndy Fiddaman {
446*d865fc92SAndy Fiddaman 	struct sockaddr_un addr;
447*d865fc92SAndy Fiddaman 	sigset_t set;
448*d865fc92SAndy Fiddaman 	cmsg_test_t *t;
449*d865fc92SAndy Fiddaman 
450*d865fc92SAndy Fiddaman 	sigemptyset(&set);
451*d865fc92SAndy Fiddaman 	sigaddset(&set, SIGUSR2);
452*d865fc92SAndy Fiddaman 	sigaddset(&set, SIGINT);
453*d865fc92SAndy Fiddaman 
454*d865fc92SAndy Fiddaman 	sock = socket(PF_LOCAL, SOCK_STREAM, 0);
455*d865fc92SAndy Fiddaman 	if (sock == -1)
456*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "failed to create socket");
457*d865fc92SAndy Fiddaman 	addr.sun_family = AF_UNIX;
458*d865fc92SAndy Fiddaman 	strlcpy(addr.sun_path, sockpath, sizeof (addr.sun_path));
459*d865fc92SAndy Fiddaman 	if (bind(sock, (struct sockaddr *)&addr, sizeof (addr)) == -1)
460*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "bind failed");
461*d865fc92SAndy Fiddaman 	if (listen(sock, 0) == -1)
462*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "listen failed");
463*d865fc92SAndy Fiddaman 
464*d865fc92SAndy Fiddaman 	if ((testfd = open("/dev/null", O_RDONLY)) == -1)
465*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "/dev/null");
466*d865fc92SAndy Fiddaman 
467*d865fc92SAndy Fiddaman 	check_fds("server");
468*d865fc92SAndy Fiddaman 
469*d865fc92SAndy Fiddaman 	/* Signal the child to connect to the socket */
470*d865fc92SAndy Fiddaman 	send_and_wait(pid, &set, SIGUSR1, SIGUSR2);
471*d865fc92SAndy Fiddaman 
472*d865fc92SAndy Fiddaman 	if ((cfd = accept(sock, NULL, 0)) == -1)
473*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "accept failed");
474*d865fc92SAndy Fiddaman 
475*d865fc92SAndy Fiddaman 	for (t = tests; t->name != NULL; t++) {
476*d865fc92SAndy Fiddaman 		if (debug)
477*d865fc92SAndy Fiddaman 			printf("\n>>> Starting test %s\n", t->name);
478*d865fc92SAndy Fiddaman 
479*d865fc92SAndy Fiddaman 		sendtest(t);
480*d865fc92SAndy Fiddaman 		check_fds("server");
481*d865fc92SAndy Fiddaman 
482*d865fc92SAndy Fiddaman 		send_and_wait(pid, &set, SIGUSR1, SIGUSR2);
483*d865fc92SAndy Fiddaman 	}
484*d865fc92SAndy Fiddaman 
485*d865fc92SAndy Fiddaman 	close(cfd);
486*d865fc92SAndy Fiddaman 	close(testfd);
487*d865fc92SAndy Fiddaman 	close(sock);
488*d865fc92SAndy Fiddaman 
489*d865fc92SAndy Fiddaman 	return (0);
490*d865fc92SAndy Fiddaman }
491*d865fc92SAndy Fiddaman 
492*d865fc92SAndy Fiddaman static boolean_t pass;
493*d865fc92SAndy Fiddaman 
494*d865fc92SAndy Fiddaman static void
495*d865fc92SAndy Fiddaman check(uint_t actual, uint_t expected, char *tag)
496*d865fc92SAndy Fiddaman {
497*d865fc92SAndy Fiddaman 	if (actual != expected) {
498*d865fc92SAndy Fiddaman 		fprintf(stderr, "    !!!: "
499*d865fc92SAndy Fiddaman 		    "%1$s = %2$u(%2$#x) (expected %3$u(%3$#x))\n",
500*d865fc92SAndy Fiddaman 		    tag, actual, expected);
501*d865fc92SAndy Fiddaman 		pass = _B_FALSE;
502*d865fc92SAndy Fiddaman 	} else if (debug) {
503*d865fc92SAndy Fiddaman 		fprintf(stderr, "       : "
504*d865fc92SAndy Fiddaman 		    "%1$s = %2$u(%2$#x)\n",
505*d865fc92SAndy Fiddaman 		    tag, actual);
506*d865fc92SAndy Fiddaman 	}
507*d865fc92SAndy Fiddaman }
508*d865fc92SAndy Fiddaman 
509*d865fc92SAndy Fiddaman static boolean_t
510*d865fc92SAndy Fiddaman recvtest(cmsg_test_t *t)
511*d865fc92SAndy Fiddaman {
512*d865fc92SAndy Fiddaman 	struct msghdr msg;
513*d865fc92SAndy Fiddaman 	struct cmsghdr *cm;
514*d865fc92SAndy Fiddaman 	struct iovec iov;
515*d865fc92SAndy Fiddaman 	size_t bufsize;
516*d865fc92SAndy Fiddaman 	ssize_t nbytes;
517*d865fc92SAndy Fiddaman 	char c = '*';
518*d865fc92SAndy Fiddaman 
519*d865fc92SAndy Fiddaman 	bzero(&msg, sizeof (msg));
520*d865fc92SAndy Fiddaman 
521*d865fc92SAndy Fiddaman 	msg.msg_name = NULL;
522*d865fc92SAndy Fiddaman 	msg.msg_namelen = 0;
523*d865fc92SAndy Fiddaman 
524*d865fc92SAndy Fiddaman 	iov.iov_base = &c;
525*d865fc92SAndy Fiddaman 	iov.iov_len = sizeof (c);
526*d865fc92SAndy Fiddaman 	msg.msg_iov = &iov;
527*d865fc92SAndy Fiddaman 	msg.msg_iovlen = 1;
528*d865fc92SAndy Fiddaman 
529*d865fc92SAndy Fiddaman 	msg.msg_flags = 0;
530*d865fc92SAndy Fiddaman 
531*d865fc92SAndy Fiddaman 	/*
532*d865fc92SAndy Fiddaman 	 * If the test does not specify a receive buffer size, calculate one
533*d865fc92SAndy Fiddaman 	 * from the number of file descriptors to receive.
534*d865fc92SAndy Fiddaman 	 */
535*d865fc92SAndy Fiddaman 	if (t->bufsize == 0) {
536*d865fc92SAndy Fiddaman 		bufsize = sizeof (int) * t->recv;
537*d865fc92SAndy Fiddaman 		bufsize = CMSG_SPACE(bufsize);
538*d865fc92SAndy Fiddaman 	} else {
539*d865fc92SAndy Fiddaman 		/*
540*d865fc92SAndy Fiddaman 		 * Use the specific buffer size provided but add in
541*d865fc92SAndy Fiddaman 		 * space for the header
542*d865fc92SAndy Fiddaman 		 */
543*d865fc92SAndy Fiddaman 		bufsize = t->bufsize + CMSG_LEN(0);
544*d865fc92SAndy Fiddaman 	}
545*d865fc92SAndy Fiddaman 
546*d865fc92SAndy Fiddaman 	if (t->predata > 0) {
547*d865fc92SAndy Fiddaman 		/* A dummy cmsg will be found at the head of the data */
548*d865fc92SAndy Fiddaman 		bufsize += CMSG_SPACE(t->predata);
549*d865fc92SAndy Fiddaman 	}
550*d865fc92SAndy Fiddaman 
551*d865fc92SAndy Fiddaman 	msg.msg_controllen = bufsize;
552*d865fc92SAndy Fiddaman 	msg.msg_control = alloca(bufsize);
553*d865fc92SAndy Fiddaman 	bzero(msg.msg_control, msg.msg_controllen);
554*d865fc92SAndy Fiddaman 
555*d865fc92SAndy Fiddaman 	pass = _B_TRUE;
556*d865fc92SAndy Fiddaman 
557*d865fc92SAndy Fiddaman 	if (debug)
558*d865fc92SAndy Fiddaman 		printf("Receiving: controllen=%u, \n", msg.msg_controllen);
559*d865fc92SAndy Fiddaman 
560*d865fc92SAndy Fiddaman 	nbytes = recvmsg(sock, &msg, 0);
561*d865fc92SAndy Fiddaman 
562*d865fc92SAndy Fiddaman 	if (nbytes == -1) {
563*d865fc92SAndy Fiddaman 		pass = _B_FALSE;
564*d865fc92SAndy Fiddaman 		fprintf(stderr, "recvmsg() failed: %s\n", strerror(errno));
565*d865fc92SAndy Fiddaman 		goto out;
566*d865fc92SAndy Fiddaman 	}
567*d865fc92SAndy Fiddaman 
568*d865fc92SAndy Fiddaman 	if (debug) {
569*d865fc92SAndy Fiddaman 		printf("Received: controllen=%u, flags=%#x\n",
570*d865fc92SAndy Fiddaman 		    msg.msg_controllen, msg.msg_flags);
571*d865fc92SAndy Fiddaman 	}
572*d865fc92SAndy Fiddaman 
573*d865fc92SAndy Fiddaman 	check(msg.msg_flags, t->x_flags, "msg_flags");
574*d865fc92SAndy Fiddaman 	check(msg.msg_controllen, t->x_controllen, "msg_controllen");
575*d865fc92SAndy Fiddaman 
576*d865fc92SAndy Fiddaman 	for (cm = CMSG_FIRSTHDR(&msg); cm; cm = CMSG_NXTHDR(&msg, cm)) {
577*d865fc92SAndy Fiddaman 		void *data, *end;
578*d865fc92SAndy Fiddaman 
579*d865fc92SAndy Fiddaman 		if (debug) {
580*d865fc92SAndy Fiddaman 			printf("    >> : Got cmsg %x/%x - %u\n", cm->cmsg_level,
581*d865fc92SAndy Fiddaman 			    cm->cmsg_type, cm->cmsg_len);
582*d865fc92SAndy Fiddaman 		}
583*d865fc92SAndy Fiddaman 
584*d865fc92SAndy Fiddaman 		if (cm->cmsg_type != SCM_RIGHTS) {
585*d865fc92SAndy Fiddaman 			if (debug)
586*d865fc92SAndy Fiddaman 				printf("       : skipping cmsg\n");
587*d865fc92SAndy Fiddaman 			continue;
588*d865fc92SAndy Fiddaman 		}
589*d865fc92SAndy Fiddaman 
590*d865fc92SAndy Fiddaman 		check(cm->cmsg_len - CMSG_LEN(0),
591*d865fc92SAndy Fiddaman 		    t->x_cmsg_datalen, "cmsg_len");
592*d865fc92SAndy Fiddaman 
593*d865fc92SAndy Fiddaman 		/* Close any received file descriptors */
594*d865fc92SAndy Fiddaman 		data = CMSG_DATA(cm);
595*d865fc92SAndy Fiddaman 
596*d865fc92SAndy Fiddaman 		if ((msg.msg_flags & MSG_CTRUNC) &&
597*d865fc92SAndy Fiddaman 		    CMSG_NXTHDR(&msg, cm) == NULL) {
598*d865fc92SAndy Fiddaman 			/*
599*d865fc92SAndy Fiddaman 			 * illumos did not previously adjust cmsg_len on
600*d865fc92SAndy Fiddaman 			 * truncation. This is the last cmsg, derive the
601*d865fc92SAndy Fiddaman 			 * length from msg_controllen
602*d865fc92SAndy Fiddaman 			 */
603*d865fc92SAndy Fiddaman 			end = msg.msg_control + msg.msg_controllen;
604*d865fc92SAndy Fiddaman 		} else {
605*d865fc92SAndy Fiddaman 			end = data + cm->cmsg_len - CMSG_LEN(0);
606*d865fc92SAndy Fiddaman 		}
607*d865fc92SAndy Fiddaman 
608*d865fc92SAndy Fiddaman 		while (data <= end - sizeof (int)) {
609*d865fc92SAndy Fiddaman 			int *a = (int *)data;
610*d865fc92SAndy Fiddaman 			if (debug)
611*d865fc92SAndy Fiddaman 				printf("       : close(%d)\n", *a);
612*d865fc92SAndy Fiddaman 			if (close(*a) == -1) {
613*d865fc92SAndy Fiddaman 				pass = _B_FALSE;
614*d865fc92SAndy Fiddaman 				fprintf(stderr, "    !!!: "
615*d865fc92SAndy Fiddaman 				    "failed to close fd %d - %s\n", *a,
616*d865fc92SAndy Fiddaman 				    strerror(errno));
617*d865fc92SAndy Fiddaman 			}
618*d865fc92SAndy Fiddaman 			data += sizeof (int);
619*d865fc92SAndy Fiddaman 		}
620*d865fc92SAndy Fiddaman 	}
621*d865fc92SAndy Fiddaman 
622*d865fc92SAndy Fiddaman out:
623*d865fc92SAndy Fiddaman 
624*d865fc92SAndy Fiddaman 	check_fds("client");
625*d865fc92SAndy Fiddaman 	check(fdcount, 0, "client descriptors");
626*d865fc92SAndy Fiddaman 	printf("     + : %s %s\n", pass ? "PASS" : "FAIL", t->name);
627*d865fc92SAndy Fiddaman 
628*d865fc92SAndy Fiddaman 	return (pass);
629*d865fc92SAndy Fiddaman }
630*d865fc92SAndy Fiddaman 
631*d865fc92SAndy Fiddaman static int
632*d865fc92SAndy Fiddaman client(const char *sockpath, pid_t pid)
633*d865fc92SAndy Fiddaman {
634*d865fc92SAndy Fiddaman 	struct sockaddr_un addr;
635*d865fc92SAndy Fiddaman 	sigset_t set;
636*d865fc92SAndy Fiddaman 	cmsg_test_t *t;
637*d865fc92SAndy Fiddaman 	int ret = 0;
638*d865fc92SAndy Fiddaman 
639*d865fc92SAndy Fiddaman 	sigemptyset(&set);
640*d865fc92SAndy Fiddaman 	sigaddset(&set, SIGUSR1);
641*d865fc92SAndy Fiddaman 	sigaddset(&set, SIGINT);
642*d865fc92SAndy Fiddaman 
643*d865fc92SAndy Fiddaman 	send_and_wait(pid, &set, 0, SIGUSR1);
644*d865fc92SAndy Fiddaman 
645*d865fc92SAndy Fiddaman 	sock = socket(PF_LOCAL, SOCK_STREAM, 0);
646*d865fc92SAndy Fiddaman 	if (sock == -1)
647*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "failed to create socket");
648*d865fc92SAndy Fiddaman 	addr.sun_family = AF_UNIX;
649*d865fc92SAndy Fiddaman 	strlcpy(addr.sun_path, sockpath, sizeof (addr.sun_path));
650*d865fc92SAndy Fiddaman 	if (connect(sock, (struct sockaddr *)&addr, sizeof (addr)) == -1)
651*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "could not connect to server socket");
652*d865fc92SAndy Fiddaman 
653*d865fc92SAndy Fiddaman 	for (t = tests; t->name != NULL; t++) {
654*d865fc92SAndy Fiddaman 		send_and_wait(pid, &set, SIGUSR2, SIGUSR1);
655*d865fc92SAndy Fiddaman 		if (!recvtest(t))
656*d865fc92SAndy Fiddaman 			ret = 1;
657*d865fc92SAndy Fiddaman 	}
658*d865fc92SAndy Fiddaman 
659*d865fc92SAndy Fiddaman 	close(sock);
660*d865fc92SAndy Fiddaman 
661*d865fc92SAndy Fiddaman 	return (ret);
662*d865fc92SAndy Fiddaman }
663*d865fc92SAndy Fiddaman 
664*d865fc92SAndy Fiddaman int
665*d865fc92SAndy Fiddaman main(int argc, const char **argv)
666*d865fc92SAndy Fiddaman {
667*d865fc92SAndy Fiddaman 	char sockpath[] = "/tmp/cmsg.testsock.XXXXXX";
668*d865fc92SAndy Fiddaman 	pid_t pid, ppid;
669*d865fc92SAndy Fiddaman 	sigset_t set;
670*d865fc92SAndy Fiddaman 	int ret = 0;
671*d865fc92SAndy Fiddaman 
672*d865fc92SAndy Fiddaman 	if (argc > 1 && strcmp(argv[1], "-d") == 0)
673*d865fc92SAndy Fiddaman 		debug = _B_TRUE;
674*d865fc92SAndy Fiddaman 
675*d865fc92SAndy Fiddaman 	sigfillset(&set);
676*d865fc92SAndy Fiddaman 	sigdelset(&set, SIGINT);
677*d865fc92SAndy Fiddaman 	sigdelset(&set, SIGTSTP);
678*d865fc92SAndy Fiddaman 	sigprocmask(SIG_BLOCK, &set, NULL);
679*d865fc92SAndy Fiddaman 
680*d865fc92SAndy Fiddaman 	if (mktemp(sockpath) == NULL)
681*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "Failed to make temporary socket path");
682*d865fc92SAndy Fiddaman 
683*d865fc92SAndy Fiddaman 	ppid = getpid();
684*d865fc92SAndy Fiddaman 	pid = fork();
685*d865fc92SAndy Fiddaman 	switch (pid) {
686*d865fc92SAndy Fiddaman 	case -1:
687*d865fc92SAndy Fiddaman 		err(EXIT_FAILURE, "fork failed");
688*d865fc92SAndy Fiddaman 	case 0:
689*d865fc92SAndy Fiddaman 		return (server(sockpath, ppid));
690*d865fc92SAndy Fiddaman 	default:
691*d865fc92SAndy Fiddaman 		break;
692*d865fc92SAndy Fiddaman 	}
693*d865fc92SAndy Fiddaman 
694*d865fc92SAndy Fiddaman 	ret = client(sockpath, pid);
695*d865fc92SAndy Fiddaman 	kill(pid, SIGINT);
696*d865fc92SAndy Fiddaman 
697*d865fc92SAndy Fiddaman 	unlink(sockpath);
698*d865fc92SAndy Fiddaman 
699*d865fc92SAndy Fiddaman 	return (ret);
700*d865fc92SAndy Fiddaman }
701