xref: /minix/minix/tests/test56.c (revision ebfedea0)
1 /*
2  * Test Program for Unix Domain Sockets
3  *
4  * Overview: This program tests Unix Domain Sockets. It attempts
5  * to exercise the functions associated with Unix Domain Sockets.
6  * It also attempts to make sure all of the functions which handle
7  * file/socket descriptors work correctly when given a socket
8  * descriptor for a Unix domain socket. It also implicitly checks
9  * for the existance of constants like AF_UNIX and structures like
10  * sockaddr_un (it won't compile if they aren't defined). Besides
11  * checking that the sockets work properly, this test program also
12  * checks that the errors returned conform to the POSIX 2008
13  * standards. Some tests are omitted as they could adversely affect
14  * the operation of the host system. For example, implementing a test
15  * for socket() failing with errno = ENFILE would require using up all
16  * of the file descriptors supported by the OS (defined in
17  * /proc/sys/fs/file-max on Linux); this could cause problems for
18  * daemons and other processes running on the system. Some tests are
19  * omitted because they would require changes to libc or the kernel.
20  * For example, getting EINTR would require  delaying the system call
21  * execution time long enough to raise a signal to interupt it. Some
22  * tests were omitted because the particular errors cannot occur when
23  * using Unix domain sockets. For example, write() will never fail with
24  * ENETDOWN because Unix domain sockets don't use network interfaces.
25  *
26  * Structure: Some functions can be tested or partially tested without
27  * making a connection, socket() for example. These have test
28  * functions like test_NAME(). The functionality that needs two way
29  * communication is contained within test_xfer().
30  *
31  * Functions Tested: accept(), bind(), close(), connect(), dup(),
32  * dup2(), fstat(), getpeername(), getsockname(), getsockopt(),
33  * listen(), read(), readv(), recv(), recvfrom(), recvmsg(), select(),
34  * send(), sendmsg(), sendto(), setsockopt(), shutdown(), socket(),
35  * socketpair(), write(), writev()
36  */
37 
38 #include <ctype.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <signal.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <sys/socket.h>
46 #include <sys/ucred.h>
47 #include <sys/stat.h>
48 #include <sys/time.h>
49 #include <sys/types.h>
50 #include <sys/uio.h>
51 #include <sys/un.h>
52 #include <sys/wait.h>
53 #include <time.h>
54 #include <unistd.h>
55 
56 /* Maximum number of errors that we'll allow to occur before this test
57  * program gives us and quits.
58  */
59 int max_error = 4;
60 #include "common.h"
61 #include "common-socket.h"
62 
63 
64 /* Use the common testing code instead of reinventing the wheel. */
65 
66 /* path of the unix domain socket */
67 #define TEST_SUN_PATH "test.sock"
68 #define TEST_SUN_PATHB "testb.sock"
69 
70 /* filenames for symlinks -- we link these to each other to test ELOOP .*/
71 #define TEST_SYM_A "test.a"
72 #define TEST_SYM_B "test.b"
73 
74 /* text file and test phrase for testing file descriptor passing */
75 #define TEST_TXT_FILE "test.txt"
76 #define MSG "This raccoon loves to eat bugs.\n"
77 
78 /* socket types supported */
79 static int types[3] = {SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM};
80 static char sock_fullpath[PATH_MAX + 1];
81 
82 /* Convert name to the full path of the socket. Assumes name is in cwd. */
83 static char *fullpath(const char *name)
84 {
85 	char cwd[PATH_MAX + 1];
86 
87 	if (realpath(".", cwd) == NULL)
88 		test_fail("Couldn't retrieve current working dir");
89 
90 	snprintf(sock_fullpath, PATH_MAX, "%s/%s", cwd, name);
91 
92 	return(sock_fullpath);
93 }
94 
95 static void test_header(void)
96 {
97 	struct sockaddr_un sun;
98 	debug("entering test_header()");
99 
100 	sun.sun_family = AF_UNIX;
101 	sun.sun_path[0] = 'x';
102 	sun.sun_path[1] = 'x';
103 	sun.sun_path[2] = 'x';
104 	sun.sun_path[3] = '\0';
105 
106 	if (SUN_LEN(&sun) != 5) {
107 		test_fail("SUN_LEN(&sun) should be 5");
108 	}
109 
110 	if (PF_UNIX != PF_LOCAL || PF_UNIX != AF_UNIX) {
111 		test_fail("PF_UNIX, PF_LOCAL and AF_UNIX");
112 	}
113 }
114 
115 static void test_socketpair(void)
116 {
117 	char buf[128];
118 	struct sockaddr_un addr;
119 	int socket_vector[2];
120 	int rc;
121 	int i;
122 
123 	debug("entering test_socketpair()");
124 
125 	UNLINK(TEST_SUN_PATH);
126 	memset(&addr, '\0', sizeof(struct sockaddr_un));
127 	addr.sun_family = AF_UNIX;
128 	strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
129 
130 	debug("Testing socketpair() success");
131 
132 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector);
133 	if (rc == -1) {
134 		test_fail("socketpair() should have worked");
135 	}
136 
137 	debug("Testing a simple read/write using sockets from socketpair()");
138 	memset(buf, '\0', sizeof(buf));
139 
140 	strncpy(buf, "Howdy Partner", sizeof(buf) - 1);
141 
142 	rc = write(socket_vector[0], buf, sizeof(buf));
143 	if (rc == -1) {
144 		test_fail("write(sd, buf, sizeof(buf)) failed unexpectedly");
145 	}
146 
147 	memset(buf, '\0', sizeof(buf));
148 
149 	rc = read(socket_vector[1], buf, sizeof(buf));
150 	if (rc == -1) {
151 		test_fail("read() failed unexpectedly");
152 	}
153 
154 	if (strncmp(buf, "Howdy Partner", strlen("Howdy Partner")) != 0) {
155 		test_fail("We did not read what we wrote");
156 	}
157 
158 	CLOSE(socket_vector[0]);
159 	CLOSE(socket_vector[1]);
160 
161 	debug("Test socketpair() with all FDs open by this process");
162 
163 	for (i = 3; i < getdtablesize(); i++) {
164 		rc = open("/dev/null", O_RDONLY);
165 		if (rc == -1) {
166 			test_fail("we couldn't open /dev/null for read");
167 		}
168 	}
169 
170 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector);
171 	if (!(rc == -1 && errno == EMFILE)) {
172 		test_fail("socketpair() should have failed with EMFILE");
173 	}
174 
175 	for (i = 3; i < getdtablesize(); i++) {
176 		CLOSE(i);
177 	}
178 
179 	rc = socketpair(PF_UNIX, SOCK_STREAM, 4, socket_vector);
180 	if (!(rc == -1 && errno == EPROTONOSUPPORT)) {
181 		test_fail("socketpair() should have failed");
182 	}
183 
184 	debug("leaving test_socketpair()");
185 }
186 
187 static void test_ucred(void)
188 {
189 	struct uucred credentials;
190 	socklen_t ucred_length;
191 	uid_t euid = geteuid();
192 	gid_t egid = getegid();
193 	int sv[2];
194 	int rc;
195 
196 	debug("Test credentials passing");
197 
198 	ucred_length = sizeof(struct uucred);
199 
200 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
201 	if (rc == -1) {
202 		test_fail("socketpair(PF_UNIX, SOCK_STREAM, 0, sv) failed");
203 	}
204 
205 	memset(&credentials, '\0', ucred_length);
206 	rc = getsockopt(sv[0], SOL_SOCKET, SO_PEERCRED, &credentials,
207 							&ucred_length);
208 	if (rc == -1) {
209 		test_fail("getsockopt(SO_PEERCRED) failed");
210 	} else if (credentials.cr_ngroups != 0 ||
211 			credentials.cr_uid != geteuid() ||
212 			credentials.cr_gid != getegid()) {
213 		/* printf("%d=%d %d=%d %d=%d",credentials.cr_ngroups, 0,
214 		 credentials.cr_uid, geteuid(), credentials.cr_gid, getegid()); */
215 		test_fail("Credential passing gave us the wrong cred");
216 	}
217 
218 	rc = getpeereid(sv[0], &euid, &egid);
219 	if (rc == -1) {
220 		test_fail("getpeereid(sv[0], &euid, &egid) failed");
221 	} else if (credentials.cr_uid != euid || credentials.cr_gid != egid) {
222 		test_fail("getpeereid() didn't give the correct euid/egid");
223 	}
224 
225 	CLOSE(sv[0]);
226 	CLOSE(sv[1]);
227 }
228 
229 static void callback_check_sockaddr(const struct sockaddr *sockaddr,
230 	socklen_t sockaddrlen, const char *callname, int addridx) {
231 	char buf[256];
232 	const char *path;
233 	const struct sockaddr_un *sockaddr_un =
234 		(const struct sockaddr_un *) sockaddr;
235 
236 	switch (addridx) {
237 	case 1: path = TEST_SUN_PATH; break;
238 	case 2: path = TEST_SUN_PATHB; break;
239 	default:
240 		fprintf(stderr, "error: invalid addridx %d in "
241 			"callback_check_sockaddr\n", addridx);
242 		abort();
243 	}
244 
245 	if (!(sockaddr_un->sun_family == AF_UNIX &&
246 			strncmp(sockaddr_un->sun_path,
247 			fullpath(path),
248 			sizeof(sockaddr_un->sun_path) - 1) == 0)) {
249 
250 		snprintf(buf, sizeof(buf), "%s() didn't return the right addr",
251 			callname);
252 		test_fail(buf);
253 		fprintf(stderr, "exp: '%s' | got: '%s'\n", path,
254 			sockaddr_un->sun_path);
255 	}
256 }
257 
258 static void callback_cleanup(void) {
259 	UNLINK(TEST_SUN_PATH);
260 	UNLINK(TEST_SUN_PATHB);
261 	UNLINK(TEST_SYM_A);
262 	UNLINK(TEST_SYM_B);
263 }
264 
265 static void test_bind_unix(void)
266 {
267 	struct sockaddr_un addr;
268 	int sd;
269 	int rc;
270 
271 	debug("entering test_bind_unix()");
272 	UNLINK(TEST_SUN_PATH);
273 	memset(&addr, '\0', sizeof(struct sockaddr_un));
274 	addr.sun_family = AF_UNIX;
275 	strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
276 
277 	debug("Test bind() with an empty sun_path");
278 
279 	SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
280 	memset(addr.sun_path, '\0', sizeof(addr.sun_path));
281 	errno = 0;
282 
283 	rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
284 	if (!(rc == -1 && errno == ENOENT)) {
285 		test_fail("bind() should have failed with ENOENT");
286 	}
287 	CLOSE(sd);
288 
289 	debug("Test bind() using a symlink loop");
290 
291 	UNLINK(TEST_SUN_PATH);
292 	UNLINK(TEST_SYM_A);
293 	UNLINK(TEST_SYM_B);
294 
295 	SYMLINK(TEST_SYM_A, TEST_SYM_B);
296 	SYMLINK(TEST_SYM_B, TEST_SYM_A);
297 
298 	SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
299 
300 	strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1);
301 	errno = 0;
302 	rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
303 	if (!((rc == -1) && (errno == ELOOP))) {
304 		test_fail("bind() should have failed with ELOOP");
305 	}
306 	CLOSE(sd);
307 
308 	UNLINK(TEST_SUN_PATH);
309 	UNLINK(TEST_SYM_A);
310 	UNLINK(TEST_SYM_B);
311 
312 	/* Test bind with garbage in sockaddr_un */
313 	memset(&addr, '?', sizeof(struct sockaddr_un));
314 	addr.sun_family = AF_UNIX;
315 	addr.sun_path[0] = 'f';
316 	addr.sun_path[1] = 'o';
317 	addr.sun_path[2] = 'o';
318 	addr.sun_path[3] = '\0';
319 	SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
320 	rc = bind(sd, (struct sockaddr *) &addr, strlen(addr.sun_path) + 1);
321 	if (rc == -1) {
322 		test_fail("bind() should have worked");
323 	}
324 	CLOSE(sd);
325 	UNLINK("foo");
326 
327 	debug("leaving test_bind_unix()");
328 }
329 
330 static void callback_xfer_prepclient(void) {
331 	debug("Creating symlink to TEST_SUN_PATH");
332 
333 	SYMLINK(TEST_SUN_PATH, TEST_SYM_A);
334 }
335 
336 static void callback_xfer_peercred(int sd) {
337 	struct uucred credentials;
338 	int rc;
339 	socklen_t ucred_length;
340 
341 	ucred_length = sizeof(struct uucred);
342 
343 	debug("Test passing the client credentials to the server");
344 
345 	memset(&credentials, '\0', ucred_length);
346 	rc = getsockopt(sd, SOL_SOCKET, SO_PEERCRED, &credentials,
347 							&ucred_length);
348 
349 	if (rc == -1) {
350 		test_fail("[client] getsockopt() failed");
351 	}  else if (credentials.cr_uid != geteuid() ||
352 					credentials.cr_gid != getegid()) {
353 		printf("%d=%d=%d %d=%d=%d\n", credentials.cr_uid, getuid(),
354 			geteuid(), credentials.cr_gid, getgid(), getegid());
355 		test_fail("[client] Credential passing gave us a bad UID/GID");
356 	}
357 }
358 
359 static void test_vectorio(int type)
360 {
361 	int sv[2];
362 	int rc;
363 	struct iovec iov[3];
364 	char buf1[BUFSIZE];
365 	char buf2[BUFSIZE];
366 	char buf3[BUFSIZE];
367 	char buf4[BUFSIZE*3];
368 	const struct iovec *iovp = iov;
369 
370 	debug("begin vectorio tests");
371 
372 	memset(buf1, '\0', BUFSIZE);
373 	strncpy(buf1, "HELLO ", BUFSIZE - 1);
374 
375 	memset(buf2, '\0', BUFSIZE);
376 	strncpy(buf2, "WORLD", BUFSIZE - 1);
377 
378 	memset(buf3, '\0', BUFSIZE);
379 
380 	rc = socketpair(PF_UNIX, type, 0, sv);
381 	if (rc == -1) {
382 		test_fail("socketpair");
383 	}
384 
385 	iov[0].iov_base = buf1;
386 	iov[0].iov_len  = strlen(buf1);
387 	iov[1].iov_base = buf2;
388 	iov[1].iov_len  = strlen(buf2);
389 	iov[2].iov_base = buf3;
390 	iov[2].iov_len  = 1;
391 
392 	rc = writev(sv[0], iovp, 3);
393 	if (rc == -1) {
394 		test_fail("writev");
395 	}
396 
397 	memset(buf4, '\0', BUFSIZE*3);
398 
399 	rc = read(sv[1], buf4, BUFSIZE*3);
400 	if (rc == -1) {
401 		test_fail("read");
402 	}
403 
404 	if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
405 		test_fail("the string we read was not 'HELLO WORLD'");
406 	}
407 
408 	memset(buf1, '\0', BUFSIZE);
409 	strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
410 
411 	rc = write(sv[1], buf1, strlen(buf1) + 1);
412 	if (rc == -1) {
413 		test_fail("write");
414 	}
415 
416 	memset(buf2, '\0', BUFSIZE);
417 	memset(buf3, '\0', BUFSIZE);
418 	memset(buf4, '\0', BUFSIZE*3);
419 
420 	iov[0].iov_base = buf2;
421 	iov[0].iov_len  = 5;
422 	iov[1].iov_base = buf3;
423 	iov[1].iov_len  = 5;
424 	iov[2].iov_base = buf4;
425 	iov[2].iov_len  = 32;
426 
427 	rc = readv(sv[0], iovp, 3);
428 	if (rc == -1) {
429 		test_fail("readv");
430 	}
431 
432 	if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
433 					strncmp(buf4, "Time", 4)) {
434 		test_fail("readv");
435 	}
436 
437 	rc = close(sv[0]);
438 	if (rc == -1) {
439 		test_fail("close");
440 	}
441 
442 	rc = close(sv[1]);
443 	if (rc == -1) {
444 		test_fail("close");
445 	}
446 
447 	debug("done vector io tests");
448 }
449 
450 static void test_msg(int type)
451 {
452 	int sv[2];
453 	int rc;
454 	struct msghdr msg1;
455 	struct msghdr msg2;
456 	struct iovec iov[3];
457 	char buf1[BUFSIZE];
458 	char buf2[BUFSIZE];
459 	char buf3[BUFSIZE];
460 	char buf4[BUFSIZE*3];
461 
462 	debug("begin sendmsg/recvmsg tests");
463 
464 	memset(buf1, '\0', BUFSIZE);
465 	strncpy(buf1, "HELLO ", BUFSIZE - 1);
466 
467 	memset(buf2, '\0', BUFSIZE);
468 	strncpy(buf2, "WORLD", BUFSIZE - 1);
469 
470 	memset(buf3, '\0', BUFSIZE);
471 
472 	rc = socketpair(PF_UNIX, type, 0, sv);
473 	if (rc == -1) {
474 		test_fail("socketpair");
475 	}
476 
477 	iov[0].iov_base = buf1;
478 	iov[0].iov_len  = strlen(buf1);
479 	iov[1].iov_base = buf2;
480 	iov[1].iov_len  = strlen(buf2);
481 	iov[2].iov_base = buf3;
482 	iov[2].iov_len  = 1;
483 
484 	memset(&msg1, '\0', sizeof(struct msghdr));
485 	msg1.msg_name = NULL;
486 	msg1.msg_namelen = 0;
487 	msg1.msg_iov = iov;
488 	msg1.msg_iovlen = 3;
489 	msg1.msg_control = NULL;
490 	msg1.msg_controllen = 0;
491 	msg1.msg_flags = 0;
492 
493 	rc = sendmsg(sv[0], &msg1, 0);
494 	if (rc == -1) {
495 		test_fail("writev");
496 	}
497 
498 	memset(buf4, '\0', BUFSIZE*3);
499 
500 	rc = read(sv[1], buf4, BUFSIZE*3);
501 	if (rc == -1) {
502 		test_fail("read");
503 	}
504 
505 	if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
506 		test_fail("the string we read was not 'HELLO WORLD'");
507 	}
508 
509 	memset(buf1, '\0', BUFSIZE);
510 	strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
511 
512 	rc = write(sv[1], buf1, strlen(buf1) + 1);
513 	if (rc == -1) {
514 		test_fail("write");
515 	}
516 
517 	memset(buf2, '\0', BUFSIZE);
518 	memset(buf3, '\0', BUFSIZE);
519 	memset(buf4, '\0', BUFSIZE*3);
520 
521 	iov[0].iov_base = buf2;
522 	iov[0].iov_len  = 5;
523 	iov[1].iov_base = buf3;
524 	iov[1].iov_len  = 5;
525 	iov[2].iov_base = buf4;
526 	iov[2].iov_len  = 32;
527 
528 	memset(&msg2, '\0', sizeof(struct msghdr));
529 	msg2.msg_name = NULL;
530 	msg2.msg_namelen = 0;
531 	msg2.msg_iov = iov;
532 	msg2.msg_iovlen = 3;
533 	msg2.msg_control = NULL;
534 	msg2.msg_controllen = 0;
535 	msg2.msg_flags = 0;
536 
537 	rc = recvmsg(sv[0], &msg2, 0);
538 	if (rc == -1) {
539 		test_fail("readv");
540 	}
541 
542 	if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
543 					strncmp(buf4, "Time", 4)) {
544 		test_fail("readv");
545 	}
546 
547 	rc = close(sv[0]);
548 	if (rc == -1) {
549 		test_fail("close");
550 	}
551 
552 	rc = close(sv[1]);
553 	if (rc == -1) {
554 		test_fail("close");
555 	}
556 }
557 
558 static void test_scm_credentials(void)
559 {
560 	int rc;
561 	int src;
562 	int dst;
563 	struct uucred cred;
564 	struct cmsghdr *cmsg = NULL;
565 	struct sockaddr_un addr;
566 	struct iovec iov[3];
567 	struct msghdr msg1;
568 	struct msghdr msg2;
569 	char buf1[BUFSIZE];
570 	char buf2[BUFSIZE];
571 	char buf3[BUFSIZE];
572 	char ctrl[BUFSIZE];
573 	socklen_t addrlen = sizeof(struct sockaddr_un);
574 
575 	debug("test_scm_credentials");
576 
577 	UNLINK(TEST_SUN_PATH);
578 	UNLINK(TEST_SUN_PATHB);
579 
580 	debug("creating src socket");
581 
582 	src = socket(PF_UNIX, SOCK_DGRAM, 0);
583 	if (src == -1) {
584 		test_fail("socket");
585 	}
586 
587 	debug("creating dst socket");
588 
589 	dst = socket(PF_UNIX, SOCK_DGRAM, 0);
590 	if (dst == -1) {
591 		test_fail("socket");
592 	}
593 
594 	debug("binding src socket");
595 
596 	memset(&addr, '\0', sizeof(struct sockaddr_un));
597 	addr.sun_family = AF_UNIX;
598 	strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1);
599 	rc = bind(src, (struct sockaddr *) &addr, addrlen);
600 	if (rc == -1) {
601 		test_fail("bind");
602 	}
603 
604 	debug("binding dst socket");
605 
606 	memset(&addr, '\0', sizeof(struct sockaddr_un));
607 	addr.sun_family = AF_UNIX;
608 	strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
609 
610 	rc = bind(dst, (struct sockaddr *) &addr, addrlen);
611 	if (rc == -1) {
612 		test_fail("bind");
613 	}
614 
615 	memset(&buf1, '\0', BUFSIZE);
616 	memset(&buf2, '\0', BUFSIZE);
617 	memset(&buf3, '\0', BUFSIZE);
618 	memset(&ctrl, '\0', BUFSIZE);
619 
620 	strncpy(buf1, "Minix ", BUFSIZE-1);
621 	strncpy(buf2, "is ", BUFSIZE-1);
622 	strncpy(buf3, "great!", BUFSIZE-1);
623 
624 	iov[0].iov_base = buf1;
625 	iov[0].iov_len  = 6;
626 	iov[1].iov_base = buf2;
627 	iov[1].iov_len  = 3;
628 	iov[2].iov_base = buf3;
629 	iov[2].iov_len  = 32;
630 
631 	memset(&msg1, '\0', sizeof(struct msghdr));
632 	msg1.msg_name = &addr;
633 	msg1.msg_namelen = addrlen;
634 	msg1.msg_iov = iov;
635 	msg1.msg_iovlen = 3;
636 	msg1.msg_control = NULL;
637 	msg1.msg_controllen = 0;
638 	msg1.msg_flags = 0;
639 
640 	debug("sending msg1");
641 
642 	rc = sendmsg(src, &msg1, 0);
643 	if (rc == -1) {
644 		test_fail("sendmsg");
645 	}
646 
647 	memset(&buf1, '\0', BUFSIZE);
648 	memset(&buf2, '\0', BUFSIZE);
649 	memset(&buf3, '\0', BUFSIZE);
650 	memset(&ctrl, '\0', BUFSIZE);
651 
652 	iov[0].iov_base = buf1;
653 	iov[0].iov_len  = 9;
654 	iov[1].iov_base = buf2;
655 	iov[1].iov_len  = 32;
656 
657 	memset(&addr, '\0', sizeof(struct sockaddr_un));
658 	memset(&msg2, '\0', sizeof(struct msghdr));
659 	msg2.msg_name = &addr;
660 	msg2.msg_namelen = sizeof(struct sockaddr_un);
661 	msg2.msg_iov = iov;
662 	msg2.msg_iovlen = 2;
663 	msg2.msg_control = ctrl;
664 	msg2.msg_controllen = BUFSIZE;
665 	msg2.msg_flags = 0;
666 
667 	debug("recv msg2");
668 
669 	rc = recvmsg(dst, &msg2, 0);
670 	if (rc == -1) {
671 		test_fail("recvmsg");
672 	}
673 
674 	debug("checking results");
675 
676 	if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
677 		test_fail("recvmsg");
678 	}
679 
680 	/* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
681 	 * because that is what is returned by recvmsg().
682 	 */
683 	if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path,
684 					fullpath(TEST_SUN_PATHB))) {
685 		test_fail("recvmsg");
686 	}
687 
688 	debug("looking for credentials");
689 
690 	memset(&cred, '\0', sizeof(struct uucred));
691 	for (cmsg = CMSG_FIRSTHDR(&msg2); cmsg != NULL;
692 					cmsg = CMSG_NXTHDR(&msg2, cmsg)) {
693 
694 		if (cmsg->cmsg_level == SOL_SOCKET &&
695 				cmsg->cmsg_type == SCM_CREDS) {
696 
697 			memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct uucred));
698 			break;
699 		}
700 	}
701 
702 	if (cred.cr_ngroups != 0 || cred.cr_uid != geteuid() ||
703 						cred.cr_gid != getegid()) {
704 
705 		test_fail("did no receive the proper credentials");
706 	}
707 
708 	rc = close(dst);
709 	if (rc == -1) {
710 		test_fail("close");
711 	}
712 
713 	rc = close(src);
714 	if (rc == -1) {
715 		test_fail("close");
716 	}
717 
718 	UNLINK(TEST_SUN_PATH);
719 	UNLINK(TEST_SUN_PATHB);
720 }
721 
722 static void test_connect(const struct socket_test_info *info)
723 {
724 	int i, sd, sds[2], rc;
725 
726 	/* connect() is already tested throughout test56, but
727 	 * in most cases the client and server end up on /dev/uds
728 	 * minor 0 and minor 1. This test opens some sockets first and
729 	 * then calls test_simple_client_server(). This forces the
730 	 * client and server minor numbers higher in the descriptor table.
731 	 */
732 
733 	debug("starting test_connect()");
734 
735 	sd = socket(AF_UNIX, SOCK_DGRAM, 0);
736 	if (sd == -1) {
737 		test_fail("couldn't create a socket");
738 	}
739 
740 	rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sds);
741 	if (rc == -1) {
742 		test_fail("couldn't create a socketpair");
743 	}
744 
745 	for (i = 0; i < 3; i++) {
746 		test_simple_client_server(info, types[i]);
747 	}
748 
749 	rc = close(sds[1]);
750 	if (rc == -1) {
751 		test_fail("close() failed");
752 	}
753 
754 	rc = close(sds[0]);
755 	if (rc == -1) {
756 		test_fail("close() failed");
757 	}
758 
759 	rc = close(sd);
760 	if (rc == -1) {
761 		test_fail("close() failed");
762 	}
763 
764 	debug("exiting test_connect()");
765 }
766 
767 static int test_multiproc_read(void)
768 {
769 /* test that when we fork() a process with an open socket descriptor,
770  * the descriptor in each process points to the same thing.
771  */
772 
773 	pid_t pid;
774 	int sds[2];
775 	int rc, status;
776 	char buf[3];
777 
778 	debug("entering test_multiproc_read()");
779 
780 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
781 	if (rc == -1) {
782 		test_fail("socketpair");
783 		return 1;
784 	}
785 
786 	memset(buf, '\0', 3);
787 
788 
789 	/* the signal handler is only used by the client, but we have to
790 	 * install it now. if we don't the server may signal the client
791 	 * before the handler is installed.
792 	 */
793 	debug("installing signal handler");
794 	if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
795 		test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
796 		return 1;
797 	}
798 
799 	debug("signal handler installed");
800 
801 	server_ready = 0;
802 
803 	pid = fork();
804 
805 	if (pid == -1) {
806 
807 		test_fail("fork");
808 		return 1;
809 
810 	} else if (pid == 0) {
811 
812 		while (server_ready == 0) {
813 			debug("waiting for SIGUSR1 from parent");
814 			sleep(1);
815 		}
816 
817 		rc = read(sds[1], buf, 2);
818 		if (rc == -1) {
819 			test_fail("read");
820 			exit(1);
821 		}
822 
823 		if (!(buf[0] == 'X' && buf[1] == '3')) {
824 			test_fail("Didn't read X3");
825 			exit(1);
826 		}
827 
828 		exit(0);
829 	} else {
830 
831 		rc = write(sds[0], "MNX3", 4);
832 		if (rc == -1) {
833 			test_fail("write");
834 		}
835 
836 		rc = read(sds[1], buf, 2);
837 		if (rc == -1) {
838 			test_fail("read");
839 		}
840 
841 		if (!(buf[0] == 'M' && buf[1] == 'N')) {
842 			test_fail("Didn't read MN");
843 		}
844 
845 		/* time to tell the client to start the test */
846 		kill(pid, SIGUSR1);
847 
848 		do {
849 			rc = waitpid(pid, &status, 0);
850 		} while (rc == -1 && errno == EINTR);
851 
852 		/* we use the exit status to get its error count */
853 		errct += WEXITSTATUS(status);
854 	}
855 
856 	return 0;
857 }
858 
859 static int test_multiproc_write(void)
860 {
861 /* test that when we fork() a process with an open socket descriptor,
862  * the descriptor in each process points to the same thing.
863  */
864 
865 	pid_t pid;
866 	int sds[2];
867 	int rc, status;
868 	char buf[7];
869 
870 	debug("entering test_multiproc_write()");
871 
872 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
873 	if (rc == -1) {
874 		test_fail("socketpair");
875 		return 1;
876 	}
877 
878 	memset(buf, '\0', 7);
879 
880 
881 	/* the signal handler is only used by the client, but we have to
882 	 * install it now. if we don't the server may signal the client
883 	 * before the handler is installed.
884 	 */
885 	debug("installing signal handler");
886 	if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
887 		test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
888 		return 1;
889 	}
890 
891 	debug("signal handler installed");
892 
893 	server_ready = 0;
894 
895 	pid = fork();
896 
897 	if (pid == -1) {
898 
899 		test_fail("fork");
900 		return 1;
901 
902 	} else if (pid == 0) {
903 
904 		while (server_ready == 0) {
905 			debug("waiting for SIGUSR1 from parent");
906 			sleep(1);
907 		}
908 
909 		rc = write(sds[1], "IX3", 3);
910 		if (rc == -1) {
911 			test_fail("write");
912 			exit(1);
913 		}
914 
915 		rc = read(sds[0], buf, 6);
916 		if (rc == -1) {
917 			test_fail("read");
918 			exit(1);
919 		}
920 
921 		if (strcmp(buf, "MINIX3") != 0) {
922 			test_fail("didn't read MINIX3");
923 			exit(1);
924 		}
925 
926 		exit(0);
927 	} else {
928 
929 		rc = write(sds[1], "MIN", 3);
930 		if (rc == -1) {
931 			test_fail("write");
932 		}
933 
934 		/* time to tell the client to start the test */
935 		kill(pid, SIGUSR1);
936 
937 		do {
938 			rc = waitpid(pid, &status, 0);
939 		} while (rc == -1 && errno == EINTR);
940 
941 		/* we use the exit status to get its error count */
942 		errct += WEXITSTATUS(status);
943 	}
944 
945 	return 0;
946 }
947 
948 static void test_fd_passing_child(int sd)
949 {
950 	int fd, rc;
951 	char x = 'x';
952 	struct msghdr msghdr;
953 	struct cmsghdr *cmsg;
954 	struct iovec iov;
955 	char buf[BUFSIZE];
956 
957 	memset(buf, '\0', BUFSIZE);
958 
959 	fd = open(TEST_TXT_FILE, O_CREAT|O_TRUNC|O_RDWR);
960 	if (fd == -1) {
961 		test_fail("could not open test.txt");
962 	}
963 
964 	msghdr.msg_name = NULL;
965 	msghdr.msg_namelen = 0;
966 
967 	iov.iov_base = &x;
968 	iov.iov_len = 1;
969 	msghdr.msg_iov = &iov;
970 	msghdr.msg_iovlen = 1;
971 
972 	msghdr.msg_control = buf;
973 	msghdr.msg_controllen = CMSG_SPACE(sizeof(int));
974 
975 	msghdr.msg_flags = 0;
976 
977 	cmsg = CMSG_FIRSTHDR(&msghdr);
978 	cmsg->cmsg_len = CMSG_SPACE(sizeof(int));
979 	cmsg->cmsg_level = SOL_SOCKET;
980 	cmsg->cmsg_type = SCM_RIGHTS;
981 
982 	((int *) CMSG_DATA(cmsg))[0] = fd;
983 
984 	rc = sendmsg(sd, &msghdr, 0);
985 	if (rc == -1) {
986 		test_fail("could not send message");
987 	}
988 
989 	memset(buf, '\0', BUFSIZE);
990 	rc = read(sd, buf, BUFSIZE);
991 	if (rc == -1) {
992 		test_fail("could not read from socket");
993 	}
994 
995 	if (strcmp(buf, "done") != 0) {
996 		test_fail("we didn't read the right message");
997 	}
998 
999 	memset(buf, '\0', BUFSIZE);
1000 	rc = lseek(fd, 0, SEEK_SET);
1001 	if (rc == -1) {
1002 		test_fail("could not seek to start of test.txt");
1003 	}
1004 
1005 	rc = read(fd, buf, BUFSIZE);
1006 	if (rc == -1) {
1007 		test_fail("could not read from test.txt");
1008 	}
1009 
1010 	if (strcmp(buf, MSG) != 0) {
1011 		test_fail("other process didn't write MSG to test.txt");
1012 	}
1013 
1014 	rc = close(fd);
1015 	if (rc == -1) {
1016 		test_fail("could not close test.txt");
1017 	}
1018 
1019 	rc = close(sd);
1020 	if (rc == -1) {
1021 		test_fail("could not close socket");
1022 	}
1023 
1024 	rc = unlink(TEST_TXT_FILE);
1025 	if (rc == -1) {
1026 		test_fail("could not unlink test.txt");
1027 	}
1028 
1029 	exit(errct);
1030 }
1031 
1032 static void test_fd_passing_parent(int sd)
1033 {
1034 	int rc, fd;
1035 	char x;
1036 	struct msghdr msghdr;
1037 	struct cmsghdr *cmsg;
1038 	struct iovec iov;
1039 	char buf[BUFSIZE];
1040 
1041 	memset(buf, '\0', BUFSIZE);
1042 
1043 	msghdr.msg_name = NULL;
1044 	msghdr.msg_namelen = 0;
1045 
1046 	iov.iov_base = &x;
1047 	iov.iov_len = 1;
1048 	msghdr.msg_iov = &iov;
1049 	msghdr.msg_iovlen = 1;
1050 
1051 	msghdr.msg_iov = &iov;
1052 	msghdr.msg_iovlen = 1;
1053 
1054 	msghdr.msg_control = buf;
1055 	msghdr.msg_controllen = BUFSIZE;
1056 
1057 	msghdr.msg_flags = 0;
1058 
1059 	rc = recvmsg(sd, &msghdr, 0);
1060 	if (rc == -1) {
1061 		test_fail("could not recv message.");
1062 	}
1063 
1064 	cmsg = CMSG_FIRSTHDR(&msghdr);
1065 	fd = ((int *) CMSG_DATA(cmsg))[0];
1066 
1067 	rc = write(fd, MSG, strlen(MSG));
1068 	if (rc != strlen(MSG)) {
1069 		test_fail("could not write the full message to test.txt");
1070 	}
1071 
1072 	rc = close(fd);
1073 	if (rc == -1) {
1074 		test_fail("could not close test.txt");
1075 	}
1076 
1077 	memset(buf, '\0', BUFSIZE);
1078 	strcpy(buf, "done");
1079 	rc = write(sd, buf, BUFSIZE);
1080 	if (rc == -1) {
1081 		test_fail("could not write to socket");
1082 	}
1083 
1084 	rc = close(sd);
1085 	if (rc == -1) {
1086 		test_fail("could not close socket");
1087 	}
1088 }
1089 
1090 static void test_permissions(void) {
1091 	/* Test bind and connect for permission verification
1092 	 *
1093 	 * After creating a UDS socket we change user credentials. At that
1094 	 * point we should not be allowed to bind or connect to the UDS socket
1095 	 */
1096 
1097 	pid_t pid;
1098 	int sd, rc, status;
1099 	struct sockaddr_un addr;
1100 
1101 	memset(&addr, '\0', sizeof(struct sockaddr_un));
1102 	addr.sun_family = AF_UNIX;
1103 	strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1104 
1105 	UNLINK(TEST_SUN_PATH);
1106 
1107 	pid = fork();
1108 	if (pid < 0) test_fail("unable to fork");
1109 	else if (pid == 0) {
1110 		SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1111 		if (setuid(999) != 0) test_fail("unable to chance uid");
1112 		rc = bind(sd, (struct sockaddr *) &addr,
1113 				 sizeof(struct sockaddr_un));
1114 		if (rc != -1) {
1115 			test_fail("bind() should not have worked");
1116 		}
1117 		exit(errct);
1118 	} else {
1119 		rc = waitpid(pid, &status, 0);
1120 		errct += WEXITSTATUS(status);
1121 	}
1122 
1123 	/* the signal handler is only used by the client, but we have to
1124 	 * install it now. if we don't the server may signal the client
1125 	 * before the handler is installed.
1126 	 */
1127 	debug("installing signal handler");
1128 	if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1129 		test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1130 	}
1131 
1132 	debug("signal handler installed");
1133 
1134 	server_ready = 0;
1135 
1136 	pid = fork();
1137 	if (pid < 0) test_fail("unable to fork");
1138 	else if (pid == 0) {
1139 		while (server_ready == 0) {
1140 			debug("[client] waiting for the server to signal");
1141 			sleep(1);
1142 		}
1143 		SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1144 		if (setuid(999) != 0) test_fail("unable to chance uid");
1145 		rc = connect(sd, (struct sockaddr *) &addr,
1146 						sizeof(struct sockaddr_un));
1147 		if (rc != -1)
1148 			test_fail("connect should not have worked");
1149 		exit(errct);
1150 	} else {
1151 		SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1152 		rc = bind(sd, (struct sockaddr *) &addr,
1153 				 sizeof(struct sockaddr_un));
1154 		if (rc == -1) {
1155 			test_fail("bind() should have worked");
1156 		}
1157 
1158 		rc = listen(sd, 8);
1159 		if (rc == -1) {
1160 			test_fail("listen(sd, 8) should have worked");
1161 		}
1162 		kill(pid, SIGUSR1);
1163 		sleep(1);
1164 		CLOSE(sd);
1165 
1166 		rc = waitpid(pid, &status, 0);
1167 		errct += WEXITSTATUS(status);
1168 	}
1169 
1170 	UNLINK(TEST_SUN_PATH);
1171 }
1172 
1173 static void test_fd_passing(void) {
1174 	int status;
1175 	int sv[2];
1176 	pid_t pid;
1177 	int rc;
1178 
1179 	rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
1180 	if (rc == -1) {
1181 		test_fail("socketpair failed");
1182 	}
1183 
1184 	pid = fork();
1185 	if (pid == -1) {
1186 		test_fail("fork() failed");
1187 
1188 		rc = close(sv[0]);
1189 		if (rc == -1) {
1190 			test_fail("could not close sv[0]");
1191 		}
1192 
1193 		rc = close(sv[1]);
1194 		if (rc == -1) {
1195 			test_fail("could not close sv[1]");
1196 		}
1197 
1198 		exit(0);
1199 	} else if (pid == 0) {
1200 		rc = close(sv[0]);
1201 		if (rc == -1) {
1202 			test_fail("could not close sv[0]");
1203 		}
1204 
1205 		test_fd_passing_child(sv[1]);
1206 		test_fail("should never get here");
1207 		exit(1);
1208 	} else {
1209 		rc = close(sv[1]);
1210 		if (rc == -1) {
1211 			test_fail("could not close sv[1]");
1212 		}
1213 
1214 		test_fd_passing_parent(sv[0]);
1215 
1216 		/* wait for client to exit */
1217 		do {
1218 			errno = 0;
1219 			rc = waitpid(pid, &status, 0);
1220 		} while (rc == -1 && errno == EINTR);
1221 
1222 		/* we use the exit status to get its error count */
1223 		errct += WEXITSTATUS(status);
1224 	}
1225 }
1226 
1227 static void test_select(void)
1228 {
1229 	int nfds = -1;
1230 	int socks[2];
1231 	fd_set readfds, writefds;
1232 	struct timeval tv;
1233 	int res = 0;
1234 	char buf[1];
1235 
1236 	FD_ZERO(&readfds);
1237 	FD_ZERO(&writefds);
1238 
1239 	tv.tv_sec = 2;
1240 	tv.tv_usec = 0;	/* 2 sec time out */
1241 
1242 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) {
1243 		test_fail("Can't open socket pair.");
1244 	}
1245 	FD_SET(socks[0], &readfds);
1246 	nfds = socks[0] + 1;
1247 
1248 	/* Close the write end of the socket to generate EOF on read end */
1249 	if ((res = shutdown(socks[1], SHUT_WR)) != 0) {
1250 		test_fail("shutdown failed\n");
1251 	}
1252 
1253 	res = select(nfds, &readfds, NULL, NULL, &tv);
1254 	if (res != 1) {
1255 		test_fail("select should've returned 1 ready fd\n");
1256 	}
1257 	if (!(FD_ISSET(socks[0], &readfds))) {
1258 		test_fail("The server didn't respond within 2 seconds");
1259 	}
1260 	/* Now try to read from empty, closed pipe */
1261 	if (read(socks[0], buf, sizeof(buf)) != 0) {
1262 		test_fail("reading from empty, closed pipe should return EOF");
1263 	}
1264 
1265 	close(socks[0]);
1266 
1267 	/* Try again the other way around: create a socketpair, close the
1268 	 * read end, and try to write. This should cause an EPIPE */
1269 
1270 	tv.tv_sec = 2;
1271 	tv.tv_usec = 0;	/* 2 sec time out */
1272 
1273 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) {
1274 		test_fail("Can't open socket pair.");
1275 	}
1276 	FD_SET(socks[1], &writefds);
1277 	nfds = socks[1] + 1;
1278 
1279 	/* kill the read end of the socket to generate EPIPE on write end */
1280 	if ((res = shutdown(socks[0], SHUT_RD)) != 0) {
1281 		test_fail("shutdown failed\n");
1282 	}
1283 
1284 	res = select(nfds, NULL, &writefds, NULL, &tv);
1285 	if (res != 1) {
1286 		test_fail("select should've returned 1 ready fd\n");
1287 	}
1288 	if (!(FD_ISSET(socks[1], &writefds))) {
1289 		test_fail("The server didn't respond within 2 seconds");
1290 	}
1291 
1292 	/* Now try to write to closed pipe */
1293 	errno = 0;
1294 	if ((res = write(socks[1], buf, sizeof(buf))) != -1) {
1295 		printf("write res = %d\n", res);
1296 		test_fail("writing to empty, closed pipe should fail");
1297 	}
1298 	if (errno != EPIPE) {
1299 		printf("errno = %d\n", errno);
1300 		test_fail("writing to closed pipe should return EPIPE\n");
1301 	}
1302 
1303 	close(socks[1]);
1304 }
1305 
1306 static void test_select_close(void)
1307 {
1308 	int res, socks[2];
1309 	fd_set readfds;
1310 	struct timeval tv;
1311 
1312 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) {
1313 		test_fail("Can't open socket pair.");
1314 	}
1315 
1316 	switch (fork()) {
1317 	case 0:
1318 		sleep(1);
1319 
1320 		exit(0);
1321 	case -1:
1322 		test_fail("Can't fork.");
1323 	default:
1324 		break;
1325 	}
1326 
1327 	close(socks[1]);
1328 
1329 	FD_ZERO(&readfds);
1330 	FD_SET(socks[0], &readfds);
1331 	tv.tv_sec = 2;
1332 	tv.tv_usec = 0;	/* 2 sec time out */
1333 
1334 	res = select(socks[0] + 1, &readfds, NULL, NULL, &tv);
1335 	if (res != 1) {
1336 		test_fail("select should've returned 1 ready fd\n");
1337 	}
1338 	if (!(FD_ISSET(socks[0], &readfds))) {
1339 		test_fail("The server didn't respond within 2 seconds");
1340 	}
1341 
1342 	wait(NULL);
1343 
1344 	close(socks[0]);
1345 }
1346 
1347 static void test_fchmod(void)
1348 {
1349 	int socks[2];
1350 	struct stat st1, st2;
1351 
1352 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) {
1353 		test_fail("Can't open socket pair.");
1354 	}
1355 
1356 	if (fstat(socks[0], &st1) < 0 || fstat(socks[1], &st2) < 0) {
1357 		test_fail("fstat failed.");
1358 	}
1359 
1360 	if ((st1.st_mode & (S_IRUSR|S_IWUSR)) == S_IRUSR &&
1361 		(st2.st_mode & (S_IRUSR|S_IWUSR)) == S_IWUSR) {
1362 		test_fail("fstat failed.");
1363 	}
1364 
1365 	if (fchmod(socks[0], S_IRUSR) < 0 ||
1366                     fstat(socks[0], &st1) < 0 ||
1367                     (st1.st_mode & (S_IRUSR|S_IWUSR)) != S_IRUSR) {
1368 		test_fail("fchmod/fstat mode set/check failed (1).");
1369 	}
1370 
1371 	if (fchmod(socks[1], S_IWUSR) < 0 || fstat(socks[1], &st2) < 0 ||
1372                     (st2.st_mode & (S_IRUSR|S_IWUSR)) != S_IWUSR) {
1373 		test_fail("fchmod/fstat mode set/check failed (2).");
1374 	}
1375 
1376 	close(socks[0]);
1377 	close(socks[1]);
1378 }
1379 
1380 int main(int argc, char *argv[])
1381 {
1382 	int i;
1383 	struct sockaddr_un clientaddr = {
1384 		.sun_family = AF_UNIX,
1385 		.sun_path = TEST_SUN_PATH,
1386 	};
1387 	struct sockaddr_un clientaddr2 = {
1388 		.sun_family = AF_UNIX,
1389 		.sun_path = TEST_SUN_PATHB,
1390 	};
1391 	struct sockaddr_un clientaddrsym = {
1392 		.sun_family = AF_UNIX,
1393 		.sun_path = TEST_SYM_A,
1394 	};
1395 	const struct socket_test_info info = {
1396 		.clientaddr               = (struct sockaddr *) &clientaddr,
1397 		.clientaddrlen            = sizeof(clientaddr),
1398 		.clientaddr2              = (struct sockaddr *) &clientaddr2,
1399 		.clientaddr2len           = sizeof(clientaddr2),
1400 		.clientaddrsym            = (struct sockaddr *) &clientaddrsym,
1401 		.clientaddrsymlen         = sizeof(clientaddrsym),
1402 		.domain                   = PF_UNIX,
1403 		.expected_rcvbuf          = PIPE_BUF,
1404 		.expected_sndbuf          = PIPE_BUF,
1405 		.serveraddr               = (struct sockaddr *) &clientaddr,
1406 		.serveraddrlen            = sizeof(clientaddr),
1407 		.serveraddr2              = (struct sockaddr *) &clientaddr2,
1408 		.serveraddr2len           = sizeof(clientaddr2),
1409 		.type                     = SOCK_STREAM,
1410 		.types                    = types,
1411 		.typecount                = 3,
1412 		.callback_check_sockaddr  = callback_check_sockaddr,
1413 		.callback_cleanup         = callback_cleanup,
1414 		.callback_xfer_prepclient = callback_xfer_prepclient,
1415 		.callback_xfer_peercred   = callback_xfer_peercred,
1416 	};
1417 
1418 	debug("entering main()");
1419 
1420 	start(56);
1421 
1422 	test_socket(&info);
1423 	test_bind(&info);
1424 	test_bind_unix();
1425 	test_listen(&info);
1426 	test_getsockname(&info);
1427 	test_header();
1428 	test_shutdown(&info);
1429 	test_close(&info);
1430 	test_permissions();
1431 	test_dup(&info);
1432 	test_dup2(&info);
1433 	test_socketpair();
1434 	test_shutdown(&info);
1435 	test_read(&info);
1436 	test_write(&info);
1437 	test_sockopts(&info);
1438 	test_ucred();
1439 	test_xfer(&info);
1440 
1441 	for (i = 0; i < 3; i++) {
1442 		test_simple_client_server(&info, types[i]);
1443 		if (types[i] != SOCK_DGRAM) test_vectorio(types[i]);
1444 		if (types[i] != SOCK_DGRAM) test_msg(types[i]);
1445 	}
1446 
1447 	test_abort_client_server(&info, 1);
1448 	test_abort_client_server(&info, 2);
1449 	test_msg_dgram(&info);
1450 	test_connect(&info);
1451 	test_multiproc_read();
1452 	test_multiproc_write();
1453 	test_scm_credentials();
1454 	test_fd_passing();
1455 	test_select();
1456 	test_select_close();
1457 	test_fchmod();
1458 	test_nonblock(&info);
1459 	test_connect_nb(&info);
1460 	test_intr(&info);
1461 	test_connect_close(&info);
1462 	test_listen_close(&info);
1463 	test_listen_close_nb(&info);
1464 
1465 	quit();
1466 
1467 	return -1;	/* we should never get here */
1468 }
1469