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()
47 #include <sys/socket.h>
50 #include <sys/types.h>
57 /* Maximum number of errors that we'll allow to occur before this test
58 * program gives us and quits.
62 /* Use the common testing code instead of reinventing the wheel. */
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 */
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)
95 len
= sizeof(char) * 32;
106 s
= (char *) malloc(len
);
111 memset(s
, '\0', len
);
113 strftime(s
, len
- 1, ISO8601_FORMAT
, tm
);
117 /* macro to display information about a failed test and increment the errct */
118 #define test_fail(msg) \
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)); \
127 if (timestamp != NULL) { \
132 if (errct++ > MAX_ERROR) { \
133 printf("Too many errors; test aborted\n"); \
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
);
153 /* macros to display debugging information */
157 timestamp = get_timestamp(); \
158 fprintf(stdout,"[DEBUG][%s] (%s:%d) %s [pid=%d]\n", \
159 timestamp, __FILE__, __LINE__, msg, getpid()); \
161 if (timestamp != NULL) { \
168 do { /* nothing */; } while (0)
171 #define SOCKET(sd,domain,type,protocol) \
174 sd = socket(domain, type, protocol); \
176 test_fail("sd = socket(domain, type, protocol) failed");\
180 #define UNLINK(path) \
185 if (rc == -1 && errno != ENOENT) { \
186 test_fail("unlink(path) failed"); \
190 #define SYMLINK(oldpath,newpath) \
194 rc = symlink(oldpath,newpath); \
196 test_fail("symlink(oldpath,newpath) failed"); \
206 test_fail("close(sd) failed"); \
210 void test_socket(void)
212 struct stat statbuf
, statbuf2
;
217 debug("entering test_socket()");
219 debug("Test socket() with an unsupported address family");
222 sd
= socket(-1, SOCK_STREAM
, 0);
223 if (!(sd
== -1 && errno
== EAFNOSUPPORT
)) {
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
);
235 test_fail("we couldn't open /dev/null for read");
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");
248 for (i
= 3; i
< getdtablesize(); i
++) {
252 debug("Test socket() with an mismatched protocol");
255 sd
= socket(PF_UNIX
, SOCK_STREAM
, 4);
256 if (!(sd
== -1 && errno
== EPROTONOSUPPORT
)) {
257 test_fail("socket() should fail with errno = EPROTONOSUPPORT");
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
);
275 test_fail("fstat failed on sd");
278 rc
= fstat(sd2
, &statbuf2
);
280 test_fail("fstat failed on sd2");
284 if (statbuf
.st_dev
== statbuf2
.st_dev
) {
285 test_fail("/dev/uds isn't being cloned");
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)
317 struct sockaddr_un addr
;
318 int socket_vector
[2];
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
);
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
));
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
));
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
);
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
++) {
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();
395 debug("Test credentials passing");
397 ucred_length
= sizeof(struct ucred
);
399 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sv
);
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
,
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
);
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");
428 void test_getsockname(void)
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
));
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
);
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
,
468 struct sockaddr_un addr
;
469 struct sockaddr_un sock_addr
;
470 socklen_t sock_addr_len
;
476 debug("entering test_bind()");
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
));
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
);
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
,
511 debug("Test bind() with a address that has already been bind()'d");
513 SOCKET(sd2
, PF_UNIX
, SOCK_STREAM
, 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");
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
));
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");
535 debug("Test bind() with a NULL address");
537 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 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");
545 debug("Test bind() using a symlink loop");
547 UNLINK(TEST_SUN_PATH
);
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);
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");
564 UNLINK(TEST_SUN_PATH
);
568 debug("leaving test_bind()");
571 void test_listen(void)
575 debug("entering test_listen()");
577 debug("Test listen() with a bad file descriptor");
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");
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
};
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");
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");
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);
628 rc
= shutdown(sd
, how
[i
]);
629 if (!(rc
== -1 && errno
== ENOTCONN
)) {
630 test_fail("shutdown() should have failed");
635 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
637 rc
= shutdown(sd
, -1);
638 if (!(rc
== -1 && errno
== ENOTCONN
)) {
639 test_fail("shutdown(sd, -1) should have failed with ENOTCONN");
643 debug("leaving test_shutdown()");
646 void test_close(void)
648 struct sockaddr_un addr
;
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
));
665 test_fail("bind() should have worked");
670 debug("Close an already closed file descriptor");
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
));
685 test_fail("bind() should have worked");
691 test_fail("dup(sd) should have worked");
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);
709 debug("leaving test_close()");
712 void test_sockopts(void)
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");
729 option_len
= sizeof(option_value
);
731 rc
= getsockopt(sd
, SOL_SOCKET
, SO_TYPE
, &option_value
,
734 test_fail("setsockopt() should have worked");
737 if (option_value
!= types
[i
]) {
738 test_fail("SO_TYPE didn't seem to work.");
746 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
748 debug("Test setsockopt() works");
751 option_len
= sizeof(option_value
);
753 rc
= getsockopt(sd
, SOL_SOCKET
, SO_SNDBUF
, &option_value
, &option_len
);
755 test_fail("getsockopt() should have worked");
758 if (option_value
!= PIPE_BUF
) {
759 test_fail("SO_SNDBUF didn't seem to work.");
765 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
767 debug("Test setsockopt() works");
770 option_len
= sizeof(option_value
);
772 rc
= getsockopt(sd
, SOL_SOCKET
, SO_RCVBUF
, &option_value
, &option_len
);
774 test_fail("getsockopt() should have worked");
777 if (option_value
!= PIPE_BUF
) {
778 test_fail("SO_RCVBUF didn't seem to work.");
784 debug("leaving test_sockopts()");
793 debug("entering test_read()");
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
);
803 test_fail("open(\"/tmp\", O_RDONLY) should have worked");
808 debug("leaving test_read()");
811 void test_write(void)
816 debug("entering test_write()");
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()");
831 struct sockaddr_un addr
;
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
;
846 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
847 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
849 test_fail("bind() should have worked");
855 test_fail("dup(sd) should have worked");
858 rc
= fstat(sd
, &info1
);
860 test_fail("fstat(fd, &info1) failed");
863 rc
= fstat(sd2
, &info2
);
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");
875 debug("Test dup() with a closed socket");
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");
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
);
898 test_fail("we couldn't open /dev/null for read");
904 if (!(sd2
== -1 && errno
== EMFILE
)) {
905 test_fail("dup(sd) should have failed with errno = EMFILE");
908 for (i
= 3; i
< getdtablesize(); i
++) {
912 UNLINK(TEST_SUN_PATH
);
914 debug("leaving test_dup()");
921 struct sockaddr_un addr
;
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
));
937 test_fail("bind() should have worked");
940 fd
= open("/dev/null", O_RDONLY
);
942 test_fail("open(\"/dev/null\", O_RDONLY) failed");
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
);
955 test_fail("fstat(fd, &info1) failed");
958 rc
= fstat(sd
, &info2
);
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");
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
;
992 socklen_t client_addr_size
;
994 struct sockaddr_un addr
;
995 struct sockaddr_un client_addr
;
1001 ucred_length
= sizeof(struct ucred
);
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
));
1016 test_fail("bind() should have worked");
1021 test_fail("listen(sd, 8) should have worked");
1024 /* we're ready for connections, time to tell the client to start
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()
1039 rc
= select(sd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1041 test_fail("[server] select() should not have failed");
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");
1055 client_sd
= accept(sd
, (struct sockaddr
*) &client_addr
,
1058 if (client_sd
== -1) {
1059 test_fail("accept() should have worked");
1063 debug("[server] client accept()'d");
1066 debug("[server] Reading message");
1067 rc
= read(client_sd
, buf
, sizeof(buf
));
1069 test_fail("read() failed unexpectedly");
1073 debug("[server] we got the following message:");
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
));
1083 test_fail("write(client_sd, buf, sizeof(buf)) failed");
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);
1097 test_fail("recv() failed unexpectedly");
1101 debug("[server] we got the following message:");
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);
1111 test_fail("send(client_sd, buf, sizeof(buf), 0) failed");
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);
1125 test_fail("recvfrom() failed unexpectedly");
1129 debug("[server] we got the following message:");
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);
1139 test_fail("sendto() failed");
1144 if (rc
< strlen(buf
)) {
1145 test_fail("[server] write didn't write all the bytes");
1148 shutdown(client_sd
, SHUT_RDWR
);
1151 shutdown(sd
, SHUT_RDWR
);
1154 /* wait for client to exit */
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");
1171 /* the server will send SIGUSR1 when it is time for us
1172 * to start the tests
1176 debug("got SIGUSR1, the server is ready for the client");
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
;
1193 struct sockaddr_un addr
;
1194 struct sockaddr_un peer_addr
;
1195 socklen_t peer_addr_len
;
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");
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
));
1228 test_fail("[client] connect() should have worked");
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
);
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
));
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
));
1263 test_fail("[client] read() failed unexpectedly");
1265 debug("[client] we got the following message:");
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);
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
,
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()");
1300 tv
.tv_usec
= 500000;
1303 FD_SET(sd
, &readfds
);
1305 rc
= select(sd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1307 test_fail("[client] select() should not have failed");
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);
1322 test_fail("[client] recv() failed unexpectedly");
1324 debug("[client] we got the following message:");
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);
1338 test_fail("[client] sendto() failed");
1341 debug("Testing select()");
1344 tv
.tv_usec
= 500000;
1347 FD_SET(sd
, &readfds
);
1349 rc
= select(sd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1351 test_fail("[client] select() should not have failed");
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);
1366 test_fail("[cleint] recvfrom() failed unexpectedly");
1368 debug("[client] we got the following message:");
1372 if (strncmp(buf
, "HOLA!", sizeof(buf
)) != 0) {
1373 test_fail("[client] We didn't get the right response.");
1376 debug("[client] closing socket");
1379 debug("[client] leaving test_xfer_client()");
1383 void test_xfer(void)
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");
1405 test_fail("fork() failed");
1407 } else if (pid
== 0) {
1410 test_fail("we should never get here");
1414 test_xfer_server(pid
);
1415 debug("parent done");
1419 UNLINK(TEST_SUN_PATH
);
1422 void test_simple_client(int type
)
1426 struct sockaddr_un addr
;
1428 sd
= socket(PF_UNIX
, type
, 0);
1430 test_fail("socket");
1434 while (server_ready
== 0) {
1435 debug("[client] waiting for the server");
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
));
1450 test_fail("sendto");
1456 rc
= connect(sd
, (struct sockaddr
*) &addr
,
1457 sizeof(struct sockaddr_un
));
1459 test_fail("connect");
1463 rc
= write(sd
, buf
, strlen(buf
) + 1);
1468 memset(buf
, '\0', BUFSIZE
);
1469 rc
= read(sd
, buf
, BUFSIZE
);
1474 if (strcmp("Hello, My Name is Server.", buf
) != 0) {
1475 test_fail("didn't read the correct string");
1487 void test_simple_server(int type
, pid_t pid
)
1490 int sd
, rc
, client_sd
, status
;
1491 struct sockaddr_un addr
;
1494 addr_len
= sizeof(struct sockaddr_un
);
1496 sd
= socket(PF_UNIX
, type
, 0);
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
));
1509 if (type
== SOCK_DGRAM
) {
1511 /* ready for client */
1514 rc
= recvfrom(sd
, buf
, BUFSIZE
, 0,
1515 (struct sockaddr
*) &addr
, &addr_len
);
1517 test_fail("recvfrom");
1524 test_fail("listen");
1527 /* we're ready for connections, time to tell the client
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
);
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() */
1550 bzero(buf
, BUFSIZE
);
1551 snprintf(buf
, BUFSIZE
-1, "Hello, My Name is Server.");
1553 rc
= write(client_sd
, buf
, strlen(buf
) + 1);
1558 rc
= close(client_sd
);
1570 /* wait for client to exit */
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
)
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");
1603 test_fail("fork() failed");
1605 } else if (pid
== 0) {
1607 test_simple_client(type
);
1608 test_fail("we should never get here");
1612 test_simple_server(type
, pid
);
1613 debug("parent done");
1616 UNLINK(TEST_SUN_PATH
);
1619 void test_vectorio(int type
)
1623 struct iovec iov
[3];
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
);
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
;
1652 rc
= writev(sv
[0], iovp
, 3);
1654 test_fail("writev");
1657 memset(buf4
, '\0', BUFSIZE
*3);
1659 rc
= read(sv
[1], buf4
, BUFSIZE
*3);
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);
1676 memset(buf2
, '\0', BUFSIZE
);
1677 memset(buf3
, '\0', BUFSIZE
);
1678 memset(buf4
, '\0', BUFSIZE
*3);
1680 iov
[0].iov_base
= buf2
;
1682 iov
[1].iov_base
= buf3
;
1684 iov
[2].iov_base
= buf4
;
1685 iov
[2].iov_len
= 32;
1687 rc
= readv(sv
[0], iovp
, 3);
1692 if (strncmp(buf2
, "Unit ", 5) || strncmp(buf3
, "Test ", 5) ||
1693 strncmp(buf4
, "Time", 4)) {
1707 debug("done vector io tests");
1710 void test_msg(int type
)
1716 struct iovec iov
[3];
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
);
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
;
1744 memset(&msg1
, '\0', sizeof(struct msghdr
));
1745 msg1
.msg_name
= NULL
;
1746 msg1
.msg_namelen
= 0;
1748 msg1
.msg_iovlen
= 3;
1749 msg1
.msg_control
= NULL
;
1750 msg1
.msg_controllen
= 0;
1753 rc
= sendmsg(sv
[0], &msg1
, 0);
1755 test_fail("writev");
1758 memset(buf4
, '\0', BUFSIZE
*3);
1760 rc
= read(sv
[1], buf4
, BUFSIZE
*3);
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);
1777 memset(buf2
, '\0', BUFSIZE
);
1778 memset(buf3
, '\0', BUFSIZE
);
1779 memset(buf4
, '\0', BUFSIZE
*3);
1781 iov
[0].iov_base
= buf2
;
1783 iov
[1].iov_base
= buf3
;
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;
1792 msg2
.msg_iovlen
= 3;
1793 msg2
.msg_control
= NULL
;
1794 msg2
.msg_controllen
= 0;
1797 rc
= recvmsg(sv
[0], &msg2
, 0);
1802 if (strncmp(buf2
, "Unit ", 5) || strncmp(buf3
, "Test ", 5) ||
1803 strncmp(buf4
, "Time", 4)) {
1818 void test_msg_dgram(void)
1823 struct sockaddr_un addr
;
1824 struct iovec iov
[3];
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);
1839 test_fail("socket");
1842 dst
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
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
);
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
);
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
;
1874 iov
[1].iov_base
= buf2
;
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
;
1883 msg1
.msg_iovlen
= 3;
1884 msg1
.msg_control
= NULL
;
1885 msg1
.msg_controllen
= 0;
1888 rc
= sendmsg(src
, &msg1
, 0);
1890 test_fail("sendmsg");
1893 memset(&buf1
, '\0', BUFSIZE
);
1894 memset(&buf2
, '\0', BUFSIZE
);
1896 iov
[0].iov_base
= buf1
;
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
);
1906 msg2
.msg_iovlen
= 2;
1907 msg2
.msg_control
= NULL
;
1908 msg2
.msg_controllen
= 0;
1911 rc
= recvmsg(dst
, &msg2
, 0);
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");
1938 UNLINK(TEST_SUN_PATH
);
1939 UNLINK(TEST_SUN_PATHB
);
1942 void test_scm_credentials(void)
1948 struct cmsghdr
*cmsg
= NULL
;
1949 struct sockaddr_un addr
;
1950 struct iovec iov
[3];
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);
1968 test_fail("socket");
1971 debug("creating dst socket");
1973 dst
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
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
);
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
);
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
;
2010 iov
[1].iov_base
= buf2
;
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
;
2019 msg1
.msg_iovlen
= 3;
2020 msg1
.msg_control
= NULL
;
2021 msg1
.msg_controllen
= 0;
2024 debug("sending msg1");
2026 rc
= sendmsg(src
, &msg1
, 0);
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
;
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
);
2046 msg2
.msg_iovlen
= 2;
2047 msg2
.msg_control
= ctrl
;
2048 msg2
.msg_controllen
= BUFSIZE
;
2053 rc
= recvmsg(dst
, &msg2
, 0);
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
));
2086 if (cred
.pid
!= getpid() || cred
.uid
!= geteuid() ||
2087 cred
.gid
!= getegid()) {
2089 test_fail("did no receive the proper credentials");
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);
2121 test_fail("couldn't create a socket");
2124 rc
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sds
);
2126 test_fail("couldn't create a socketpair");
2129 for (i
= 0; i
< 3; i
++) {
2130 test_simple_client_server(types
[i
]);
2135 test_fail("close() failed");
2140 test_fail("close() failed");
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.
2162 debug("entering test_multiproc_read()");
2164 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sds
);
2166 test_fail("socketpair");
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");
2183 debug("signal handler installed");
2194 } else if (pid
== 0) {
2196 while (server_ready
== 0) {
2197 debug("waiting for SIGUSR1 from parent");
2201 rc
= read(sds
[1], buf
, 2);
2207 if (!(buf
[0] == 'X' && buf
[1] == '3')) {
2208 test_fail("Didn't read X3");
2215 rc
= write(sds
[0], "MNX3", 4);
2220 rc
= read(sds
[1], buf
, 2);
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 */
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
);
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.
2254 debug("entering test_multiproc_write()");
2256 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sds
);
2258 test_fail("socketpair");
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");
2275 debug("signal handler installed");
2286 } else if (pid
== 0) {
2288 while (server_ready
== 0) {
2289 debug("waiting for SIGUSR1 from parent");
2293 rc
= write(sds
[1], "IX3", 3);
2299 rc
= read(sds
[0], buf
, 6);
2305 if (strcmp(buf
, "MINIX3") != 0) {
2306 test_fail("didn't read MINIX3");
2313 rc
= write(sds
[1], "MIN", 3);
2318 /* time to tell the client to start the test */
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
);
2332 void test_fd_passing_child(int sd
)
2336 struct msghdr msghdr
;
2337 struct cmsghdr
*cmsg
;
2341 memset(buf
, '\0', BUFSIZE
);
2343 fd
= open(TEST_TXT_FILE
, O_CREAT
|O_TRUNC
|O_RDWR
);
2345 test_fail("could not open test.txt");
2348 msghdr
.msg_name
= NULL
;
2349 msghdr
.msg_namelen
= 0;
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);
2370 test_fail("could not send message");
2373 memset(buf
, '\0', BUFSIZE
);
2374 rc
= read(sd
, buf
, BUFSIZE
);
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
);
2386 test_fail("could not seek to start of test.txt");
2389 rc
= read(fd
, buf
, BUFSIZE
);
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");
2400 test_fail("could not close test.txt");
2405 test_fail("could not close socket");
2408 rc
= unlink(TEST_TXT_FILE
);
2410 test_fail("could not unlink test.txt");
2416 void test_fd_passing_parent(int sd
)
2420 struct msghdr msghdr
;
2421 struct cmsghdr
*cmsg
;
2425 memset(buf
, '\0', BUFSIZE
);
2427 msghdr
.msg_name
= NULL
;
2428 msghdr
.msg_namelen
= 0;
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);
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");
2458 test_fail("could not close test.txt");
2461 memset(buf
, '\0', BUFSIZE
);
2462 strcpy(buf
, "done");
2463 rc
= write(sd
, buf
, BUFSIZE
);
2465 test_fail("could not write to socket");
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
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
);
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
));
2502 test_fail("bind() should not have worked");
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");
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");
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
));
2535 test_fail("connect should not have worked");
2538 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
2539 rc
= bind(sd
, (struct sockaddr
*) &addr
,
2540 sizeof(struct sockaddr_un
));
2542 test_fail("bind() should have worked");
2547 test_fail("listen(sd, 8) should have worked");
2553 rc
= waitpid(pid
, &status
, 0);
2554 errct
+= WEXITSTATUS(status
);
2557 UNLINK(TEST_SUN_PATH
);
2560 void test_fd_passing(void) {
2566 rc
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sv
);
2568 test_fail("socketpair failed");
2573 test_fail("fork() failed");
2577 test_fail("could not close sv[0]");
2582 test_fail("could not close sv[1]");
2586 } else if (pid
== 0) {
2589 test_fail("could not close sv[0]");
2592 test_fd_passing_child(sv
[1]);
2593 test_fail("should never get here");
2598 test_fail("could not close sv[1]");
2601 test_fd_passing_parent(sv
[0]);
2603 /* wait for client to exit */
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
[])
2618 debug("entering main()");
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
]);
2648 test_multiproc_read();
2649 test_multiproc_write();
2650 test_scm_credentials();
2654 return -1; /* we should never get here */