tests: print error locations verbosely
[minix.git] / test / test56.c
blob973e173bcfdac34525d9f70ac0e5795cee2baedb
1 /*
2 * Test Program for Unix Domain Sockets
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.
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().
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()
38 #define DEBUG 0
40 #include <ctype.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <signal.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <sys/socket.h>
48 #include <sys/stat.h>
49 #include <sys/time.h>
50 #include <sys/types.h>
51 #include <sys/uio.h>
52 #include <sys/un.h>
53 #include <sys/wait.h>
54 #include <time.h>
55 #include <unistd.h>
57 /* Maximum number of errors that we'll allow to occur before this test
58 * program gives us and quits.
60 #define MAX_ERROR 4
62 /* Use the common testing code instead of reinventing the wheel. */
63 #include "common.c"
65 /* path of the unix domain socket */
66 #define TEST_SUN_PATH "test.sock"
67 #define TEST_SUN_PATHB "testb.sock"
69 /* filenames for symlinks -- we link these to each other to test ELOOP .*/
70 #define TEST_SYM_A "test.a"
71 #define TEST_SYM_B "test.b"
73 /* text file and test phrase for testing file descriptor passing */
74 #define TEST_TXT_FILE "test.txt"
75 #define MSG "This raccoon loves to eat bugs.\n"
77 /* buffer for send/recv */
78 #define BUFSIZE (128)
80 #define ISO8601_FORMAT "%Y-%m-%dT%H:%M:%S"
82 /* socket types supported */
83 int types[3] = {SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM};
84 char sock_fullpath[PATH_MAX + 1];
87 /* timestamps for debug and error logs */
88 char *get_timestamp(void)
90 struct tm *tm;
91 time_t t;
92 size_t len;
93 char *s;
95 len = sizeof(char) * 32;
97 t = time(NULL);
98 if (t == -1) {
99 return NULL;
101 tm = gmtime(&t);
102 if (tm == NULL) {
103 return NULL;
106 s = (char *) malloc(len);
107 if (!s) {
108 perror("malloc");
109 return NULL;
111 memset(s, '\0', len);
113 strftime(s, len - 1, ISO8601_FORMAT, tm);
114 return s;
117 /* macro to display information about a failed test and increment the errct */
118 #define test_fail(msg) \
119 do { \
120 char *timestamp; \
121 timestamp = get_timestamp(); \
122 if (errct == 0) fprintf(stderr, "\n"); \
123 fprintf(stderr, "[ERROR][%s] (%s Line %d) %s [pid=%d:errno=%d:%s]\n", \
124 timestamp, __FILE__, __LINE__, msg, getpid(), \
125 errno, strerror(errno)); \
126 fflush(stderr); \
127 if (timestamp != NULL) { \
128 free(timestamp); \
129 timestamp = NULL; \
131 errct++; \
132 if (errct++ > MAX_ERROR) { \
133 printf("Too many errors; test aborted\n"); \
134 quit(); \
135 exit(1); \
137 } while (0)
139 /* Convert name to the full path of the socket. Assumes name is in cwd. */
140 char *fullpath(char *name)
142 char cwd[PATH_MAX + 1];
144 if (realpath(".", cwd) == NULL)
145 test_fail("Couldn't retrieve current working dir");
147 snprintf(sock_fullpath, PATH_MAX, "%s/%s", cwd, name);
149 return(sock_fullpath);
152 #if DEBUG == 1
153 /* macros to display debugging information */
154 #define debug(msg) \
155 do { \
156 char *timestamp; \
157 timestamp = get_timestamp(); \
158 fprintf(stdout,"[DEBUG][%s] (%s:%d) %s [pid=%d]\n", \
159 timestamp, __FILE__, __LINE__, msg, getpid()); \
160 fflush(stdout); \
161 if (timestamp != NULL) { \
162 free(timestamp); \
163 timestamp = NULL; \
165 } while (0)
166 #else
167 #define debug(msg) \
168 do { /* nothing */; } while (0)
169 #endif
171 #define SOCKET(sd,domain,type,protocol) \
172 do { \
173 errno = 0; \
174 sd = socket(domain, type, protocol); \
175 if (sd == -1) { \
176 test_fail("sd = socket(domain, type, protocol) failed");\
178 } while (0)
180 #define UNLINK(path) \
181 do { \
182 int rc; \
183 errno = 0; \
184 rc = unlink(path); \
185 if (rc == -1 && errno != ENOENT) { \
186 test_fail("unlink(path) failed"); \
188 } while(0)
190 #define SYMLINK(oldpath,newpath) \
191 do { \
192 int rc; \
193 errno = 0; \
194 rc = symlink(oldpath,newpath); \
195 if (rc == -1) { \
196 test_fail("symlink(oldpath,newpath) failed"); \
198 } while(0)
200 #define CLOSE(sd) \
201 do { \
202 int rc; \
203 errno = 0; \
204 rc = close(sd); \
205 if (rc == -1) { \
206 test_fail("close(sd) failed"); \
208 } while (0)
210 void test_socket(void)
212 struct stat statbuf, statbuf2;
213 int sd, sd2;
214 int rc;
215 int i;
217 debug("entering test_socket()");
219 debug("Test socket() with an unsupported address family");
221 errno = 0;
222 sd = socket(-1, SOCK_STREAM, 0);
223 if (!(sd == -1 && errno == EAFNOSUPPORT)) {
224 test_fail("socket");
225 if (sd != -1) {
226 CLOSE(sd);
230 debug("Test socket() with all available FDs open by this process");
232 for (i = 3; i < getdtablesize(); i++) {
233 rc = open("/dev/null", O_RDONLY);
234 if (rc == -1) {
235 test_fail("we couldn't open /dev/null for read");
239 errno = 0;
240 sd = socket(PF_UNIX, SOCK_STREAM, 0);
241 if (!(sd == -1 && errno == EMFILE)) {
242 test_fail("socket() call with all fds open should fail");
243 if (sd != -1) {
244 CLOSE(sd);
248 for (i = 3; i < getdtablesize(); i++) {
249 CLOSE(i);
252 debug("Test socket() with an mismatched protocol");
254 errno = 0;
255 sd = socket(PF_UNIX, SOCK_STREAM, 4);
256 if (!(sd == -1 && errno == EPROTONOSUPPORT)) {
257 test_fail("socket() should fail with errno = EPROTONOSUPPORT");
258 if (sd != -1) {
259 CLOSE(sd);
263 debug("Test socket() success");
266 * open 2 sockets at once and *then* close them.
267 * This will test that /dev/uds is cloning properly.
270 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
271 SOCKET(sd2, PF_UNIX, SOCK_STREAM, 0);
273 rc = fstat(sd, &statbuf);
274 if (rc == -1) {
275 test_fail("fstat failed on sd");
278 rc = fstat(sd2, &statbuf2);
279 if (rc == -1) {
280 test_fail("fstat failed on sd2");
284 if (statbuf.st_dev == statbuf2.st_dev) {
285 test_fail("/dev/uds isn't being cloned");
288 CLOSE(sd2);
289 CLOSE(sd);
291 debug("leaving test_socket()");
294 void test_header(void)
296 struct sockaddr_un sun;
297 debug("entering test_header()");
299 sun.sun_family = AF_UNIX;
300 sun.sun_path[0] = 'x';
301 sun.sun_path[1] = 'x';
302 sun.sun_path[2] = 'x';
303 sun.sun_path[3] = '\0';
305 if (SUN_LEN(&sun) != 4) {
306 test_fail("SUN_LEN(&sun) should be 4");
309 if (PF_UNIX != PF_LOCAL || PF_UNIX != PF_FILE || PF_UNIX != AF_UNIX) {
310 test_fail("PF_UNIX, PF_LOCAL, PF_FILE, and AF_UNIX");
314 void test_socketpair(void)
316 char buf[128];
317 struct sockaddr_un addr;
318 int socket_vector[2];
319 int rc;
320 int i;
322 debug("entering test_socketpair()");
324 UNLINK(TEST_SUN_PATH);
325 memset(&addr, '\0', sizeof(struct sockaddr_un));
326 addr.sun_family = AF_UNIX;
327 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
329 debug("Testing socketpair() success");
331 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector);
332 if (rc == -1) {
333 test_fail("socketpair() should have worked");
336 debug("Testing a simple read/write using sockets from socketpair()");
337 memset(buf, '\0', sizeof(buf));
339 strncpy(buf, "Howdy Partner", sizeof(buf) - 1);
341 rc = write(socket_vector[0], buf, sizeof(buf));
342 if (rc == -1) {
343 test_fail("write(sd, buf, sizeof(buf)) failed unexpectedly");
346 memset(buf, '\0', sizeof(buf));
348 rc = read(socket_vector[1], buf, sizeof(buf));
349 if (rc == -1) {
350 test_fail("read() failed unexpectedly");
353 if (strncmp(buf, "Howdy Partner", strlen("Howdy Partner")) != 0) {
354 test_fail("We did not read what we wrote");
357 CLOSE(socket_vector[0]);
358 CLOSE(socket_vector[1]);
360 debug("Test socketpair() with all FDs open by this process");
362 for (i = 3; i < getdtablesize(); i++) {
363 rc = open("/dev/null", O_RDONLY);
364 if (rc == -1) {
365 test_fail("we couldn't open /dev/null for read");
369 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector);
370 if (!(rc == -1 && errno == EMFILE)) {
371 test_fail("socketpair() should have failed with EMFILE");
374 for (i = 3; i < getdtablesize(); i++) {
375 CLOSE(i);
378 rc = socketpair(PF_UNIX, SOCK_STREAM, 4, socket_vector);
379 if (!(rc == -1 && errno == EPROTONOSUPPORT)) {
380 test_fail("socketpair() should have failed");
383 debug("leaving test_socketpair()");
386 void test_ucred(void)
388 struct ucred credentials;
389 socklen_t ucred_length;
390 uid_t euid = geteuid();
391 gid_t egid = getegid();
392 int sv[2];
393 int rc;
395 debug("Test credentials passing");
397 ucred_length = sizeof(struct ucred);
399 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
400 if (rc == -1) {
401 test_fail("socketpair(PF_UNIX, SOCK_STREAM, 0, sv) failed");
404 memset(&credentials, '\0', ucred_length);
405 rc = getsockopt(sv[0], SOL_SOCKET, SO_PEERCRED, &credentials,
406 &ucred_length);
407 if (rc == -1) {
408 test_fail("getsockopt(SO_PEERCRED) failed");
409 } else if (credentials.pid != getpid() ||
410 credentials.uid != geteuid() ||
411 credentials.gid != getegid()) {
412 /* printf("%d=%d %d=%d %d=%d",credentials.pid, getpid(),
413 credentials.uid, geteuid(), credentials.gid, getegid()); */
414 test_fail("Credential passing gave us the wrong cred");
417 rc = getpeereid(sv[0], &euid, &egid);
418 if (rc == -1) {
419 test_fail("getpeereid(sv[0], &euid, &egid) failed");
420 } else if (credentials.uid != euid || credentials.gid != egid) {
421 test_fail("getpeereid() didn't give the correct euid/egid");
424 CLOSE(sv[0]);
425 CLOSE(sv[1]);
428 void test_getsockname(void)
430 int sd;
431 int rc;
432 struct sockaddr_un addr, sock_addr;
433 socklen_t sock_addr_len;
435 memset(&addr, '\0', sizeof(struct sockaddr_un));
436 addr.sun_family = AF_UNIX;
437 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
439 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
440 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
441 if (rc == -1) {
442 test_fail("bind() should have worked");
445 debug("Test getsockname() success");
447 memset(&sock_addr, '\0', sizeof(struct sockaddr_un));
448 sock_addr_len = sizeof(struct sockaddr_un);
450 rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len);
451 if (rc == -1) {
452 test_fail("getsockname() should have worked");
455 if (!(sock_addr.sun_family == AF_UNIX && strncmp(sock_addr.sun_path,
456 fullpath(TEST_SUN_PATH),
457 sizeof(sock_addr.sun_path) - 1) == 0)) {
458 test_fail("getsockname() did return the right address");
459 fprintf(stderr, "exp: '%s' | got: '%s'\n", addr.sun_path,
460 sock_addr.sun_path);
463 CLOSE(sd);
466 void test_bind(void)
468 struct sockaddr_un addr;
469 struct sockaddr_un sock_addr;
470 socklen_t sock_addr_len;
471 int sd;
472 int sd2;
473 int rc;
475 debug("entering test_bind()");
476 UNLINK(TEST_SUN_PATH);
477 memset(&addr, '\0', sizeof(struct sockaddr_un));
478 addr.sun_family = AF_UNIX;
479 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
481 debug("Test bind() success");
483 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
484 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
485 if (rc == -1) {
486 test_fail("bind() should have worked");
489 debug("Test getsockname() success");
491 memset(&sock_addr, '\0', sizeof(struct sockaddr_un));
492 sock_addr_len = sizeof(struct sockaddr_un);
494 rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len);
495 if (rc == -1) {
496 test_fail("getsockname() should have worked");
499 if (!(sock_addr.sun_family == AF_UNIX &&
500 strncmp(sock_addr.sun_path,
501 fullpath(TEST_SUN_PATH),
502 sizeof(sock_addr.sun_path) - 1) == 0)) {
504 test_fail("getsockname() didn't return the right addr");
505 fprintf(stderr, "exp: '%s' | got: '%s'\n", addr.sun_path,
506 sock_addr.sun_path);
509 debug("Test bind() with a address that has already been bind()'d");
511 SOCKET(sd2, PF_UNIX, SOCK_STREAM, 0);
512 errno = 0;
513 rc = bind(sd2, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
514 if (!((rc == -1) && (errno == EADDRINUSE))) {
515 test_fail("bind() should have failed with EADDRINUSE");
517 CLOSE(sd2);
518 CLOSE(sd);
519 UNLINK(TEST_SUN_PATH);
521 debug("Test bind() with an empty sun_path");
523 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
524 memset(addr.sun_path, '\0', sizeof(addr.sun_path));
525 errno = 0;
527 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
528 if (!(rc == -1 && errno == ENOENT)) {
529 test_fail("bind() should have failed with ENOENT");
531 CLOSE(sd);
533 debug("Test bind() with a NULL address");
535 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
536 errno = 0;
537 rc = bind(sd, (struct sockaddr *) NULL, sizeof(struct sockaddr_un));
538 if (!((rc == -1) && (errno == EFAULT))) {
539 test_fail("bind() should have failed with EFAULT");
541 CLOSE(sd);
543 debug("Test bind() using a symlink loop");
545 UNLINK(TEST_SUN_PATH);
546 UNLINK(TEST_SYM_A);
547 UNLINK(TEST_SYM_B);
549 SYMLINK(TEST_SYM_A, TEST_SYM_B);
550 SYMLINK(TEST_SYM_B, TEST_SYM_A);
552 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
554 strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1);
555 errno = 0;
556 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
557 if (!((rc == -1) && (errno == ELOOP))) {
558 test_fail("bind() should have failed with ELOOP");
560 CLOSE(sd);
562 UNLINK(TEST_SUN_PATH);
563 UNLINK(TEST_SYM_A);
564 UNLINK(TEST_SYM_B);
566 debug("leaving test_bind()");
569 void test_listen(void)
571 int rc;
573 debug("entering test_listen()");
575 debug("Test listen() with a bad file descriptor");
577 errno = 0;
578 rc = listen(-1, 0);
579 if (!(rc == -1 && errno == EBADF)) {
580 test_fail("listen(-1, 0) should have failed");
583 debug("Test listen() with a non-socket file descriptor");
585 errno = 0;
586 rc = listen(0, 0);
587 if (!(rc == -1 && errno == ENOTTY)) {
588 test_fail("listen(0, 0) should have failed");
591 debug("leaving test_listen()");
594 void test_shutdown(void)
596 int how[3] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
597 int sd;
598 int rc;
599 int i;
601 debug("entering test_shutdown()");
603 /* test for each direction (read, write, read-write) */
604 for (i = 0; i < 3; i++) {
606 debug("test shutdown() with an invalid descriptor");
608 errno = 0;
609 rc = shutdown(-1, how[i]);
610 if (!(rc == -1 && errno == EBADF)) {
611 test_fail("shutdown(-1, how[i]) should have failed");
614 debug("test shutdown() with a non-socket descriptor");
616 errno = 0;
617 rc = shutdown(0, how[i]);
618 if (!(rc == -1 && errno == ENOSYS)) {
619 test_fail("shutdown() should have failed with ENOSYS");
622 debug("test shutdown() with a socket that is not connected");
624 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
625 errno = 0;
626 rc = shutdown(sd, how[i]);
627 if (!(rc == -1 && errno == ENOTCONN)) {
628 test_fail("shutdown() should have failed");
630 CLOSE(sd);
633 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
634 errno = 0;
635 rc = shutdown(sd, -1);
636 if (!(rc == -1 && errno == ENOTCONN)) {
637 test_fail("shutdown(sd, -1) should have failed with ENOTCONN");
639 CLOSE(sd);
641 debug("leaving test_shutdown()");
644 void test_close(void)
646 struct sockaddr_un addr;
647 int sd, sd2;
648 int rc, i;
650 debug("entering test_close()");
652 UNLINK(TEST_SUN_PATH);
654 memset(&addr, '\0', sizeof(struct sockaddr_un));
655 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
656 addr.sun_family = AF_UNIX;
658 debug("Test close() success");
660 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
661 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
662 if (rc != 0) {
663 test_fail("bind() should have worked");
666 CLOSE(sd);
668 debug("Close an already closed file descriptor");
670 errno = 0;
671 rc = close(sd);
672 if (!(rc == -1 && errno == EBADF)) {
673 test_fail("close(sd) should have failed with EBADF");
676 UNLINK(TEST_SUN_PATH);
678 debug("dup()'ing a file descriptor and closing both should work");
680 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
681 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
682 if (rc != 0) {
683 test_fail("bind() should have worked");
686 errno = 0;
687 sd2 = dup(sd);
688 if (sd2 == -1) {
689 test_fail("dup(sd) should have worked");
690 } else {
691 CLOSE(sd2);
692 CLOSE(sd);
695 UNLINK(TEST_SUN_PATH);
697 /* Create and close a socket a bunch of times.
698 * If the implementation doesn't properly free the
699 * socket during close(), eventually socket() will
700 * fail when the internal descriptor table is full.
702 for (i = 0; i < 1024; i++) {
703 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
704 CLOSE(sd);
707 debug("leaving test_close()");
710 void test_sockopts(void)
712 int i;
713 int rc;
714 int sd;
715 int option_value;
716 socklen_t option_len;
718 debug("entering test_sockopts()");
720 for (i = 0; i < 3; i++) {
722 SOCKET(sd, PF_UNIX, types[i], 0);
724 debug("Test setsockopt() works");
726 option_value = 0;
727 option_len = sizeof(option_value);
728 errno = 0;
729 rc = getsockopt(sd, SOL_SOCKET, SO_TYPE, &option_value,
730 &option_len);
731 if (rc != 0) {
732 test_fail("setsockopt() should have worked");
735 if (option_value != types[i]) {
736 test_fail("SO_TYPE didn't seem to work.");
739 CLOSE(sd);
744 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
746 debug("Test setsockopt() works");
748 option_value = 0;
749 option_len = sizeof(option_value);
750 errno = 0;
751 rc = getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &option_value, &option_len);
752 if (rc != 0) {
753 test_fail("getsockopt() should have worked");
756 if (option_value != PIPE_BUF) {
757 test_fail("SO_SNDBUF didn't seem to work.");
760 CLOSE(sd);
763 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
765 debug("Test setsockopt() works");
767 option_value = 0;
768 option_len = sizeof(option_value);
769 errno = 0;
770 rc = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &option_value, &option_len);
771 if (rc != 0) {
772 test_fail("getsockopt() should have worked");
775 if (option_value != PIPE_BUF) {
776 test_fail("SO_RCVBUF didn't seem to work.");
779 CLOSE(sd);
782 debug("leaving test_sockopts()");
785 void test_read(void)
787 int rc;
788 int fd;
789 char buf[BUFSIZE];
791 debug("entering test_read()");
793 errno = 0;
794 rc = read(-1, buf, sizeof(buf));
795 if (!(rc == -1 && errno == EBADF)) {
796 test_fail("read() should have failed with EBADF");
799 fd = open("/tmp", O_RDONLY);
800 if (fd == -1) {
801 test_fail("open(\"/tmp\", O_RDONLY) should have worked");
804 CLOSE(fd);
806 debug("leaving test_read()");
809 void test_write(void)
811 int rc;
812 char buf[BUFSIZE];
814 debug("entering test_write()");
816 errno = 0;
817 rc = write(-1, buf, sizeof(buf));
818 if (!(rc == -1 && errno == EBADF)) {
819 test_fail("write() should have failed with EBADF");
822 debug("leaving test_write()");
825 void test_dup(void)
827 struct stat info1;
828 struct stat info2;
829 struct sockaddr_un addr;
830 int sd, sd2;
831 int rc;
832 int i;
834 debug("entering test_dup()");
836 UNLINK(TEST_SUN_PATH);
838 memset(&addr, '\0', sizeof(struct sockaddr_un));
839 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
840 addr.sun_family = AF_UNIX;
842 debug("Test dup()");
844 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
845 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
846 if (rc != 0) {
847 test_fail("bind() should have worked");
850 errno = 0;
851 sd2 = dup(sd);
852 if (sd2 == -1) {
853 test_fail("dup(sd) should have worked");
856 rc = fstat(sd, &info1);
857 if (rc == -1) {
858 test_fail("fstat(fd, &info1) failed");
861 rc = fstat(sd2, &info2);
862 if (rc == -1) {
863 test_fail("fstat(sd, &info2) failed");
866 if (info1.st_ino != info2.st_ino) {
867 test_fail("dup() failed info1.st_ino != info2.st_ino");
870 CLOSE(sd);
871 CLOSE(sd2);
873 debug("Test dup() with a closed socket");
875 errno = 0;
876 rc = dup(sd);
877 if (!(rc == -1 && errno == EBADF)) {
878 test_fail("dup(sd) on a closed socket shouldn't have worked");
881 debug("Test dup() with socket descriptor of -1");
883 errno = 0;
884 rc = dup(-1);
885 if (!(rc == -1 && errno == EBADF)) {
886 test_fail("dup(-1) shouldn't have worked");
889 debug("Test dup() when all of the file descriptors are taken");
891 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
893 for (i = 4; i < getdtablesize(); i++) {
894 rc = open("/dev/null", O_RDONLY);
895 if (rc == -1) {
896 test_fail("we couldn't open /dev/null for read");
900 errno = 0;
901 sd2 = dup(sd);
902 if (!(sd2 == -1 && errno == EMFILE)) {
903 test_fail("dup(sd) should have failed with errno = EMFILE");
906 for (i = 3; i < getdtablesize(); i++) {
907 CLOSE(i);
910 UNLINK(TEST_SUN_PATH);
912 debug("leaving test_dup()");
915 void test_dup2(void)
917 struct stat info1;
918 struct stat info2;
919 struct sockaddr_un addr;
920 int sd;
921 int fd;
922 int rc;
924 debug("entering test_dup2()");
925 UNLINK(TEST_SUN_PATH);
927 memset(&addr, '\0', sizeof(struct sockaddr_un));
928 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
929 addr.sun_family = AF_UNIX;
931 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
933 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
934 if (rc != 0) {
935 test_fail("bind() should have worked");
938 fd = open("/dev/null", O_RDONLY);
939 if (fd == -1) {
940 test_fail("open(\"/dev/null\", O_RDONLY) failed");
943 fd = dup2(sd, fd);
944 if (fd == -1) {
945 test_fail("dup2(sd, fd) failed.");
948 memset(&info1, '\0', sizeof(struct stat));
949 memset(&info2, '\0', sizeof(struct stat));
951 rc = fstat(fd, &info1);
952 if (rc == -1) {
953 test_fail("fstat(fd, &info1) failed");
956 rc = fstat(sd, &info2);
957 if (rc == -1) {
958 test_fail("fstat(sd, &info2) failed");
961 if (!(info1.st_ino == info2.st_ino &&
962 major(info1.st_dev) == major(info2.st_dev) &&
963 minor(info1.st_dev) == minor(info2.st_dev))) {
965 test_fail("dup2() failed");
968 CLOSE(fd);
969 CLOSE(sd);
971 UNLINK(TEST_SUN_PATH);
972 debug("leaving test_dup2()");
977 * A toupper() server. This toy server converts a string to upper case.
979 void test_xfer_server(pid_t pid)
981 int i;
982 struct timeval tv;
983 fd_set readfds;
984 int status;
985 int rc;
986 int sd;
987 char buf[BUFSIZE];
988 socklen_t client_addr_size;
989 int client_sd;
990 struct sockaddr_un addr;
991 struct sockaddr_un client_addr;
993 status = 0;
994 rc = 0;
995 sd = 0;
996 client_sd = 0;
997 client_addr_size = sizeof(struct sockaddr_un);
999 memset(&buf, '\0', sizeof(buf));
1000 memset(&addr, '\0', sizeof(struct sockaddr_un));
1001 memset(&client_addr, '\0', sizeof(struct sockaddr_un));
1003 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1004 addr.sun_family = AF_UNIX;
1006 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1008 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
1009 if (rc == -1) {
1010 test_fail("bind() should have worked");
1013 rc = listen(sd, 8);
1014 if (rc == -1) {
1015 test_fail("listen(sd, 8) should have worked");
1018 /* we're ready for connections, time to tell the client to start
1019 * the test
1021 kill(pid, SIGUSR1);
1023 tv.tv_sec = 10;
1024 tv.tv_usec = 0;
1026 FD_ZERO(&readfds);
1027 FD_SET(sd, &readfds);
1029 /* use select() in case the client is really broken and never
1030 * attempts to connect (we don't want to block on accept()
1031 * forever).
1033 rc = select(sd + 1, &readfds, NULL, NULL, &tv);
1034 if (rc == -1) {
1035 test_fail("[server] select() should not have failed");
1038 if (rc != 1) {
1039 test_fail("[server] select() should have returned 1");
1040 printf("[server] select returned %d\n", rc);
1043 if (!(FD_ISSET(sd, &readfds))) {
1044 test_fail("[server] client didn't connect within 10 seconds");
1045 kill(pid, SIGKILL);
1046 return;
1049 client_sd = accept(sd, (struct sockaddr *) &client_addr,
1050 &client_addr_size);
1052 if (client_sd == -1) {
1053 test_fail("accept() should have worked");
1054 kill(pid, SIGKILL);
1055 return;
1056 } else {
1057 debug("[server] client accept()'d");
1060 debug("[server] Reading message");
1061 rc = read(client_sd, buf, sizeof(buf));
1062 if (rc == -1) {
1063 test_fail("read() failed unexpectedly");
1064 kill(pid, SIGKILL);
1065 return;
1067 debug("[server] we got the following message:");
1068 debug(buf);
1070 for (i = 0; i < rc && i < 127; i++) {
1071 buf[i] = toupper(buf[i]);
1074 debug("[server] Writing message...");
1075 rc = write(client_sd, buf, sizeof(buf));
1076 if (rc == -1) {
1077 test_fail("write(client_sd, buf, sizeof(buf)) failed");
1078 kill(pid, SIGKILL);
1079 return;
1082 if (rc < strlen(buf)) {
1083 test_fail("[server] write didn't write all the bytes");
1086 memset(&buf, '\0', sizeof(buf));
1088 debug("[server] Recv message");
1089 rc = recv(client_sd, buf, sizeof(buf), 0);
1090 if (rc == -1) {
1091 test_fail("recv() failed unexpectedly");
1092 kill(pid, SIGKILL);
1093 return;
1095 debug("[server] we got the following message:");
1096 debug(buf);
1098 for (i = 0; i < rc && i < 127; i++) {
1099 buf[i] = toupper(buf[i]);
1102 debug("[server] Sending message...");
1103 rc = send(client_sd, buf, sizeof(buf), 0);
1104 if (rc == -1) {
1105 test_fail("send(client_sd, buf, sizeof(buf), 0) failed");
1106 kill(pid, SIGKILL);
1107 return;
1110 if (rc < strlen(buf)) {
1111 test_fail("[server] write didn't write all the bytes");
1114 memset(&buf, '\0', sizeof(buf));
1116 debug("[server] Recvfrom message");
1117 rc = recvfrom(client_sd, buf, sizeof(buf), 0, NULL, 0);
1118 if (rc == -1) {
1119 test_fail("recvfrom() failed unexpectedly");
1120 kill(pid, SIGKILL);
1121 return;
1123 debug("[server] we got the following message:");
1124 debug(buf);
1126 for (i = 0; i < rc && i < 127; i++) {
1127 buf[i] = toupper(buf[i]);
1130 debug("[server] Sendto message...");
1131 rc = sendto(client_sd, buf, sizeof(buf), 0, NULL, 0);
1132 if (rc == -1) {
1133 test_fail("sendto() failed");
1134 kill(pid, SIGKILL);
1135 return;
1138 if (rc < strlen(buf)) {
1139 test_fail("[server] write didn't write all the bytes");
1142 shutdown(client_sd, SHUT_RDWR);
1143 CLOSE(client_sd);
1145 shutdown(sd, SHUT_RDWR);
1146 CLOSE(sd);
1148 /* wait for client to exit */
1149 do {
1150 errno = 0;
1151 rc = waitpid(pid, &status, 0);
1152 } while (rc == -1 && errno == EINTR);
1154 /* we use the exit status to get its error count */
1155 errct += WEXITSTATUS(status);
1158 int server_ready = 0;
1160 /* signal handler for the client */
1161 void test_xfer_sighdlr(int sig)
1163 debug("entering signal handler");
1164 switch (sig) {
1165 /* the server will send SIGUSR1 when it is time for us
1166 * to start the tests
1168 case SIGUSR1:
1169 server_ready = 1;
1170 debug("got SIGUSR1, the server is ready for the client");
1171 break;
1172 default:
1173 debug("didn't get SIGUSR1");
1175 debug("leaving signal handler");
1179 * A toupper() client.
1181 void test_xfer_client(void)
1183 struct ucred credentials;
1184 socklen_t ucred_length;
1185 struct timeval tv;
1186 fd_set readfds;
1187 struct sockaddr_un addr;
1188 struct sockaddr_un peer_addr;
1189 socklen_t peer_addr_len;
1190 int sd;
1191 int rc;
1192 char buf[BUFSIZE];
1194 debug("[client] entering test_xfer_client()");
1195 errct = 0; /* reset error count */
1196 ucred_length = sizeof(struct ucred);
1197 memset(&buf, '\0', sizeof(buf));
1199 while (server_ready == 0) {
1200 debug("[client] waiting for the server to signal");
1201 sleep(1);
1204 peer_addr_len = sizeof(struct sockaddr_un);
1207 debug("Creating symlink to TEST_SUN_PATH");
1209 SYMLINK(TEST_SUN_PATH, TEST_SYM_A);
1211 memset(&addr, '\0', sizeof(struct sockaddr_un));
1212 strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1);
1213 addr.sun_family = AF_UNIX;
1215 debug("[client] creating client socket");
1216 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1218 debug("[client] connecting to server through the symlink");
1219 rc = connect(sd, (struct sockaddr *) &addr,
1220 sizeof(struct sockaddr_un));
1221 if (rc == -1) {
1222 test_fail("[client] connect() should have worked");
1223 } else {
1224 debug("[client] connected");
1227 debug("[client] testing getpeername()");
1228 memset(&peer_addr, '\0', sizeof(struct sockaddr_un));
1229 rc = getpeername(sd, (struct sockaddr *) &peer_addr, &peer_addr_len);
1230 if (rc == -1) {
1231 test_fail("[client] getpeername() should have worked");
1234 /* we need to use the full path "/usr/src/test/DIR_56/test.sock"
1235 * because that is what is returned by getpeername().
1238 if (!(peer_addr.sun_family == AF_UNIX &&
1239 strncmp(peer_addr.sun_path,
1240 fullpath(TEST_SUN_PATH),
1241 sizeof(peer_addr.sun_path) - 1) == 0)) {
1243 test_fail("getpeername() didn't return the right address");
1246 strncpy(buf, "Hello, World!", sizeof(buf) - 1);
1247 debug("[client] send to server");
1248 rc = write(sd, buf, sizeof(buf));
1249 if (rc == -1) {
1250 test_fail("[client] write() failed unexpectedly");
1253 memset(buf, '\0', sizeof(buf));
1254 debug("[client] read from server");
1255 rc = read(sd, buf, sizeof(buf));
1256 if (rc == -1) {
1257 test_fail("[client] read() failed unexpectedly");
1258 } else {
1259 debug("[client] we got the following message:");
1260 debug(buf);
1263 if (strncmp(buf, "HELLO, WORLD!", sizeof(buf)) != 0) {
1264 test_fail("[client] We didn't get the correct response");
1267 memset(&buf, '\0', sizeof(buf));
1268 strncpy(buf, "Bonjour!", sizeof(buf) - 1);
1270 debug("[client] send to server");
1271 rc = send(sd, buf, sizeof(buf), 0);
1272 if (rc == -1) {
1273 test_fail("[client] send() failed unexpectedly");
1276 debug("Test passing the client credentials to the server");
1278 memset(&credentials, '\0', ucred_length);
1279 rc = getsockopt(sd, SOL_SOCKET, SO_PEERCRED, &credentials,
1280 &ucred_length);
1282 if (rc == -1) {
1283 test_fail("[client] getsockopt() failed");
1284 } else if (credentials.uid != geteuid() ||
1285 credentials.gid != getegid()) {
1286 printf("%d=%d=%d %d=%d=%d\n", credentials.uid, getuid(),
1287 geteuid(), credentials.gid, getgid(), getegid());
1288 test_fail("[client] Credential passing gave us a bad UID/GID");
1291 debug("Testing select()");
1293 tv.tv_sec = 2;
1294 tv.tv_usec = 500000;
1296 FD_ZERO(&readfds);
1297 FD_SET(sd, &readfds);
1299 rc = select(sd + 1, &readfds, NULL, NULL, &tv);
1300 if (rc == -1) {
1301 test_fail("[client] select() should not have failed");
1304 if (rc != 1) {
1305 test_fail("[client] select() should have returned 1");
1308 if (!(FD_ISSET(sd, &readfds))) {
1309 test_fail("The server didn't respond within 2.5 seconds");
1312 memset(buf, '\0', sizeof(buf));
1313 debug("[client] recv from server");
1314 rc = recv(sd, buf, sizeof(buf), 0);
1315 if (rc == -1) {
1316 test_fail("[client] recv() failed unexpectedly");
1317 } else {
1318 debug("[client] we got the following message:");
1319 debug(buf);
1322 if (strncmp(buf, "BONJOUR!", sizeof(buf)) != 0) {
1323 test_fail("[client] We didn't get the right response.");
1326 memset(&buf, '\0', sizeof(buf));
1327 strncpy(buf, "Hola!", sizeof(buf) - 1);
1329 debug("[client] sendto to server");
1330 rc = sendto(sd, buf, sizeof(buf), 0, NULL, 0);
1331 if (rc == -1) {
1332 test_fail("[client] sendto() failed");
1335 debug("Testing select()");
1337 tv.tv_sec = 2;
1338 tv.tv_usec = 500000;
1340 FD_ZERO(&readfds);
1341 FD_SET(sd, &readfds);
1343 rc = select(sd + 1, &readfds, NULL, NULL, &tv);
1344 if (rc == -1) {
1345 test_fail("[client] select() should not have failed");
1348 if (rc != 1) {
1349 test_fail("[client] select() should have returned 1");
1352 if (!(FD_ISSET(sd, &readfds))) {
1353 test_fail("[client] The server didn't respond in 2.5 seconds");
1356 memset(buf, '\0', sizeof(buf));
1357 debug("[client] recvfrom from server");
1358 rc = recvfrom(sd, buf, sizeof(buf), 0, NULL, 0);
1359 if (rc == -1) {
1360 test_fail("[cleint] recvfrom() failed unexpectedly");
1361 } else {
1362 debug("[client] we got the following message:");
1363 debug(buf);
1366 if (strncmp(buf, "HOLA!", sizeof(buf)) != 0) {
1367 test_fail("[client] We didn't get the right response.");
1370 debug("[client] closing socket");
1371 CLOSE(sd);
1373 debug("[client] leaving test_xfer_client()");
1374 exit(errct);
1377 void test_xfer(void)
1379 pid_t pid;
1381 UNLINK(TEST_SYM_A);
1382 UNLINK(TEST_SUN_PATH);
1384 /* the signal handler is only used by the client, but we have to
1385 * install it now. if we don't the server may signal the client
1386 * before the handler is installed.
1388 debug("installing signal handler");
1389 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1390 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1393 debug("signal handler installed");
1395 server_ready = 0;
1397 pid = fork();
1398 if (pid == -1) {
1399 test_fail("fork() failed");
1400 return;
1401 } else if (pid == 0) {
1402 debug("child");
1403 test_xfer_client();
1404 test_fail("we should never get here");
1405 exit(1);
1406 } else {
1407 debug("parent");
1408 test_xfer_server(pid);
1409 debug("parent done");
1412 UNLINK(TEST_SYM_A);
1413 UNLINK(TEST_SUN_PATH);
1416 void test_simple_client(int type)
1418 char buf[BUFSIZE];
1419 int sd, rc;
1420 struct sockaddr_un addr;
1422 sd = socket(PF_UNIX, type, 0);
1423 if (sd == -1) {
1424 test_fail("socket");
1425 exit(errct);
1428 while (server_ready == 0) {
1429 debug("[client] waiting for the server");
1430 sleep(1);
1433 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1434 addr.sun_family = AF_UNIX;
1436 bzero(buf, BUFSIZE);
1437 snprintf(buf, BUFSIZE-1, "Hello, My Name is Client.");
1439 if (type == SOCK_DGRAM) {
1441 rc = sendto(sd, buf, strlen(buf) + 1, 0,
1442 (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
1443 if (rc == -1) {
1444 test_fail("sendto");
1445 exit(errct);
1448 } else {
1450 rc = connect(sd, (struct sockaddr *) &addr,
1451 sizeof(struct sockaddr_un));
1452 if (rc == -1) {
1453 test_fail("connect");
1454 exit(errct);
1457 rc = write(sd, buf, strlen(buf) + 1);
1458 if (rc == -1) {
1459 test_fail("write");
1462 memset(buf, '\0', BUFSIZE);
1463 rc = read(sd, buf, BUFSIZE);
1464 if (rc == -1) {
1465 test_fail("read");
1468 if (strcmp("Hello, My Name is Server.", buf) != 0) {
1469 test_fail("didn't read the correct string");
1473 rc = close(sd);
1474 if (rc == -1) {
1475 test_fail("close");
1478 exit(errct);
1481 void test_simple_server(int type, pid_t pid)
1483 char buf[BUFSIZE];
1484 int sd, rc, client_sd, status;
1485 struct sockaddr_un addr;
1486 socklen_t addr_len;
1488 addr_len = sizeof(struct sockaddr_un);
1490 sd = socket(PF_UNIX, type, 0);
1491 if (sd == -1) {
1492 test_fail("socket");
1495 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1496 addr.sun_family = AF_UNIX;
1498 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
1499 if (rc == -1) {
1500 test_fail("bind");
1503 if (type == SOCK_DGRAM) {
1505 /* ready for client */
1506 kill(pid, SIGUSR1);
1508 rc = recvfrom(sd, buf, BUFSIZE, 0,
1509 (struct sockaddr *) &addr, &addr_len);
1510 if (rc == -1) {
1511 test_fail("recvfrom");
1514 } else {
1516 rc = listen(sd, 5);
1517 if (rc == -1) {
1518 test_fail("listen");
1521 /* we're ready for connections, time to tell the client
1522 * to start the test
1524 kill(pid, SIGUSR1);
1526 client_sd = accept(sd, (struct sockaddr *) &addr, &addr_len);
1527 if (client_sd == -1) {
1528 test_fail("accept");
1531 memset(buf, '\0', BUFSIZE);
1532 rc = read(client_sd, buf, BUFSIZE);
1533 if (rc == -1) {
1534 test_fail("read");
1537 if (strcmp("Hello, My Name is Client.", buf) != 0) {
1538 test_fail("didn't read the correct string");
1541 /* added for extra fun to make the client block on read() */
1542 sleep(1);
1544 bzero(buf, BUFSIZE);
1545 snprintf(buf, BUFSIZE-1, "Hello, My Name is Server.");
1547 rc = write(client_sd, buf, strlen(buf) + 1);
1548 if (rc == -1) {
1549 test_fail("write");
1552 rc = close(client_sd);
1553 if (rc == -1) {
1554 test_fail("close");
1559 rc = close(sd);
1560 if (rc == -1) {
1561 test_fail("close");
1564 /* wait for client to exit */
1565 do {
1566 errno = 0;
1567 rc = waitpid(pid, &status, 0);
1568 } while (rc == -1 && errno == EINTR);
1570 /* we use the exit status to get its error count */
1571 errct += WEXITSTATUS(status);
1574 void test_simple_client_server(int type)
1576 pid_t pid;
1578 debug("test_simple_client_server()");
1580 UNLINK(TEST_SUN_PATH);
1582 /* the signal handler is only used by the client, but we have to
1583 * install it now. if we don't the server may signal the client
1584 * before the handler is installed.
1586 debug("installing signal handler");
1587 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1588 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1591 debug("signal handler installed");
1593 server_ready = 0;
1595 pid = fork();
1596 if (pid == -1) {
1597 test_fail("fork() failed");
1598 return;
1599 } else if (pid == 0) {
1600 debug("child");
1601 test_simple_client(type);
1602 test_fail("we should never get here");
1603 exit(1);
1604 } else {
1605 debug("parent");
1606 test_simple_server(type, pid);
1607 debug("parent done");
1610 UNLINK(TEST_SUN_PATH);
1613 void test_vectorio(int type)
1615 int sv[2];
1616 int rc;
1617 struct iovec iov[3];
1618 char buf1[BUFSIZE];
1619 char buf2[BUFSIZE];
1620 char buf3[BUFSIZE];
1621 char buf4[BUFSIZE*3];
1622 const struct iovec *iovp = iov;
1624 debug("begin vectorio tests");
1626 memset(buf1, '\0', BUFSIZE);
1627 strncpy(buf1, "HELLO ", BUFSIZE - 1);
1629 memset(buf2, '\0', BUFSIZE);
1630 strncpy(buf2, "WORLD", BUFSIZE - 1);
1632 memset(buf3, '\0', BUFSIZE);
1634 rc = socketpair(PF_UNIX, type, 0, sv);
1635 if (rc == -1) {
1636 test_fail("socketpair");
1639 iov[0].iov_base = buf1;
1640 iov[0].iov_len = strlen(buf1);
1641 iov[1].iov_base = buf2;
1642 iov[1].iov_len = strlen(buf2);
1643 iov[2].iov_base = buf3;
1644 iov[2].iov_len = 1;
1646 rc = writev(sv[0], iovp, 3);
1647 if (rc == -1) {
1648 test_fail("writev");
1651 memset(buf4, '\0', BUFSIZE*3);
1653 rc = read(sv[1], buf4, BUFSIZE*3);
1654 if (rc == -1) {
1655 test_fail("read");
1658 if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
1659 test_fail("the string we read was not 'HELLO WORLD'");
1662 memset(buf1, '\0', BUFSIZE);
1663 strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
1665 rc = write(sv[1], buf1, strlen(buf1) + 1);
1666 if (rc == -1) {
1667 test_fail("write");
1670 memset(buf2, '\0', BUFSIZE);
1671 memset(buf3, '\0', BUFSIZE);
1672 memset(buf4, '\0', BUFSIZE*3);
1674 iov[0].iov_base = buf2;
1675 iov[0].iov_len = 5;
1676 iov[1].iov_base = buf3;
1677 iov[1].iov_len = 5;
1678 iov[2].iov_base = buf4;
1679 iov[2].iov_len = 32;
1681 rc = readv(sv[0], iovp, 3);
1682 if (rc == -1) {
1683 test_fail("readv");
1686 if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
1687 strncmp(buf4, "Time", 4)) {
1688 test_fail("readv");
1691 rc = close(sv[0]);
1692 if (rc == -1) {
1693 test_fail("close");
1696 rc = close(sv[1]);
1697 if (rc == -1) {
1698 test_fail("close");
1701 debug("done vector io tests");
1704 void test_msg(int type)
1706 int sv[2];
1707 int rc;
1708 struct msghdr msg1;
1709 struct msghdr msg2;
1710 struct iovec iov[3];
1711 char buf1[BUFSIZE];
1712 char buf2[BUFSIZE];
1713 char buf3[BUFSIZE];
1714 char buf4[BUFSIZE*3];
1716 debug("begin sendmsg/recvmsg tests");
1718 memset(buf1, '\0', BUFSIZE);
1719 strncpy(buf1, "HELLO ", BUFSIZE - 1);
1721 memset(buf2, '\0', BUFSIZE);
1722 strncpy(buf2, "WORLD", BUFSIZE - 1);
1724 memset(buf3, '\0', BUFSIZE);
1726 rc = socketpair(PF_UNIX, type, 0, sv);
1727 if (rc == -1) {
1728 test_fail("socketpair");
1731 iov[0].iov_base = buf1;
1732 iov[0].iov_len = strlen(buf1);
1733 iov[1].iov_base = buf2;
1734 iov[1].iov_len = strlen(buf2);
1735 iov[2].iov_base = buf3;
1736 iov[2].iov_len = 1;
1738 memset(&msg1, '\0', sizeof(struct msghdr));
1739 msg1.msg_name = NULL;
1740 msg1.msg_namelen = 0;
1741 msg1.msg_iov = iov;
1742 msg1.msg_iovlen = 3;
1743 msg1.msg_control = NULL;
1744 msg1.msg_controllen = 0;
1745 msg1.msg_flags = 0;
1747 rc = sendmsg(sv[0], &msg1, 0);
1748 if (rc == -1) {
1749 test_fail("writev");
1752 memset(buf4, '\0', BUFSIZE*3);
1754 rc = read(sv[1], buf4, BUFSIZE*3);
1755 if (rc == -1) {
1756 test_fail("read");
1759 if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
1760 test_fail("the string we read was not 'HELLO WORLD'");
1763 memset(buf1, '\0', BUFSIZE);
1764 strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
1766 rc = write(sv[1], buf1, strlen(buf1) + 1);
1767 if (rc == -1) {
1768 test_fail("write");
1771 memset(buf2, '\0', BUFSIZE);
1772 memset(buf3, '\0', BUFSIZE);
1773 memset(buf4, '\0', BUFSIZE*3);
1775 iov[0].iov_base = buf2;
1776 iov[0].iov_len = 5;
1777 iov[1].iov_base = buf3;
1778 iov[1].iov_len = 5;
1779 iov[2].iov_base = buf4;
1780 iov[2].iov_len = 32;
1782 memset(&msg2, '\0', sizeof(struct msghdr));
1783 msg2.msg_name = NULL;
1784 msg2.msg_namelen = 0;
1785 msg2.msg_iov = iov;
1786 msg2.msg_iovlen = 3;
1787 msg2.msg_control = NULL;
1788 msg2.msg_controllen = 0;
1789 msg2.msg_flags = 0;
1791 rc = recvmsg(sv[0], &msg2, 0);
1792 if (rc == -1) {
1793 test_fail("readv");
1796 if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
1797 strncmp(buf4, "Time", 4)) {
1798 test_fail("readv");
1801 rc = close(sv[0]);
1802 if (rc == -1) {
1803 test_fail("close");
1806 rc = close(sv[1]);
1807 if (rc == -1) {
1808 test_fail("close");
1812 void test_msg_dgram(void)
1814 int rc;
1815 int src;
1816 int dst;
1817 struct sockaddr_un addr;
1818 struct iovec iov[3];
1819 struct msghdr msg1;
1820 struct msghdr msg2;
1821 char buf1[BUFSIZE];
1822 char buf2[BUFSIZE];
1823 char buf3[BUFSIZE];
1824 socklen_t addrlen = sizeof(struct sockaddr_un);
1826 debug("test msg_dgram");
1828 UNLINK(TEST_SUN_PATH);
1829 UNLINK(TEST_SUN_PATHB);
1831 src = socket(PF_UNIX, SOCK_DGRAM, 0);
1832 if (src == -1) {
1833 test_fail("socket");
1836 dst = socket(PF_UNIX, SOCK_DGRAM, 0);
1837 if (dst == -1) {
1838 test_fail("socket");
1841 memset(&addr, '\0', sizeof(struct sockaddr_un));
1842 addr.sun_family = AF_UNIX;
1843 strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1);
1844 rc = bind(src, (struct sockaddr *) &addr, addrlen);
1845 if (rc == -1) {
1846 test_fail("bind");
1849 memset(&addr, '\0', sizeof(struct sockaddr_un));
1850 addr.sun_family = AF_UNIX;
1851 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1853 rc = bind(dst, (struct sockaddr *) &addr, addrlen);
1854 if (rc == -1) {
1855 test_fail("bind");
1858 memset(&buf1, '\0', BUFSIZE);
1859 memset(&buf2, '\0', BUFSIZE);
1860 memset(&buf3, '\0', BUFSIZE);
1862 strncpy(buf1, "Minix ", BUFSIZE-1);
1863 strncpy(buf2, "is ", BUFSIZE-1);
1864 strncpy(buf3, "great!", BUFSIZE-1);
1866 iov[0].iov_base = buf1;
1867 iov[0].iov_len = 6;
1868 iov[1].iov_base = buf2;
1869 iov[1].iov_len = 3;
1870 iov[2].iov_base = buf3;
1871 iov[2].iov_len = 32;
1873 memset(&msg1, '\0', sizeof(struct msghdr));
1874 msg1.msg_name = &addr;
1875 msg1.msg_namelen = addrlen;
1876 msg1.msg_iov = iov;
1877 msg1.msg_iovlen = 3;
1878 msg1.msg_control = NULL;
1879 msg1.msg_controllen = 0;
1880 msg1.msg_flags = 0;
1882 rc = sendmsg(src, &msg1, 0);
1883 if (rc == -1) {
1884 test_fail("sendmsg");
1887 memset(&buf1, '\0', BUFSIZE);
1888 memset(&buf2, '\0', BUFSIZE);
1890 iov[0].iov_base = buf1;
1891 iov[0].iov_len = 9;
1892 iov[1].iov_base = buf2;
1893 iov[1].iov_len = 32;
1895 memset(&addr, '\0', sizeof(struct sockaddr_un));
1896 memset(&msg2, '\0', sizeof(struct msghdr));
1897 msg2.msg_name = &addr;
1898 msg2.msg_namelen = sizeof(struct sockaddr_un);
1899 msg2.msg_iov = iov;
1900 msg2.msg_iovlen = 2;
1901 msg2.msg_control = NULL;
1902 msg2.msg_controllen = 0;
1903 msg2.msg_flags = 0;
1905 rc = recvmsg(dst, &msg2, 0);
1906 if (rc == -1) {
1907 test_fail("recvmsg");
1910 if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
1911 test_fail("recvmsg");
1914 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
1915 * because that is what is returned by recvmsg().
1917 if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path,
1918 fullpath(TEST_SUN_PATHB))) {
1919 test_fail("recvmsg");
1922 rc = close(dst);
1923 if (rc == -1) {
1924 test_fail("close");
1927 rc = close(src);
1928 if (rc == -1) {
1929 test_fail("close");
1932 UNLINK(TEST_SUN_PATH);
1933 UNLINK(TEST_SUN_PATHB);
1936 void test_scm_credentials(void)
1938 int rc;
1939 int src;
1940 int dst;
1941 struct ucred cred;
1942 struct cmsghdr *cmsg = NULL;
1943 struct sockaddr_un addr;
1944 struct iovec iov[3];
1945 struct msghdr msg1;
1946 struct msghdr msg2;
1947 char buf1[BUFSIZE];
1948 char buf2[BUFSIZE];
1949 char buf3[BUFSIZE];
1950 char ctrl[BUFSIZE];
1951 socklen_t addrlen = sizeof(struct sockaddr_un);
1953 debug("test_scm_credentials");
1955 UNLINK(TEST_SUN_PATH);
1956 UNLINK(TEST_SUN_PATHB);
1958 debug("creating src socket");
1960 src = socket(PF_UNIX, SOCK_DGRAM, 0);
1961 if (src == -1) {
1962 test_fail("socket");
1965 debug("creating dst socket");
1967 dst = socket(PF_UNIX, SOCK_DGRAM, 0);
1968 if (dst == -1) {
1969 test_fail("socket");
1972 debug("binding src socket");
1974 memset(&addr, '\0', sizeof(struct sockaddr_un));
1975 addr.sun_family = AF_UNIX;
1976 strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1);
1977 rc = bind(src, (struct sockaddr *) &addr, addrlen);
1978 if (rc == -1) {
1979 test_fail("bind");
1982 debug("binding dst socket");
1984 memset(&addr, '\0', sizeof(struct sockaddr_un));
1985 addr.sun_family = AF_UNIX;
1986 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1988 rc = bind(dst, (struct sockaddr *) &addr, addrlen);
1989 if (rc == -1) {
1990 test_fail("bind");
1993 memset(&buf1, '\0', BUFSIZE);
1994 memset(&buf2, '\0', BUFSIZE);
1995 memset(&buf3, '\0', BUFSIZE);
1996 memset(&ctrl, '\0', BUFSIZE);
1998 strncpy(buf1, "Minix ", BUFSIZE-1);
1999 strncpy(buf2, "is ", BUFSIZE-1);
2000 strncpy(buf3, "great!", BUFSIZE-1);
2002 iov[0].iov_base = buf1;
2003 iov[0].iov_len = 6;
2004 iov[1].iov_base = buf2;
2005 iov[1].iov_len = 3;
2006 iov[2].iov_base = buf3;
2007 iov[2].iov_len = 32;
2009 memset(&msg1, '\0', sizeof(struct msghdr));
2010 msg1.msg_name = &addr;
2011 msg1.msg_namelen = addrlen;
2012 msg1.msg_iov = iov;
2013 msg1.msg_iovlen = 3;
2014 msg1.msg_control = NULL;
2015 msg1.msg_controllen = 0;
2016 msg1.msg_flags = 0;
2018 debug("sending msg1");
2020 rc = sendmsg(src, &msg1, 0);
2021 if (rc == -1) {
2022 test_fail("sendmsg");
2025 memset(&buf1, '\0', BUFSIZE);
2026 memset(&buf2, '\0', BUFSIZE);
2027 memset(&buf3, '\0', BUFSIZE);
2028 memset(&ctrl, '\0', BUFSIZE);
2030 iov[0].iov_base = buf1;
2031 iov[0].iov_len = 9;
2032 iov[1].iov_base = buf2;
2033 iov[1].iov_len = 32;
2035 memset(&addr, '\0', sizeof(struct sockaddr_un));
2036 memset(&msg2, '\0', sizeof(struct msghdr));
2037 msg2.msg_name = &addr;
2038 msg2.msg_namelen = sizeof(struct sockaddr_un);
2039 msg2.msg_iov = iov;
2040 msg2.msg_iovlen = 2;
2041 msg2.msg_control = ctrl;
2042 msg2.msg_controllen = BUFSIZE;
2043 msg2.msg_flags = 0;
2045 debug("recv msg2");
2047 rc = recvmsg(dst, &msg2, 0);
2048 if (rc == -1) {
2049 test_fail("recvmsg");
2052 debug("checking results");
2054 if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
2055 test_fail("recvmsg");
2058 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
2059 * because that is what is returned by recvmsg().
2061 if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path,
2062 fullpath(TEST_SUN_PATHB))) {
2063 test_fail("recvmsg");
2066 debug("looking for credentials");
2068 memset(&cred, '\0', sizeof(struct ucred));
2069 for (cmsg = CMSG_FIRSTHDR(&msg2); cmsg != NULL;
2070 cmsg = CMSG_NXTHDR(&msg2, cmsg)) {
2072 if (cmsg->cmsg_level == SOL_SOCKET &&
2073 cmsg->cmsg_type == SCM_CREDENTIALS) {
2075 memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct ucred));
2076 break;
2080 if (cred.pid != getpid() || cred.uid != geteuid() ||
2081 cred.gid != getegid()) {
2083 test_fail("did no receive the proper credentials");
2086 rc = close(dst);
2087 if (rc == -1) {
2088 test_fail("close");
2091 rc = close(src);
2092 if (rc == -1) {
2093 test_fail("close");
2096 UNLINK(TEST_SUN_PATH);
2097 UNLINK(TEST_SUN_PATHB);
2100 void test_connect(void)
2102 int i, sd, sds[2], rc;
2104 /* connect() is already tested throughout test56, but
2105 * in most cases the client and server end up on /dev/uds
2106 * minor 0 and minor 1. This test opens some sockets first and
2107 * then calls test_simple_client_server(). This forces the
2108 * client and server minor numbers higher in the descriptor table.
2111 debug("starting test_connect()");
2113 sd = socket(AF_UNIX, SOCK_DGRAM, 0);
2114 if (sd == -1) {
2115 test_fail("couldn't create a socket");
2118 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sds);
2119 if (rc == -1) {
2120 test_fail("couldn't create a socketpair");
2123 for (i = 0; i < 3; i++) {
2124 test_simple_client_server(types[i]);
2127 rc = close(sds[1]);
2128 if (rc == -1) {
2129 test_fail("close() failed");
2132 rc = close(sds[0]);
2133 if (rc == -1) {
2134 test_fail("close() failed");
2137 rc = close(sd);
2138 if (rc == -1) {
2139 test_fail("close() failed");
2142 debug("exiting test_connect()");
2145 int test_multiproc_read(void)
2147 /* test that when we fork() a process with an open socket descriptor,
2148 * the descriptor in each process points to the same thing.
2151 pid_t pid;
2152 int sds[2];
2153 int rc, status;
2154 char buf[3];
2156 debug("entering test_multiproc_read()");
2158 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
2159 if (rc == -1) {
2160 test_fail("socketpair");
2161 return 1;
2164 memset(buf, '\0', 3);
2167 /* the signal handler is only used by the client, but we have to
2168 * install it now. if we don't the server may signal the client
2169 * before the handler is installed.
2171 debug("installing signal handler");
2172 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
2173 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2174 return 1;
2177 debug("signal handler installed");
2179 server_ready = 0;
2181 pid = fork();
2183 if (pid == -1) {
2185 test_fail("fork");
2186 return 1;
2188 } else if (pid == 0) {
2190 while (server_ready == 0) {
2191 debug("waiting for SIGUSR1 from parent");
2192 sleep(1);
2195 rc = read(sds[1], buf, 2);
2196 if (rc == -1) {
2197 test_fail("read");
2198 exit(1);
2201 if (!(buf[0] == 'X' && buf[1] == '3')) {
2202 test_fail("Didn't read X3");
2203 exit(1);
2206 exit(0);
2207 } else {
2209 rc = write(sds[0], "MNX3", 4);
2210 if (rc == -1) {
2211 test_fail("write");
2214 rc = read(sds[1], buf, 2);
2215 if (rc == -1) {
2216 test_fail("read");
2219 if (!(buf[0] == 'M' && buf[1] == 'N')) {
2220 test_fail("Didn't read MN");
2223 /* time to tell the client to start the test */
2224 kill(pid, SIGUSR1);
2226 do {
2227 rc = waitpid(pid, &status, 0);
2228 } while (rc == -1 && errno == EINTR);
2230 /* we use the exit status to get its error count */
2231 errct += WEXITSTATUS(status);
2234 return 0;
2237 int test_multiproc_write(void)
2239 /* test that when we fork() a process with an open socket descriptor,
2240 * the descriptor in each process points to the same thing.
2243 pid_t pid;
2244 int sds[2];
2245 int rc, status;
2246 char buf[7];
2248 debug("entering test_multiproc_write()");
2250 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
2251 if (rc == -1) {
2252 test_fail("socketpair");
2253 return 1;
2256 memset(buf, '\0', 7);
2259 /* the signal handler is only used by the client, but we have to
2260 * install it now. if we don't the server may signal the client
2261 * before the handler is installed.
2263 debug("installing signal handler");
2264 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
2265 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2266 return 1;
2269 debug("signal handler installed");
2271 server_ready = 0;
2273 pid = fork();
2275 if (pid == -1) {
2277 test_fail("fork");
2278 return 1;
2280 } else if (pid == 0) {
2282 while (server_ready == 0) {
2283 debug("waiting for SIGUSR1 from parent");
2284 sleep(1);
2287 rc = write(sds[1], "IX3", 3);
2288 if (rc == -1) {
2289 test_fail("write");
2290 exit(1);
2293 rc = read(sds[0], buf, 6);
2294 if (rc == -1) {
2295 test_fail("read");
2296 exit(1);
2299 if (strcmp(buf, "MINIX3") != 0) {
2300 test_fail("didn't read MINIX3");
2301 exit(1);
2304 exit(0);
2305 } else {
2307 rc = write(sds[1], "MIN", 3);
2308 if (rc == -1) {
2309 test_fail("write");
2312 /* time to tell the client to start the test */
2313 kill(pid, SIGUSR1);
2315 do {
2316 rc = waitpid(pid, &status, 0);
2317 } while (rc == -1 && errno == EINTR);
2319 /* we use the exit status to get its error count */
2320 errct += WEXITSTATUS(status);
2323 return 0;
2326 void test_fd_passing_child(int sd)
2328 int fd, rc;
2329 char x = 'x';
2330 struct msghdr msghdr;
2331 struct cmsghdr *cmsg;
2332 struct iovec iov;
2333 char buf[BUFSIZE];
2335 memset(buf, '\0', BUFSIZE);
2337 fd = open(TEST_TXT_FILE, O_CREAT|O_TRUNC|O_RDWR);
2338 if (fd == -1) {
2339 test_fail("could not open test.txt");
2342 msghdr.msg_name = NULL;
2343 msghdr.msg_namelen = 0;
2345 iov.iov_base = &x;
2346 iov.iov_len = 1;
2347 msghdr.msg_iov = &iov;
2348 msghdr.msg_iovlen = 1;
2350 msghdr.msg_control = buf;
2351 msghdr.msg_controllen = CMSG_SPACE(sizeof(int));
2353 msghdr.msg_flags = 0;
2355 cmsg = CMSG_FIRSTHDR(&msghdr);
2356 cmsg->cmsg_len = CMSG_SPACE(sizeof(int));
2357 cmsg->cmsg_level = SOL_SOCKET;
2358 cmsg->cmsg_type = SCM_RIGHTS;
2360 ((int *) CMSG_DATA(cmsg))[0] = fd;
2362 rc = sendmsg(sd, &msghdr, 0);
2363 if (rc == -1) {
2364 test_fail("could not send message");
2367 memset(buf, '\0', BUFSIZE);
2368 rc = read(sd, buf, BUFSIZE);
2369 if (rc == -1) {
2370 test_fail("could not read from socket");
2373 if (strcmp(buf, "done") != 0) {
2374 test_fail("we didn't read the right message");
2377 memset(buf, '\0', BUFSIZE);
2378 rc = lseek(fd, 0, SEEK_SET);
2379 if (rc == -1) {
2380 test_fail("could not seek to start of test.txt");
2383 rc = read(fd, buf, BUFSIZE);
2384 if (rc == -1) {
2385 test_fail("could not read from test.txt");
2388 if (strcmp(buf, MSG) != 0) {
2389 test_fail("other process didn't write MSG to test.txt");
2392 rc = close(fd);
2393 if (rc == -1) {
2394 test_fail("could not close test.txt");
2397 rc = close(sd);
2398 if (rc == -1) {
2399 test_fail("could not close socket");
2402 rc = unlink(TEST_TXT_FILE);
2403 if (rc == -1) {
2404 test_fail("could not unlink test.txt");
2407 exit(errct);
2410 void test_fd_passing_parent(int sd)
2412 int rc, fd;
2413 char x;
2414 struct msghdr msghdr;
2415 struct cmsghdr *cmsg;
2416 struct iovec iov;
2417 char buf[BUFSIZE];
2419 memset(buf, '\0', BUFSIZE);
2421 msghdr.msg_name = NULL;
2422 msghdr.msg_namelen = 0;
2424 iov.iov_base = &x;
2425 iov.iov_len = 1;
2426 msghdr.msg_iov = &iov;
2427 msghdr.msg_iovlen = 1;
2429 msghdr.msg_iov = &iov;
2430 msghdr.msg_iovlen = 1;
2432 msghdr.msg_control = buf;
2433 msghdr.msg_controllen = BUFSIZE;
2435 msghdr.msg_flags = 0;
2437 rc = recvmsg(sd, &msghdr, 0);
2438 if (rc == -1) {
2439 test_fail("could not recv message.");
2442 cmsg = CMSG_FIRSTHDR(&msghdr);
2443 fd = ((int *) CMSG_DATA(cmsg))[0];
2445 rc = write(fd, MSG, strlen(MSG));
2446 if (rc != strlen(MSG)) {
2447 test_fail("could not write the full message to test.txt");
2450 rc = close(fd);
2451 if (rc == -1) {
2452 test_fail("could not close test.txt");
2455 memset(buf, '\0', BUFSIZE);
2456 strcpy(buf, "done");
2457 rc = write(sd, buf, BUFSIZE);
2458 if (rc == -1) {
2459 test_fail("could not write to socket");
2462 rc = close(sd);
2463 if (rc == -1) {
2464 test_fail("could not close socket");
2468 void test_permissions(void) {
2469 /* Test bind and connect for permission verification
2471 * After creating a UDS socket we change user credentials. At that
2472 * point we should not be allowed to bind or connect to the UDS socket
2475 pid_t pid;
2476 int sd, rc, status;
2477 struct sockaddr_un addr;
2479 memset(&addr, '\0', sizeof(struct sockaddr_un));
2480 addr.sun_family = AF_UNIX;
2481 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
2483 UNLINK(TEST_SUN_PATH);
2485 pid = fork();
2486 if (pid < 0) test_fail("unable to fork");
2487 else if (pid == 0) {
2488 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
2489 if (setuid(999) != 0) test_fail("unable to chance uid");
2490 rc = bind(sd, (struct sockaddr *) &addr,
2491 sizeof(struct sockaddr_un));
2492 if (rc != -1) {
2493 test_fail("bind() should not have worked");
2495 exit(errct);
2496 } else {
2497 rc = waitpid(pid, &status, 0);
2498 errct += WEXITSTATUS(status);
2501 /* the signal handler is only used by the client, but we have to
2502 * install it now. if we don't the server may signal the client
2503 * before the handler is installed.
2505 debug("installing signal handler");
2506 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
2507 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2510 debug("signal handler installed");
2512 server_ready = 0;
2514 pid = fork();
2515 if (pid < 0) test_fail("unable to fork");
2516 else if (pid == 0) {
2517 while (server_ready == 0) {
2518 debug("[client] waiting for the server to signal");
2519 sleep(1);
2521 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
2522 if (setuid(999) != 0) test_fail("unable to chance uid");
2523 rc = connect(sd, (struct sockaddr *) &addr,
2524 sizeof(struct sockaddr_un));
2525 if (rc != -1)
2526 test_fail("connect should not have worked");
2527 exit(errct);
2528 } else {
2529 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
2530 rc = bind(sd, (struct sockaddr *) &addr,
2531 sizeof(struct sockaddr_un));
2532 if (rc == -1) {
2533 test_fail("bind() should have worked");
2536 rc = listen(sd, 8);
2537 if (rc == -1) {
2538 test_fail("listen(sd, 8) should have worked");
2540 kill(pid, SIGUSR1);
2541 sleep(1);
2542 CLOSE(sd);
2544 rc = waitpid(pid, &status, 0);
2545 errct += WEXITSTATUS(status);
2548 UNLINK(TEST_SUN_PATH);
2551 void test_fd_passing(void) {
2552 int status;
2553 int sv[2];
2554 pid_t pid;
2555 int rc;
2557 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
2558 if (rc == -1) {
2559 test_fail("socketpair failed");
2562 pid = fork();
2563 if (pid == -1) {
2564 test_fail("fork() failed");
2566 rc = close(sv[0]);
2567 if (rc == -1) {
2568 test_fail("could not close sv[0]");
2571 rc = close(sv[1]);
2572 if (rc == -1) {
2573 test_fail("could not close sv[1]");
2576 exit(0);
2577 } else if (pid == 0) {
2578 rc = close(sv[0]);
2579 if (rc == -1) {
2580 test_fail("could not close sv[0]");
2583 test_fd_passing_child(sv[1]);
2584 test_fail("should never get here");
2585 exit(1);
2586 } else {
2587 rc = close(sv[1]);
2588 if (rc == -1) {
2589 test_fail("could not close sv[1]");
2592 test_fd_passing_parent(sv[0]);
2594 /* wait for client to exit */
2595 do {
2596 errno = 0;
2597 rc = waitpid(pid, &status, 0);
2598 } while (rc == -1 && errno == EINTR);
2600 /* we use the exit status to get its error count */
2601 errct += WEXITSTATUS(status);
2605 int main(int argc, char *argv[])
2607 int i;
2609 debug("entering main()");
2611 start(56);
2613 test_socket();
2614 test_bind();
2615 test_listen();
2616 test_getsockname();
2617 test_header();
2618 test_shutdown();
2619 test_close();
2620 test_permissions();
2621 test_dup();
2622 test_dup2();
2623 test_socketpair();
2624 test_shutdown();
2625 test_read();
2626 test_write();
2627 test_sockopts();
2628 test_ucred();
2629 test_xfer();
2631 for (i = 0; i < 3; i++) {
2632 test_simple_client_server(types[i]);
2633 if (types[i] != SOCK_DGRAM) test_vectorio(types[i]);
2634 if (types[i] != SOCK_DGRAM) test_msg(types[i]);
2637 test_msg_dgram();
2638 test_connect();
2639 test_multiproc_read();
2640 test_multiproc_write();
2641 test_scm_credentials();
2642 test_fd_passing();
2643 quit();
2645 return -1; /* we should never get here */