mkfs: symlink support
[minix.git] / test / test56.c
blob360e2a6250c07e6e2a0a9d2a6021d07b22869e0a
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;
474 int on;
476 debug("entering test_bind()");
477 on = 1;
478 UNLINK(TEST_SUN_PATH);
479 memset(&addr, '\0', sizeof(struct sockaddr_un));
480 addr.sun_family = AF_UNIX;
481 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
483 debug("Test bind() success");
485 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
486 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
487 if (rc == -1) {
488 test_fail("bind() should have worked");
491 debug("Test getsockname() success");
493 memset(&sock_addr, '\0', sizeof(struct sockaddr_un));
494 sock_addr_len = sizeof(struct sockaddr_un);
496 rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len);
497 if (rc == -1) {
498 test_fail("getsockname() should have worked");
501 if (!(sock_addr.sun_family == AF_UNIX &&
502 strncmp(sock_addr.sun_path,
503 fullpath(TEST_SUN_PATH),
504 sizeof(sock_addr.sun_path) - 1) == 0)) {
506 test_fail("getsockname() didn't return the right addr");
507 fprintf(stderr, "exp: '%s' | got: '%s'\n", addr.sun_path,
508 sock_addr.sun_path);
511 debug("Test bind() with a address that has already been bind()'d");
513 SOCKET(sd2, PF_UNIX, SOCK_STREAM, 0);
514 errno = 0;
515 rc = bind(sd2, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
516 if (!((rc == -1) && (errno == EADDRINUSE))) {
517 test_fail("bind() should have failed with EADDRINUSE");
519 CLOSE(sd2);
520 CLOSE(sd);
521 UNLINK(TEST_SUN_PATH);
523 debug("Test bind() with an empty sun_path");
525 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
526 memset(addr.sun_path, '\0', sizeof(addr.sun_path));
527 errno = 0;
529 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
530 if (!(rc == -1 && errno == ENOENT)) {
531 test_fail("bind() should have failed with ENOENT");
533 CLOSE(sd);
535 debug("Test bind() with a NULL address");
537 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
538 errno = 0;
539 rc = bind(sd, (struct sockaddr *) NULL, sizeof(struct sockaddr_un));
540 if (!((rc == -1) && (errno == EFAULT))) {
541 test_fail("bind() should have failed with EFAULT");
543 CLOSE(sd);
545 debug("Test bind() using a symlink loop");
547 UNLINK(TEST_SUN_PATH);
548 UNLINK(TEST_SYM_A);
549 UNLINK(TEST_SYM_B);
551 SYMLINK(TEST_SYM_A, TEST_SYM_B);
552 SYMLINK(TEST_SYM_B, TEST_SYM_A);
554 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
556 strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1);
557 errno = 0;
558 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
559 if (!((rc == -1) && (errno == ELOOP))) {
560 test_fail("bind() should have failed with ELOOP");
562 CLOSE(sd);
564 UNLINK(TEST_SUN_PATH);
565 UNLINK(TEST_SYM_A);
566 UNLINK(TEST_SYM_B);
568 debug("leaving test_bind()");
571 void test_listen(void)
573 int rc;
575 debug("entering test_listen()");
577 debug("Test listen() with a bad file descriptor");
579 errno = 0;
580 rc = listen(-1, 0);
581 if (!(rc == -1 && errno == EBADF)) {
582 test_fail("listen(-1, 0) should have failed");
585 debug("Test listen() with a non-socket file descriptor");
587 errno = 0;
588 rc = listen(0, 0);
589 if (!(rc == -1 && errno == ENOTTY)) {
590 test_fail("listen(0, 0) should have failed");
593 debug("leaving test_listen()");
596 void test_shutdown(void)
598 int how[3] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
599 int sd;
600 int rc;
601 int i;
603 debug("entering test_shutdown()");
605 /* test for each direction (read, write, read-write) */
606 for (i = 0; i < 3; i++) {
608 debug("test shutdown() with an invalid descriptor");
610 errno = 0;
611 rc = shutdown(-1, how[i]);
612 if (!(rc == -1 && errno == EBADF)) {
613 test_fail("shutdown(-1, how[i]) should have failed");
616 debug("test shutdown() with a non-socket descriptor");
618 errno = 0;
619 rc = shutdown(0, how[i]);
620 if (!(rc == -1 && errno == ENOSYS)) {
621 test_fail("shutdown() should have failed with ENOSYS");
624 debug("test shutdown() with a socket that is not connected");
626 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
627 errno = 0;
628 rc = shutdown(sd, how[i]);
629 if (!(rc == -1 && errno == ENOTCONN)) {
630 test_fail("shutdown() should have failed");
632 CLOSE(sd);
635 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
636 errno = 0;
637 rc = shutdown(sd, -1);
638 if (!(rc == -1 && errno == ENOTCONN)) {
639 test_fail("shutdown(sd, -1) should have failed with ENOTCONN");
641 CLOSE(sd);
643 debug("leaving test_shutdown()");
646 void test_close(void)
648 struct sockaddr_un addr;
649 int sd, sd2;
650 int rc, i;
652 debug("entering test_close()");
654 UNLINK(TEST_SUN_PATH);
656 memset(&addr, '\0', sizeof(struct sockaddr_un));
657 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
658 addr.sun_family = AF_UNIX;
660 debug("Test close() success");
662 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
663 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
664 if (rc != 0) {
665 test_fail("bind() should have worked");
668 CLOSE(sd);
670 debug("Close an already closed file descriptor");
672 errno = 0;
673 rc = close(sd);
674 if (!(rc == -1 && errno == EBADF)) {
675 test_fail("close(sd) should have failed with EBADF");
678 UNLINK(TEST_SUN_PATH);
680 debug("dup()'ing a file descriptor and closing both should work");
682 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
683 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
684 if (rc != 0) {
685 test_fail("bind() should have worked");
688 errno = 0;
689 sd2 = dup(sd);
690 if (sd2 == -1) {
691 test_fail("dup(sd) should have worked");
692 } else {
693 CLOSE(sd2);
694 CLOSE(sd);
697 UNLINK(TEST_SUN_PATH);
699 /* Create and close a socket a bunch of times.
700 * If the implementation doesn't properly free the
701 * socket during close(), eventually socket() will
702 * fail when the internal descriptor table is full.
704 for (i = 0; i < 1024; i++) {
705 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
706 CLOSE(sd);
709 debug("leaving test_close()");
712 void test_sockopts(void)
714 int i;
715 int rc;
716 int sd;
717 int option_value;
718 socklen_t option_len;
720 debug("entering test_sockopts()");
722 for (i = 0; i < 3; i++) {
724 SOCKET(sd, PF_UNIX, types[i], 0);
726 debug("Test setsockopt() works");
728 option_value = 0;
729 option_len = sizeof(option_value);
730 errno = 0;
731 rc = getsockopt(sd, SOL_SOCKET, SO_TYPE, &option_value,
732 &option_len);
733 if (rc != 0) {
734 test_fail("setsockopt() should have worked");
737 if (option_value != types[i]) {
738 test_fail("SO_TYPE didn't seem to work.");
741 CLOSE(sd);
746 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
748 debug("Test setsockopt() works");
750 option_value = 0;
751 option_len = sizeof(option_value);
752 errno = 0;
753 rc = getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &option_value, &option_len);
754 if (rc != 0) {
755 test_fail("getsockopt() should have worked");
758 if (option_value != PIPE_BUF) {
759 test_fail("SO_SNDBUF didn't seem to work.");
762 CLOSE(sd);
765 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
767 debug("Test setsockopt() works");
769 option_value = 0;
770 option_len = sizeof(option_value);
771 errno = 0;
772 rc = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &option_value, &option_len);
773 if (rc != 0) {
774 test_fail("getsockopt() should have worked");
777 if (option_value != PIPE_BUF) {
778 test_fail("SO_RCVBUF didn't seem to work.");
781 CLOSE(sd);
784 debug("leaving test_sockopts()");
787 void test_read(void)
789 int rc;
790 int fd;
791 char buf[BUFSIZE];
793 debug("entering test_read()");
795 errno = 0;
796 rc = read(-1, buf, sizeof(buf));
797 if (!(rc == -1 && errno == EBADF)) {
798 test_fail("read() should have failed with EBADF");
801 fd = open("/tmp", O_RDONLY);
802 if (fd == -1) {
803 test_fail("open(\"/tmp\", O_RDONLY) should have worked");
806 CLOSE(fd);
808 debug("leaving test_read()");
811 void test_write(void)
813 int rc;
814 char buf[BUFSIZE];
816 debug("entering test_write()");
818 errno = 0;
819 rc = write(-1, buf, sizeof(buf));
820 if (!(rc == -1 && errno == EBADF)) {
821 test_fail("write() should have failed with EBADF");
824 debug("leaving test_write()");
827 void test_dup(void)
829 struct stat info1;
830 struct stat info2;
831 struct sockaddr_un addr;
832 int sd, sd2;
833 int rc;
834 int i;
836 debug("entering test_dup()");
838 UNLINK(TEST_SUN_PATH);
840 memset(&addr, '\0', sizeof(struct sockaddr_un));
841 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
842 addr.sun_family = AF_UNIX;
844 debug("Test dup()");
846 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
847 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
848 if (rc != 0) {
849 test_fail("bind() should have worked");
852 errno = 0;
853 sd2 = dup(sd);
854 if (sd2 == -1) {
855 test_fail("dup(sd) should have worked");
858 rc = fstat(sd, &info1);
859 if (rc == -1) {
860 test_fail("fstat(fd, &info1) failed");
863 rc = fstat(sd2, &info2);
864 if (rc == -1) {
865 test_fail("fstat(sd, &info2) failed");
868 if (info1.st_ino != info2.st_ino) {
869 test_fail("dup() failed info1.st_ino != info2.st_ino");
872 CLOSE(sd);
873 CLOSE(sd2);
875 debug("Test dup() with a closed socket");
877 errno = 0;
878 rc = dup(sd);
879 if (!(rc == -1 && errno == EBADF)) {
880 test_fail("dup(sd) on a closed socket shouldn't have worked");
883 debug("Test dup() with socket descriptor of -1");
885 errno = 0;
886 rc = dup(-1);
887 if (!(rc == -1 && errno == EBADF)) {
888 test_fail("dup(-1) shouldn't have worked");
891 debug("Test dup() when all of the file descriptors are taken");
893 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
895 for (i = 4; i < getdtablesize(); i++) {
896 rc = open("/dev/null", O_RDONLY);
897 if (rc == -1) {
898 test_fail("we couldn't open /dev/null for read");
902 errno = 0;
903 sd2 = dup(sd);
904 if (!(sd2 == -1 && errno == EMFILE)) {
905 test_fail("dup(sd) should have failed with errno = EMFILE");
908 for (i = 3; i < getdtablesize(); i++) {
909 CLOSE(i);
912 UNLINK(TEST_SUN_PATH);
914 debug("leaving test_dup()");
917 void test_dup2(void)
919 struct stat info1;
920 struct stat info2;
921 struct sockaddr_un addr;
922 int sd;
923 int fd;
924 int rc;
926 debug("entering test_dup2()");
927 UNLINK(TEST_SUN_PATH);
929 memset(&addr, '\0', sizeof(struct sockaddr_un));
930 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
931 addr.sun_family = AF_UNIX;
933 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
935 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
936 if (rc != 0) {
937 test_fail("bind() should have worked");
940 fd = open("/dev/null", O_RDONLY);
941 if (fd == -1) {
942 test_fail("open(\"/dev/null\", O_RDONLY) failed");
945 fd = dup2(sd, fd);
946 if (fd == -1) {
947 test_fail("dup2(sd, fd) failed.");
950 memset(&info1, '\0', sizeof(struct stat));
951 memset(&info2, '\0', sizeof(struct stat));
953 rc = fstat(fd, &info1);
954 if (rc == -1) {
955 test_fail("fstat(fd, &info1) failed");
958 rc = fstat(sd, &info2);
959 if (rc == -1) {
960 test_fail("fstat(sd, &info2) failed");
963 if (!(info1.st_ino == info2.st_ino &&
964 major(info1.st_dev) == major(info2.st_dev) &&
965 minor(info1.st_dev) == minor(info2.st_dev))) {
967 test_fail("dup2() failed");
970 CLOSE(fd);
971 CLOSE(sd);
973 UNLINK(TEST_SUN_PATH);
974 debug("leaving test_dup2()");
979 * A toupper() server. This toy server converts a string to upper case.
981 void test_xfer_server(pid_t pid)
983 socklen_t ucred_length;
984 int i;
985 int on;
986 struct timeval tv;
987 fd_set readfds;
988 int status;
989 int rc;
990 int sd;
991 char buf[BUFSIZE];
992 socklen_t client_addr_size;
993 int client_sd;
994 struct sockaddr_un addr;
995 struct sockaddr_un client_addr;
997 on = 1;
998 status = 0;
999 rc = 0;
1000 sd = 0;
1001 ucred_length = sizeof(struct ucred);
1002 client_sd = 0;
1003 client_addr_size = sizeof(struct sockaddr_un);
1005 memset(&buf, '\0', sizeof(buf));
1006 memset(&addr, '\0', sizeof(struct sockaddr_un));
1007 memset(&client_addr, '\0', sizeof(struct sockaddr_un));
1009 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1010 addr.sun_family = AF_UNIX;
1012 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1014 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
1015 if (rc == -1) {
1016 test_fail("bind() should have worked");
1019 rc = listen(sd, 8);
1020 if (rc == -1) {
1021 test_fail("listen(sd, 8) should have worked");
1024 /* we're ready for connections, time to tell the client to start
1025 * the test
1027 kill(pid, SIGUSR1);
1029 tv.tv_sec = 10;
1030 tv.tv_usec = 0;
1032 FD_ZERO(&readfds);
1033 FD_SET(sd, &readfds);
1035 /* use select() in case the client is really broken and never
1036 * attempts to connect (we don't want to block on accept()
1037 * forever).
1039 rc = select(sd + 1, &readfds, NULL, NULL, &tv);
1040 if (rc == -1) {
1041 test_fail("[server] select() should not have failed");
1044 if (rc != 1) {
1045 test_fail("[server] select() should have returned 1");
1046 printf("[server] select returned %d\n", rc);
1049 if (!(FD_ISSET(sd, &readfds))) {
1050 test_fail("[server] client didn't connect within 10 seconds");
1051 kill(pid, SIGKILL);
1052 return;
1055 client_sd = accept(sd, (struct sockaddr *) &client_addr,
1056 &client_addr_size);
1058 if (client_sd == -1) {
1059 test_fail("accept() should have worked");
1060 kill(pid, SIGKILL);
1061 return;
1062 } else {
1063 debug("[server] client accept()'d");
1066 debug("[server] Reading message");
1067 rc = read(client_sd, buf, sizeof(buf));
1068 if (rc == -1) {
1069 test_fail("read() failed unexpectedly");
1070 kill(pid, SIGKILL);
1071 return;
1073 debug("[server] we got the following message:");
1074 debug(buf);
1076 for (i = 0; i < rc && i < 127; i++) {
1077 buf[i] = toupper(buf[i]);
1080 debug("[server] Writing message...");
1081 rc = write(client_sd, buf, sizeof(buf));
1082 if (rc == -1) {
1083 test_fail("write(client_sd, buf, sizeof(buf)) failed");
1084 kill(pid, SIGKILL);
1085 return;
1088 if (rc < strlen(buf)) {
1089 test_fail("[server] write didn't write all the bytes");
1092 memset(&buf, '\0', sizeof(buf));
1094 debug("[server] Recv message");
1095 rc = recv(client_sd, buf, sizeof(buf), 0);
1096 if (rc == -1) {
1097 test_fail("recv() failed unexpectedly");
1098 kill(pid, SIGKILL);
1099 return;
1101 debug("[server] we got the following message:");
1102 debug(buf);
1104 for (i = 0; i < rc && i < 127; i++) {
1105 buf[i] = toupper(buf[i]);
1108 debug("[server] Sending message...");
1109 rc = send(client_sd, buf, sizeof(buf), 0);
1110 if (rc == -1) {
1111 test_fail("send(client_sd, buf, sizeof(buf), 0) failed");
1112 kill(pid, SIGKILL);
1113 return;
1116 if (rc < strlen(buf)) {
1117 test_fail("[server] write didn't write all the bytes");
1120 memset(&buf, '\0', sizeof(buf));
1122 debug("[server] Recvfrom message");
1123 rc = recvfrom(client_sd, buf, sizeof(buf), 0, NULL, 0);
1124 if (rc == -1) {
1125 test_fail("recvfrom() failed unexpectedly");
1126 kill(pid, SIGKILL);
1127 return;
1129 debug("[server] we got the following message:");
1130 debug(buf);
1132 for (i = 0; i < rc && i < 127; i++) {
1133 buf[i] = toupper(buf[i]);
1136 debug("[server] Sendto message...");
1137 rc = sendto(client_sd, buf, sizeof(buf), 0, NULL, 0);
1138 if (rc == -1) {
1139 test_fail("sendto() failed");
1140 kill(pid, SIGKILL);
1141 return;
1144 if (rc < strlen(buf)) {
1145 test_fail("[server] write didn't write all the bytes");
1148 shutdown(client_sd, SHUT_RDWR);
1149 CLOSE(client_sd);
1151 shutdown(sd, SHUT_RDWR);
1152 CLOSE(sd);
1154 /* wait for client to exit */
1155 do {
1156 errno = 0;
1157 rc = waitpid(pid, &status, 0);
1158 } while (rc == -1 && errno == EINTR);
1160 /* we use the exit status to get its error count */
1161 errct += WEXITSTATUS(status);
1164 int server_ready = 0;
1166 /* signal handler for the client */
1167 void test_xfer_sighdlr(int sig)
1169 debug("entering signal handler");
1170 switch (sig) {
1171 /* the server will send SIGUSR1 when it is time for us
1172 * to start the tests
1174 case SIGUSR1:
1175 server_ready = 1;
1176 debug("got SIGUSR1, the server is ready for the client");
1177 break;
1178 default:
1179 debug("didn't get SIGUSR1");
1181 debug("leaving signal handler");
1185 * A toupper() client.
1187 void test_xfer_client(void)
1189 struct ucred credentials;
1190 socklen_t ucred_length;
1191 struct timeval tv;
1192 fd_set readfds;
1193 struct sockaddr_un addr;
1194 struct sockaddr_un peer_addr;
1195 socklen_t peer_addr_len;
1196 int sd;
1197 int rc;
1198 char buf[BUFSIZE];
1200 debug("[client] entering test_xfer_client()");
1201 errct = 0; /* reset error count */
1202 ucred_length = sizeof(struct ucred);
1203 memset(&buf, '\0', sizeof(buf));
1205 while (server_ready == 0) {
1206 debug("[client] waiting for the server to signal");
1207 sleep(1);
1210 peer_addr_len = sizeof(struct sockaddr_un);
1213 debug("Creating symlink to TEST_SUN_PATH");
1215 SYMLINK(TEST_SUN_PATH, TEST_SYM_A);
1217 memset(&addr, '\0', sizeof(struct sockaddr_un));
1218 strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1);
1219 addr.sun_family = AF_UNIX;
1221 debug("[client] creating client socket");
1222 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1224 debug("[client] connecting to server through the symlink");
1225 rc = connect(sd, (struct sockaddr *) &addr,
1226 sizeof(struct sockaddr_un));
1227 if (rc == -1) {
1228 test_fail("[client] connect() should have worked");
1229 } else {
1230 debug("[client] connected");
1233 debug("[client] testing getpeername()");
1234 memset(&peer_addr, '\0', sizeof(struct sockaddr_un));
1235 rc = getpeername(sd, (struct sockaddr *) &peer_addr, &peer_addr_len);
1236 if (rc == -1) {
1237 test_fail("[client] getpeername() should have worked");
1240 /* we need to use the full path "/usr/src/test/DIR_56/test.sock"
1241 * because that is what is returned by getpeername().
1244 if (!(peer_addr.sun_family == AF_UNIX &&
1245 strncmp(peer_addr.sun_path,
1246 fullpath(TEST_SUN_PATH),
1247 sizeof(peer_addr.sun_path) - 1) == 0)) {
1249 test_fail("getpeername() didn't return the right address");
1252 strncpy(buf, "Hello, World!", sizeof(buf) - 1);
1253 debug("[client] send to server");
1254 rc = write(sd, buf, sizeof(buf));
1255 if (rc == -1) {
1256 test_fail("[client] write() failed unexpectedly");
1259 memset(buf, '\0', sizeof(buf));
1260 debug("[client] read from server");
1261 rc = read(sd, buf, sizeof(buf));
1262 if (rc == -1) {
1263 test_fail("[client] read() failed unexpectedly");
1264 } else {
1265 debug("[client] we got the following message:");
1266 debug(buf);
1269 if (strncmp(buf, "HELLO, WORLD!", sizeof(buf)) != 0) {
1270 test_fail("[client] We didn't get the correct response");
1273 memset(&buf, '\0', sizeof(buf));
1274 strncpy(buf, "Bonjour!", sizeof(buf) - 1);
1276 debug("[client] send to server");
1277 rc = send(sd, buf, sizeof(buf), 0);
1278 if (rc == -1) {
1279 test_fail("[client] send() failed unexpectedly");
1282 debug("Test passing the client credentials to the server");
1284 memset(&credentials, '\0', ucred_length);
1285 rc = getsockopt(sd, SOL_SOCKET, SO_PEERCRED, &credentials,
1286 &ucred_length);
1288 if (rc == -1) {
1289 test_fail("[client] getsockopt() failed");
1290 } else if (credentials.uid != geteuid() ||
1291 credentials.gid != getegid()) {
1292 printf("%d=%d=%d %d=%d=%d\n", credentials.uid, getuid(),
1293 geteuid(), credentials.gid, getgid(), getegid());
1294 test_fail("[client] Credential passing gave us a bad UID/GID");
1297 debug("Testing select()");
1299 tv.tv_sec = 2;
1300 tv.tv_usec = 500000;
1302 FD_ZERO(&readfds);
1303 FD_SET(sd, &readfds);
1305 rc = select(sd + 1, &readfds, NULL, NULL, &tv);
1306 if (rc == -1) {
1307 test_fail("[client] select() should not have failed");
1310 if (rc != 1) {
1311 test_fail("[client] select() should have returned 1");
1314 if (!(FD_ISSET(sd, &readfds))) {
1315 test_fail("The server didn't respond within 2.5 seconds");
1318 memset(buf, '\0', sizeof(buf));
1319 debug("[client] recv from server");
1320 rc = recv(sd, buf, sizeof(buf), 0);
1321 if (rc == -1) {
1322 test_fail("[client] recv() failed unexpectedly");
1323 } else {
1324 debug("[client] we got the following message:");
1325 debug(buf);
1328 if (strncmp(buf, "BONJOUR!", sizeof(buf)) != 0) {
1329 test_fail("[client] We didn't get the right response.");
1332 memset(&buf, '\0', sizeof(buf));
1333 strncpy(buf, "Hola!", sizeof(buf) - 1);
1335 debug("[client] sendto to server");
1336 rc = sendto(sd, buf, sizeof(buf), 0, NULL, 0);
1337 if (rc == -1) {
1338 test_fail("[client] sendto() failed");
1341 debug("Testing select()");
1343 tv.tv_sec = 2;
1344 tv.tv_usec = 500000;
1346 FD_ZERO(&readfds);
1347 FD_SET(sd, &readfds);
1349 rc = select(sd + 1, &readfds, NULL, NULL, &tv);
1350 if (rc == -1) {
1351 test_fail("[client] select() should not have failed");
1354 if (rc != 1) {
1355 test_fail("[client] select() should have returned 1");
1358 if (!(FD_ISSET(sd, &readfds))) {
1359 test_fail("[client] The server didn't respond in 2.5 seconds");
1362 memset(buf, '\0', sizeof(buf));
1363 debug("[client] recvfrom from server");
1364 rc = recvfrom(sd, buf, sizeof(buf), 0, NULL, 0);
1365 if (rc == -1) {
1366 test_fail("[cleint] recvfrom() failed unexpectedly");
1367 } else {
1368 debug("[client] we got the following message:");
1369 debug(buf);
1372 if (strncmp(buf, "HOLA!", sizeof(buf)) != 0) {
1373 test_fail("[client] We didn't get the right response.");
1376 debug("[client] closing socket");
1377 CLOSE(sd);
1379 debug("[client] leaving test_xfer_client()");
1380 exit(errct);
1383 void test_xfer(void)
1385 pid_t pid;
1387 UNLINK(TEST_SYM_A);
1388 UNLINK(TEST_SUN_PATH);
1390 /* the signal handler is only used by the client, but we have to
1391 * install it now. if we don't the server may signal the client
1392 * before the handler is installed.
1394 debug("installing signal handler");
1395 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1396 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1399 debug("signal handler installed");
1401 server_ready = 0;
1403 pid = fork();
1404 if (pid == -1) {
1405 test_fail("fork() failed");
1406 return;
1407 } else if (pid == 0) {
1408 debug("child");
1409 test_xfer_client();
1410 test_fail("we should never get here");
1411 exit(1);
1412 } else {
1413 debug("parent");
1414 test_xfer_server(pid);
1415 debug("parent done");
1418 UNLINK(TEST_SYM_A);
1419 UNLINK(TEST_SUN_PATH);
1422 void test_simple_client(int type)
1424 char buf[BUFSIZE];
1425 int sd, rc;
1426 struct sockaddr_un addr;
1428 sd = socket(PF_UNIX, type, 0);
1429 if (sd == -1) {
1430 test_fail("socket");
1431 exit(errct);
1434 while (server_ready == 0) {
1435 debug("[client] waiting for the server");
1436 sleep(1);
1439 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1440 addr.sun_family = AF_UNIX;
1442 bzero(buf, BUFSIZE);
1443 snprintf(buf, BUFSIZE-1, "Hello, My Name is Client.");
1445 if (type == SOCK_DGRAM) {
1447 rc = sendto(sd, buf, strlen(buf) + 1, 0,
1448 (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
1449 if (rc == -1) {
1450 test_fail("sendto");
1451 exit(errct);
1454 } else {
1456 rc = connect(sd, (struct sockaddr *) &addr,
1457 sizeof(struct sockaddr_un));
1458 if (rc == -1) {
1459 test_fail("connect");
1460 exit(errct);
1463 rc = write(sd, buf, strlen(buf) + 1);
1464 if (rc == -1) {
1465 test_fail("write");
1468 memset(buf, '\0', BUFSIZE);
1469 rc = read(sd, buf, BUFSIZE);
1470 if (rc == -1) {
1471 test_fail("read");
1474 if (strcmp("Hello, My Name is Server.", buf) != 0) {
1475 test_fail("didn't read the correct string");
1479 rc = close(sd);
1480 if (rc == -1) {
1481 test_fail("close");
1484 exit(errct);
1487 void test_simple_server(int type, pid_t pid)
1489 char buf[BUFSIZE];
1490 int sd, rc, client_sd, status;
1491 struct sockaddr_un addr;
1492 socklen_t addr_len;
1494 addr_len = sizeof(struct sockaddr_un);
1496 sd = socket(PF_UNIX, type, 0);
1497 if (sd == -1) {
1498 test_fail("socket");
1501 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1502 addr.sun_family = AF_UNIX;
1504 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
1505 if (rc == -1) {
1506 test_fail("bind");
1509 if (type == SOCK_DGRAM) {
1511 /* ready for client */
1512 kill(pid, SIGUSR1);
1514 rc = recvfrom(sd, buf, BUFSIZE, 0,
1515 (struct sockaddr *) &addr, &addr_len);
1516 if (rc == -1) {
1517 test_fail("recvfrom");
1520 } else {
1522 rc = listen(sd, 5);
1523 if (rc == -1) {
1524 test_fail("listen");
1527 /* we're ready for connections, time to tell the client
1528 * to start the test
1530 kill(pid, SIGUSR1);
1532 client_sd = accept(sd, (struct sockaddr *) &addr, &addr_len);
1533 if (client_sd == -1) {
1534 test_fail("accept");
1537 memset(buf, '\0', BUFSIZE);
1538 rc = read(client_sd, buf, BUFSIZE);
1539 if (rc == -1) {
1540 test_fail("read");
1543 if (strcmp("Hello, My Name is Client.", buf) != 0) {
1544 test_fail("didn't read the correct string");
1547 /* added for extra fun to make the client block on read() */
1548 sleep(1);
1550 bzero(buf, BUFSIZE);
1551 snprintf(buf, BUFSIZE-1, "Hello, My Name is Server.");
1553 rc = write(client_sd, buf, strlen(buf) + 1);
1554 if (rc == -1) {
1555 test_fail("write");
1558 rc = close(client_sd);
1559 if (rc == -1) {
1560 test_fail("close");
1565 rc = close(sd);
1566 if (rc == -1) {
1567 test_fail("close");
1570 /* wait for client to exit */
1571 do {
1572 errno = 0;
1573 rc = waitpid(pid, &status, 0);
1574 } while (rc == -1 && errno == EINTR);
1576 /* we use the exit status to get its error count */
1577 errct += WEXITSTATUS(status);
1580 void test_simple_client_server(int type)
1582 pid_t pid;
1584 debug("test_simple_client_server()");
1586 UNLINK(TEST_SUN_PATH);
1588 /* the signal handler is only used by the client, but we have to
1589 * install it now. if we don't the server may signal the client
1590 * before the handler is installed.
1592 debug("installing signal handler");
1593 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1594 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1597 debug("signal handler installed");
1599 server_ready = 0;
1601 pid = fork();
1602 if (pid == -1) {
1603 test_fail("fork() failed");
1604 return;
1605 } else if (pid == 0) {
1606 debug("child");
1607 test_simple_client(type);
1608 test_fail("we should never get here");
1609 exit(1);
1610 } else {
1611 debug("parent");
1612 test_simple_server(type, pid);
1613 debug("parent done");
1616 UNLINK(TEST_SUN_PATH);
1619 void test_vectorio(int type)
1621 int sv[2];
1622 int rc;
1623 struct iovec iov[3];
1624 char buf1[BUFSIZE];
1625 char buf2[BUFSIZE];
1626 char buf3[BUFSIZE];
1627 char buf4[BUFSIZE*3];
1628 const struct iovec *iovp = iov;
1630 debug("begin vectorio tests");
1632 memset(buf1, '\0', BUFSIZE);
1633 strncpy(buf1, "HELLO ", BUFSIZE - 1);
1635 memset(buf2, '\0', BUFSIZE);
1636 strncpy(buf2, "WORLD", BUFSIZE - 1);
1638 memset(buf3, '\0', BUFSIZE);
1640 rc = socketpair(PF_UNIX, type, 0, sv);
1641 if (rc == -1) {
1642 test_fail("socketpair");
1645 iov[0].iov_base = buf1;
1646 iov[0].iov_len = strlen(buf1);
1647 iov[1].iov_base = buf2;
1648 iov[1].iov_len = strlen(buf2);
1649 iov[2].iov_base = buf3;
1650 iov[2].iov_len = 1;
1652 rc = writev(sv[0], iovp, 3);
1653 if (rc == -1) {
1654 test_fail("writev");
1657 memset(buf4, '\0', BUFSIZE*3);
1659 rc = read(sv[1], buf4, BUFSIZE*3);
1660 if (rc == -1) {
1661 test_fail("read");
1664 if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
1665 test_fail("the string we read was not 'HELLO WORLD'");
1668 memset(buf1, '\0', BUFSIZE);
1669 strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
1671 rc = write(sv[1], buf1, strlen(buf1) + 1);
1672 if (rc == -1) {
1673 test_fail("write");
1676 memset(buf2, '\0', BUFSIZE);
1677 memset(buf3, '\0', BUFSIZE);
1678 memset(buf4, '\0', BUFSIZE*3);
1680 iov[0].iov_base = buf2;
1681 iov[0].iov_len = 5;
1682 iov[1].iov_base = buf3;
1683 iov[1].iov_len = 5;
1684 iov[2].iov_base = buf4;
1685 iov[2].iov_len = 32;
1687 rc = readv(sv[0], iovp, 3);
1688 if (rc == -1) {
1689 test_fail("readv");
1692 if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
1693 strncmp(buf4, "Time", 4)) {
1694 test_fail("readv");
1697 rc = close(sv[0]);
1698 if (rc == -1) {
1699 test_fail("close");
1702 rc = close(sv[1]);
1703 if (rc == -1) {
1704 test_fail("close");
1707 debug("done vector io tests");
1710 void test_msg(int type)
1712 int sv[2];
1713 int rc;
1714 struct msghdr msg1;
1715 struct msghdr msg2;
1716 struct iovec iov[3];
1717 char buf1[BUFSIZE];
1718 char buf2[BUFSIZE];
1719 char buf3[BUFSIZE];
1720 char buf4[BUFSIZE*3];
1722 debug("begin sendmsg/recvmsg tests");
1724 memset(buf1, '\0', BUFSIZE);
1725 strncpy(buf1, "HELLO ", BUFSIZE - 1);
1727 memset(buf2, '\0', BUFSIZE);
1728 strncpy(buf2, "WORLD", BUFSIZE - 1);
1730 memset(buf3, '\0', BUFSIZE);
1732 rc = socketpair(PF_UNIX, type, 0, sv);
1733 if (rc == -1) {
1734 test_fail("socketpair");
1737 iov[0].iov_base = buf1;
1738 iov[0].iov_len = strlen(buf1);
1739 iov[1].iov_base = buf2;
1740 iov[1].iov_len = strlen(buf2);
1741 iov[2].iov_base = buf3;
1742 iov[2].iov_len = 1;
1744 memset(&msg1, '\0', sizeof(struct msghdr));
1745 msg1.msg_name = NULL;
1746 msg1.msg_namelen = 0;
1747 msg1.msg_iov = iov;
1748 msg1.msg_iovlen = 3;
1749 msg1.msg_control = NULL;
1750 msg1.msg_controllen = 0;
1751 msg1.msg_flags = 0;
1753 rc = sendmsg(sv[0], &msg1, 0);
1754 if (rc == -1) {
1755 test_fail("writev");
1758 memset(buf4, '\0', BUFSIZE*3);
1760 rc = read(sv[1], buf4, BUFSIZE*3);
1761 if (rc == -1) {
1762 test_fail("read");
1765 if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
1766 test_fail("the string we read was not 'HELLO WORLD'");
1769 memset(buf1, '\0', BUFSIZE);
1770 strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
1772 rc = write(sv[1], buf1, strlen(buf1) + 1);
1773 if (rc == -1) {
1774 test_fail("write");
1777 memset(buf2, '\0', BUFSIZE);
1778 memset(buf3, '\0', BUFSIZE);
1779 memset(buf4, '\0', BUFSIZE*3);
1781 iov[0].iov_base = buf2;
1782 iov[0].iov_len = 5;
1783 iov[1].iov_base = buf3;
1784 iov[1].iov_len = 5;
1785 iov[2].iov_base = buf4;
1786 iov[2].iov_len = 32;
1788 memset(&msg2, '\0', sizeof(struct msghdr));
1789 msg2.msg_name = NULL;
1790 msg2.msg_namelen = 0;
1791 msg2.msg_iov = iov;
1792 msg2.msg_iovlen = 3;
1793 msg2.msg_control = NULL;
1794 msg2.msg_controllen = 0;
1795 msg2.msg_flags = 0;
1797 rc = recvmsg(sv[0], &msg2, 0);
1798 if (rc == -1) {
1799 test_fail("readv");
1802 if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
1803 strncmp(buf4, "Time", 4)) {
1804 test_fail("readv");
1807 rc = close(sv[0]);
1808 if (rc == -1) {
1809 test_fail("close");
1812 rc = close(sv[1]);
1813 if (rc == -1) {
1814 test_fail("close");
1818 void test_msg_dgram(void)
1820 int rc;
1821 int src;
1822 int dst;
1823 struct sockaddr_un addr;
1824 struct iovec iov[3];
1825 struct msghdr msg1;
1826 struct msghdr msg2;
1827 char buf1[BUFSIZE];
1828 char buf2[BUFSIZE];
1829 char buf3[BUFSIZE];
1830 socklen_t addrlen = sizeof(struct sockaddr_un);
1832 debug("test msg_dgram");
1834 UNLINK(TEST_SUN_PATH);
1835 UNLINK(TEST_SUN_PATHB);
1837 src = socket(PF_UNIX, SOCK_DGRAM, 0);
1838 if (src == -1) {
1839 test_fail("socket");
1842 dst = socket(PF_UNIX, SOCK_DGRAM, 0);
1843 if (dst == -1) {
1844 test_fail("socket");
1847 memset(&addr, '\0', sizeof(struct sockaddr_un));
1848 addr.sun_family = AF_UNIX;
1849 strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1);
1850 rc = bind(src, (struct sockaddr *) &addr, addrlen);
1851 if (rc == -1) {
1852 test_fail("bind");
1855 memset(&addr, '\0', sizeof(struct sockaddr_un));
1856 addr.sun_family = AF_UNIX;
1857 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1859 rc = bind(dst, (struct sockaddr *) &addr, addrlen);
1860 if (rc == -1) {
1861 test_fail("bind");
1864 memset(&buf1, '\0', BUFSIZE);
1865 memset(&buf2, '\0', BUFSIZE);
1866 memset(&buf3, '\0', BUFSIZE);
1868 strncpy(buf1, "Minix ", BUFSIZE-1);
1869 strncpy(buf2, "is ", BUFSIZE-1);
1870 strncpy(buf3, "great!", BUFSIZE-1);
1872 iov[0].iov_base = buf1;
1873 iov[0].iov_len = 6;
1874 iov[1].iov_base = buf2;
1875 iov[1].iov_len = 3;
1876 iov[2].iov_base = buf3;
1877 iov[2].iov_len = 32;
1879 memset(&msg1, '\0', sizeof(struct msghdr));
1880 msg1.msg_name = &addr;
1881 msg1.msg_namelen = addrlen;
1882 msg1.msg_iov = iov;
1883 msg1.msg_iovlen = 3;
1884 msg1.msg_control = NULL;
1885 msg1.msg_controllen = 0;
1886 msg1.msg_flags = 0;
1888 rc = sendmsg(src, &msg1, 0);
1889 if (rc == -1) {
1890 test_fail("sendmsg");
1893 memset(&buf1, '\0', BUFSIZE);
1894 memset(&buf2, '\0', BUFSIZE);
1896 iov[0].iov_base = buf1;
1897 iov[0].iov_len = 9;
1898 iov[1].iov_base = buf2;
1899 iov[1].iov_len = 32;
1901 memset(&addr, '\0', sizeof(struct sockaddr_un));
1902 memset(&msg2, '\0', sizeof(struct msghdr));
1903 msg2.msg_name = &addr;
1904 msg2.msg_namelen = sizeof(struct sockaddr_un);
1905 msg2.msg_iov = iov;
1906 msg2.msg_iovlen = 2;
1907 msg2.msg_control = NULL;
1908 msg2.msg_controllen = 0;
1909 msg2.msg_flags = 0;
1911 rc = recvmsg(dst, &msg2, 0);
1912 if (rc == -1) {
1913 test_fail("recvmsg");
1916 if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
1917 test_fail("recvmsg");
1920 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
1921 * because that is what is returned by recvmsg().
1923 if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path,
1924 fullpath(TEST_SUN_PATHB))) {
1925 test_fail("recvmsg");
1928 rc = close(dst);
1929 if (rc == -1) {
1930 test_fail("close");
1933 rc = close(src);
1934 if (rc == -1) {
1935 test_fail("close");
1938 UNLINK(TEST_SUN_PATH);
1939 UNLINK(TEST_SUN_PATHB);
1942 void test_scm_credentials(void)
1944 int rc;
1945 int src;
1946 int dst;
1947 struct ucred cred;
1948 struct cmsghdr *cmsg = NULL;
1949 struct sockaddr_un addr;
1950 struct iovec iov[3];
1951 struct msghdr msg1;
1952 struct msghdr msg2;
1953 char buf1[BUFSIZE];
1954 char buf2[BUFSIZE];
1955 char buf3[BUFSIZE];
1956 char ctrl[BUFSIZE];
1957 socklen_t addrlen = sizeof(struct sockaddr_un);
1959 debug("test_scm_credentials");
1961 UNLINK(TEST_SUN_PATH);
1962 UNLINK(TEST_SUN_PATHB);
1964 debug("creating src socket");
1966 src = socket(PF_UNIX, SOCK_DGRAM, 0);
1967 if (src == -1) {
1968 test_fail("socket");
1971 debug("creating dst socket");
1973 dst = socket(PF_UNIX, SOCK_DGRAM, 0);
1974 if (dst == -1) {
1975 test_fail("socket");
1978 debug("binding src socket");
1980 memset(&addr, '\0', sizeof(struct sockaddr_un));
1981 addr.sun_family = AF_UNIX;
1982 strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1);
1983 rc = bind(src, (struct sockaddr *) &addr, addrlen);
1984 if (rc == -1) {
1985 test_fail("bind");
1988 debug("binding dst socket");
1990 memset(&addr, '\0', sizeof(struct sockaddr_un));
1991 addr.sun_family = AF_UNIX;
1992 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1994 rc = bind(dst, (struct sockaddr *) &addr, addrlen);
1995 if (rc == -1) {
1996 test_fail("bind");
1999 memset(&buf1, '\0', BUFSIZE);
2000 memset(&buf2, '\0', BUFSIZE);
2001 memset(&buf3, '\0', BUFSIZE);
2002 memset(&ctrl, '\0', BUFSIZE);
2004 strncpy(buf1, "Minix ", BUFSIZE-1);
2005 strncpy(buf2, "is ", BUFSIZE-1);
2006 strncpy(buf3, "great!", BUFSIZE-1);
2008 iov[0].iov_base = buf1;
2009 iov[0].iov_len = 6;
2010 iov[1].iov_base = buf2;
2011 iov[1].iov_len = 3;
2012 iov[2].iov_base = buf3;
2013 iov[2].iov_len = 32;
2015 memset(&msg1, '\0', sizeof(struct msghdr));
2016 msg1.msg_name = &addr;
2017 msg1.msg_namelen = addrlen;
2018 msg1.msg_iov = iov;
2019 msg1.msg_iovlen = 3;
2020 msg1.msg_control = NULL;
2021 msg1.msg_controllen = 0;
2022 msg1.msg_flags = 0;
2024 debug("sending msg1");
2026 rc = sendmsg(src, &msg1, 0);
2027 if (rc == -1) {
2028 test_fail("sendmsg");
2031 memset(&buf1, '\0', BUFSIZE);
2032 memset(&buf2, '\0', BUFSIZE);
2033 memset(&buf3, '\0', BUFSIZE);
2034 memset(&ctrl, '\0', BUFSIZE);
2036 iov[0].iov_base = buf1;
2037 iov[0].iov_len = 9;
2038 iov[1].iov_base = buf2;
2039 iov[1].iov_len = 32;
2041 memset(&addr, '\0', sizeof(struct sockaddr_un));
2042 memset(&msg2, '\0', sizeof(struct msghdr));
2043 msg2.msg_name = &addr;
2044 msg2.msg_namelen = sizeof(struct sockaddr_un);
2045 msg2.msg_iov = iov;
2046 msg2.msg_iovlen = 2;
2047 msg2.msg_control = ctrl;
2048 msg2.msg_controllen = BUFSIZE;
2049 msg2.msg_flags = 0;
2051 debug("recv msg2");
2053 rc = recvmsg(dst, &msg2, 0);
2054 if (rc == -1) {
2055 test_fail("recvmsg");
2058 debug("checking results");
2060 if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
2061 test_fail("recvmsg");
2064 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
2065 * because that is what is returned by recvmsg().
2067 if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path,
2068 fullpath(TEST_SUN_PATHB))) {
2069 test_fail("recvmsg");
2072 debug("looking for credentials");
2074 memset(&cred, '\0', sizeof(struct ucred));
2075 for (cmsg = CMSG_FIRSTHDR(&msg2); cmsg != NULL;
2076 cmsg = CMSG_NXTHDR(&msg2, cmsg)) {
2078 if (cmsg->cmsg_level == SOL_SOCKET &&
2079 cmsg->cmsg_type == SCM_CREDENTIALS) {
2081 memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct ucred));
2082 break;
2086 if (cred.pid != getpid() || cred.uid != geteuid() ||
2087 cred.gid != getegid()) {
2089 test_fail("did no receive the proper credentials");
2092 rc = close(dst);
2093 if (rc == -1) {
2094 test_fail("close");
2097 rc = close(src);
2098 if (rc == -1) {
2099 test_fail("close");
2102 UNLINK(TEST_SUN_PATH);
2103 UNLINK(TEST_SUN_PATHB);
2106 void test_connect(void)
2108 int i, sd, sds[2], rc;
2110 /* connect() is already tested throughout test56, but
2111 * in most cases the client and server end up on /dev/uds
2112 * minor 0 and minor 1. This test opens some sockets first and
2113 * then calls test_simple_client_server(). This forces the
2114 * client and server minor numbers higher in the descriptor table.
2117 debug("starting test_connect()");
2119 sd = socket(AF_UNIX, SOCK_DGRAM, 0);
2120 if (sd == -1) {
2121 test_fail("couldn't create a socket");
2124 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sds);
2125 if (rc == -1) {
2126 test_fail("couldn't create a socketpair");
2129 for (i = 0; i < 3; i++) {
2130 test_simple_client_server(types[i]);
2133 rc = close(sds[1]);
2134 if (rc == -1) {
2135 test_fail("close() failed");
2138 rc = close(sds[0]);
2139 if (rc == -1) {
2140 test_fail("close() failed");
2143 rc = close(sd);
2144 if (rc == -1) {
2145 test_fail("close() failed");
2148 debug("exiting test_connect()");
2151 int test_multiproc_read(void)
2153 /* test that when we fork() a process with an open socket descriptor,
2154 * the descriptor in each process points to the same thing.
2157 pid_t pid;
2158 int sds[2];
2159 int rc, status;
2160 char buf[3];
2162 debug("entering test_multiproc_read()");
2164 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
2165 if (rc == -1) {
2166 test_fail("socketpair");
2167 return 1;
2170 memset(buf, '\0', 3);
2173 /* the signal handler is only used by the client, but we have to
2174 * install it now. if we don't the server may signal the client
2175 * before the handler is installed.
2177 debug("installing signal handler");
2178 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
2179 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2180 return 1;
2183 debug("signal handler installed");
2185 server_ready = 0;
2187 pid = fork();
2189 if (pid == -1) {
2191 test_fail("fork");
2192 return 1;
2194 } else if (pid == 0) {
2196 while (server_ready == 0) {
2197 debug("waiting for SIGUSR1 from parent");
2198 sleep(1);
2201 rc = read(sds[1], buf, 2);
2202 if (rc == -1) {
2203 test_fail("read");
2204 exit(1);
2207 if (!(buf[0] == 'X' && buf[1] == '3')) {
2208 test_fail("Didn't read X3");
2209 exit(1);
2212 exit(0);
2213 } else {
2215 rc = write(sds[0], "MNX3", 4);
2216 if (rc == -1) {
2217 test_fail("write");
2220 rc = read(sds[1], buf, 2);
2221 if (rc == -1) {
2222 test_fail("read");
2225 if (!(buf[0] == 'M' && buf[1] == 'N')) {
2226 test_fail("Didn't read MN");
2229 /* time to tell the client to start the test */
2230 kill(pid, SIGUSR1);
2232 do {
2233 rc = waitpid(pid, &status, 0);
2234 } while (rc == -1 && errno == EINTR);
2236 /* we use the exit status to get its error count */
2237 errct += WEXITSTATUS(status);
2240 return 0;
2243 int test_multiproc_write(void)
2245 /* test that when we fork() a process with an open socket descriptor,
2246 * the descriptor in each process points to the same thing.
2249 pid_t pid;
2250 int sds[2];
2251 int rc, status;
2252 char buf[7];
2254 debug("entering test_multiproc_write()");
2256 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
2257 if (rc == -1) {
2258 test_fail("socketpair");
2259 return 1;
2262 memset(buf, '\0', 7);
2265 /* the signal handler is only used by the client, but we have to
2266 * install it now. if we don't the server may signal the client
2267 * before the handler is installed.
2269 debug("installing signal handler");
2270 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
2271 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2272 return 1;
2275 debug("signal handler installed");
2277 server_ready = 0;
2279 pid = fork();
2281 if (pid == -1) {
2283 test_fail("fork");
2284 return 1;
2286 } else if (pid == 0) {
2288 while (server_ready == 0) {
2289 debug("waiting for SIGUSR1 from parent");
2290 sleep(1);
2293 rc = write(sds[1], "IX3", 3);
2294 if (rc == -1) {
2295 test_fail("write");
2296 exit(1);
2299 rc = read(sds[0], buf, 6);
2300 if (rc == -1) {
2301 test_fail("read");
2302 exit(1);
2305 if (strcmp(buf, "MINIX3") != 0) {
2306 test_fail("didn't read MINIX3");
2307 exit(1);
2310 exit(0);
2311 } else {
2313 rc = write(sds[1], "MIN", 3);
2314 if (rc == -1) {
2315 test_fail("write");
2318 /* time to tell the client to start the test */
2319 kill(pid, SIGUSR1);
2321 do {
2322 rc = waitpid(pid, &status, 0);
2323 } while (rc == -1 && errno == EINTR);
2325 /* we use the exit status to get its error count */
2326 errct += WEXITSTATUS(status);
2329 return 0;
2332 void test_fd_passing_child(int sd)
2334 int fd, rc;
2335 char x = 'x';
2336 struct msghdr msghdr;
2337 struct cmsghdr *cmsg;
2338 struct iovec iov;
2339 char buf[BUFSIZE];
2341 memset(buf, '\0', BUFSIZE);
2343 fd = open(TEST_TXT_FILE, O_CREAT|O_TRUNC|O_RDWR);
2344 if (fd == -1) {
2345 test_fail("could not open test.txt");
2348 msghdr.msg_name = NULL;
2349 msghdr.msg_namelen = 0;
2351 iov.iov_base = &x;
2352 iov.iov_len = 1;
2353 msghdr.msg_iov = &iov;
2354 msghdr.msg_iovlen = 1;
2356 msghdr.msg_control = buf;
2357 msghdr.msg_controllen = CMSG_SPACE(sizeof(int));
2359 msghdr.msg_flags = 0;
2361 cmsg = CMSG_FIRSTHDR(&msghdr);
2362 cmsg->cmsg_len = CMSG_SPACE(sizeof(int));
2363 cmsg->cmsg_level = SOL_SOCKET;
2364 cmsg->cmsg_type = SCM_RIGHTS;
2366 ((int *) CMSG_DATA(cmsg))[0] = fd;
2368 rc = sendmsg(sd, &msghdr, 0);
2369 if (rc == -1) {
2370 test_fail("could not send message");
2373 memset(buf, '\0', BUFSIZE);
2374 rc = read(sd, buf, BUFSIZE);
2375 if (rc == -1) {
2376 test_fail("could not read from socket");
2379 if (strcmp(buf, "done") != 0) {
2380 test_fail("we didn't read the right message");
2383 memset(buf, '\0', BUFSIZE);
2384 rc = lseek(fd, 0, SEEK_SET);
2385 if (rc == -1) {
2386 test_fail("could not seek to start of test.txt");
2389 rc = read(fd, buf, BUFSIZE);
2390 if (rc == -1) {
2391 test_fail("could not read from test.txt");
2394 if (strcmp(buf, MSG) != 0) {
2395 test_fail("other process didn't write MSG to test.txt");
2398 rc = close(fd);
2399 if (rc == -1) {
2400 test_fail("could not close test.txt");
2403 rc = close(sd);
2404 if (rc == -1) {
2405 test_fail("could not close socket");
2408 rc = unlink(TEST_TXT_FILE);
2409 if (rc == -1) {
2410 test_fail("could not unlink test.txt");
2413 exit(errct);
2416 void test_fd_passing_parent(int sd)
2418 int rc, fd;
2419 char x;
2420 struct msghdr msghdr;
2421 struct cmsghdr *cmsg;
2422 struct iovec iov;
2423 char buf[BUFSIZE];
2425 memset(buf, '\0', BUFSIZE);
2427 msghdr.msg_name = NULL;
2428 msghdr.msg_namelen = 0;
2430 iov.iov_base = &x;
2431 iov.iov_len = 1;
2432 msghdr.msg_iov = &iov;
2433 msghdr.msg_iovlen = 1;
2435 msghdr.msg_iov = &iov;
2436 msghdr.msg_iovlen = 1;
2438 msghdr.msg_control = buf;
2439 msghdr.msg_controllen = BUFSIZE;
2441 msghdr.msg_flags = 0;
2443 rc = recvmsg(sd, &msghdr, 0);
2444 if (rc == -1) {
2445 test_fail("could not recv message.");
2448 cmsg = CMSG_FIRSTHDR(&msghdr);
2449 fd = ((int *) CMSG_DATA(cmsg))[0];
2451 rc = write(fd, MSG, strlen(MSG));
2452 if (rc != strlen(MSG)) {
2453 test_fail("could not write the full message to test.txt");
2456 rc = close(fd);
2457 if (rc == -1) {
2458 test_fail("could not close test.txt");
2461 memset(buf, '\0', BUFSIZE);
2462 strcpy(buf, "done");
2463 rc = write(sd, buf, BUFSIZE);
2464 if (rc == -1) {
2465 test_fail("could not write to socket");
2468 rc = close(sd);
2469 if (rc == -1) {
2470 test_fail("could not close socket");
2474 void test_permissions(void) {
2475 /* Test bind and connect for permission verification
2477 * After creating a UDS socket we change user credentials. At that
2478 * point we should not be allowed to bind or connect to the UDS socket
2481 pid_t pid;
2482 int sd, rc, status;
2483 struct sockaddr_un addr;
2484 socklen_t client_addr_size;
2486 client_addr_size = sizeof(struct sockaddr_un);
2488 memset(&addr, '\0', sizeof(struct sockaddr_un));
2489 addr.sun_family = AF_UNIX;
2490 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
2492 UNLINK(TEST_SUN_PATH);
2494 pid = fork();
2495 if (pid < 0) test_fail("unable to fork");
2496 else if (pid == 0) {
2497 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
2498 if (setuid(999) != 0) test_fail("unable to chance uid");
2499 rc = bind(sd, (struct sockaddr *) &addr,
2500 sizeof(struct sockaddr_un));
2501 if (rc != -1) {
2502 test_fail("bind() should not have worked");
2504 exit(errct);
2505 } else {
2506 rc = waitpid(pid, &status, 0);
2507 errct += WEXITSTATUS(status);
2510 /* the signal handler is only used by the client, but we have to
2511 * install it now. if we don't the server may signal the client
2512 * before the handler is installed.
2514 debug("installing signal handler");
2515 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
2516 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2519 debug("signal handler installed");
2521 server_ready = 0;
2523 pid = fork();
2524 if (pid < 0) test_fail("unable to fork");
2525 else if (pid == 0) {
2526 while (server_ready == 0) {
2527 debug("[client] waiting for the server to signal");
2528 sleep(1);
2530 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
2531 if (setuid(999) != 0) test_fail("unable to chance uid");
2532 rc = connect(sd, (struct sockaddr *) &addr,
2533 sizeof(struct sockaddr_un));
2534 if (rc != -1)
2535 test_fail("connect should not have worked");
2536 exit(errct);
2537 } else {
2538 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
2539 rc = bind(sd, (struct sockaddr *) &addr,
2540 sizeof(struct sockaddr_un));
2541 if (rc == -1) {
2542 test_fail("bind() should have worked");
2545 rc = listen(sd, 8);
2546 if (rc == -1) {
2547 test_fail("listen(sd, 8) should have worked");
2549 kill(pid, SIGUSR1);
2550 sleep(1);
2551 CLOSE(sd);
2553 rc = waitpid(pid, &status, 0);
2554 errct += WEXITSTATUS(status);
2557 UNLINK(TEST_SUN_PATH);
2560 void test_fd_passing(void) {
2561 int status;
2562 int sv[2];
2563 pid_t pid;
2564 int rc;
2566 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
2567 if (rc == -1) {
2568 test_fail("socketpair failed");
2571 pid = fork();
2572 if (pid == -1) {
2573 test_fail("fork() failed");
2575 rc = close(sv[0]);
2576 if (rc == -1) {
2577 test_fail("could not close sv[0]");
2580 rc = close(sv[1]);
2581 if (rc == -1) {
2582 test_fail("could not close sv[1]");
2585 exit(0);
2586 } else if (pid == 0) {
2587 rc = close(sv[0]);
2588 if (rc == -1) {
2589 test_fail("could not close sv[0]");
2592 test_fd_passing_child(sv[1]);
2593 test_fail("should never get here");
2594 exit(1);
2595 } else {
2596 rc = close(sv[1]);
2597 if (rc == -1) {
2598 test_fail("could not close sv[1]");
2601 test_fd_passing_parent(sv[0]);
2603 /* wait for client to exit */
2604 do {
2605 errno = 0;
2606 rc = waitpid(pid, &status, 0);
2607 } while (rc == -1 && errno == EINTR);
2609 /* we use the exit status to get its error count */
2610 errct += WEXITSTATUS(status);
2614 int main(int argc, char *argv[])
2616 int i;
2618 debug("entering main()");
2620 start(56);
2622 test_socket();
2623 test_bind();
2624 test_listen();
2625 test_getsockname();
2626 test_header();
2627 test_shutdown();
2628 test_close();
2629 test_permissions();
2630 test_dup();
2631 test_dup2();
2632 test_socketpair();
2633 test_shutdown();
2634 test_read();
2635 test_write();
2636 test_sockopts();
2637 test_ucred();
2638 test_xfer();
2640 for (i = 0; i < 3; i++) {
2641 test_simple_client_server(types[i]);
2642 if (types[i] != SOCK_DGRAM) test_vectorio(types[i]);
2643 if (types[i] != SOCK_DGRAM) test_msg(types[i]);
2646 test_msg_dgram();
2647 test_connect();
2648 test_multiproc_read();
2649 test_multiproc_write();
2650 test_scm_credentials();
2651 test_fd_passing();
2652 quit();
2654 return -1; /* we should never get here */