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
;
475 debug("entering test_bind()");
476 UNLINK(TEST_SUN_PATH
);
477 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
478 addr
.sun_family
= AF_UNIX
;
479 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
481 debug("Test bind() success");
483 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
484 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
486 test_fail("bind() should have worked");
489 debug("Test getsockname() success");
491 memset(&sock_addr
, '\0', sizeof(struct sockaddr_un
));
492 sock_addr_len
= sizeof(struct sockaddr_un
);
494 rc
= getsockname(sd
, (struct sockaddr
*) &sock_addr
, &sock_addr_len
);
496 test_fail("getsockname() should have worked");
499 if (!(sock_addr
.sun_family
== AF_UNIX
&&
500 strncmp(sock_addr
.sun_path
,
501 fullpath(TEST_SUN_PATH
),
502 sizeof(sock_addr
.sun_path
) - 1) == 0)) {
504 test_fail("getsockname() didn't return the right addr");
505 fprintf(stderr
, "exp: '%s' | got: '%s'\n", addr
.sun_path
,
509 debug("Test bind() with a address that has already been bind()'d");
511 SOCKET(sd2
, PF_UNIX
, SOCK_STREAM
, 0);
513 rc
= bind(sd2
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
514 if (!((rc
== -1) && (errno
== EADDRINUSE
))) {
515 test_fail("bind() should have failed with EADDRINUSE");
519 UNLINK(TEST_SUN_PATH
);
521 debug("Test bind() with an empty sun_path");
523 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
524 memset(addr
.sun_path
, '\0', sizeof(addr
.sun_path
));
527 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
528 if (!(rc
== -1 && errno
== ENOENT
)) {
529 test_fail("bind() should have failed with ENOENT");
533 debug("Test bind() with a NULL address");
535 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
537 rc
= bind(sd
, (struct sockaddr
*) NULL
, sizeof(struct sockaddr_un
));
538 if (!((rc
== -1) && (errno
== EFAULT
))) {
539 test_fail("bind() should have failed with EFAULT");
543 debug("Test bind() using a symlink loop");
545 UNLINK(TEST_SUN_PATH
);
549 SYMLINK(TEST_SYM_A
, TEST_SYM_B
);
550 SYMLINK(TEST_SYM_B
, TEST_SYM_A
);
552 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
554 strncpy(addr
.sun_path
, TEST_SYM_A
, sizeof(addr
.sun_path
) - 1);
556 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
557 if (!((rc
== -1) && (errno
== ELOOP
))) {
558 test_fail("bind() should have failed with ELOOP");
562 UNLINK(TEST_SUN_PATH
);
566 debug("leaving test_bind()");
569 void test_listen(void)
573 debug("entering test_listen()");
575 debug("Test listen() with a bad file descriptor");
579 if (!(rc
== -1 && errno
== EBADF
)) {
580 test_fail("listen(-1, 0) should have failed");
583 debug("Test listen() with a non-socket file descriptor");
587 if (!(rc
== -1 && errno
== ENOTTY
)) {
588 test_fail("listen(0, 0) should have failed");
591 debug("leaving test_listen()");
594 void test_shutdown(void)
596 int how
[3] = { SHUT_RD
, SHUT_WR
, SHUT_RDWR
};
601 debug("entering test_shutdown()");
603 /* test for each direction (read, write, read-write) */
604 for (i
= 0; i
< 3; i
++) {
606 debug("test shutdown() with an invalid descriptor");
609 rc
= shutdown(-1, how
[i
]);
610 if (!(rc
== -1 && errno
== EBADF
)) {
611 test_fail("shutdown(-1, how[i]) should have failed");
614 debug("test shutdown() with a non-socket descriptor");
617 rc
= shutdown(0, how
[i
]);
618 if (!(rc
== -1 && errno
== ENOSYS
)) {
619 test_fail("shutdown() should have failed with ENOSYS");
622 debug("test shutdown() with a socket that is not connected");
624 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
626 rc
= shutdown(sd
, how
[i
]);
627 if (!(rc
== -1 && errno
== ENOTCONN
)) {
628 test_fail("shutdown() should have failed");
633 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
635 rc
= shutdown(sd
, -1);
636 if (!(rc
== -1 && errno
== ENOTCONN
)) {
637 test_fail("shutdown(sd, -1) should have failed with ENOTCONN");
641 debug("leaving test_shutdown()");
644 void test_close(void)
646 struct sockaddr_un addr
;
650 debug("entering test_close()");
652 UNLINK(TEST_SUN_PATH
);
654 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
655 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
656 addr
.sun_family
= AF_UNIX
;
658 debug("Test close() success");
660 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
661 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
663 test_fail("bind() should have worked");
668 debug("Close an already closed file descriptor");
672 if (!(rc
== -1 && errno
== EBADF
)) {
673 test_fail("close(sd) should have failed with EBADF");
676 UNLINK(TEST_SUN_PATH
);
678 debug("dup()'ing a file descriptor and closing both should work");
680 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
681 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
683 test_fail("bind() should have worked");
689 test_fail("dup(sd) should have worked");
695 UNLINK(TEST_SUN_PATH
);
697 /* Create and close a socket a bunch of times.
698 * If the implementation doesn't properly free the
699 * socket during close(), eventually socket() will
700 * fail when the internal descriptor table is full.
702 for (i
= 0; i
< 1024; i
++) {
703 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
707 debug("leaving test_close()");
710 void test_sockopts(void)
716 socklen_t option_len
;
718 debug("entering test_sockopts()");
720 for (i
= 0; i
< 3; i
++) {
722 SOCKET(sd
, PF_UNIX
, types
[i
], 0);
724 debug("Test setsockopt() works");
727 option_len
= sizeof(option_value
);
729 rc
= getsockopt(sd
, SOL_SOCKET
, SO_TYPE
, &option_value
,
732 test_fail("setsockopt() should have worked");
735 if (option_value
!= types
[i
]) {
736 test_fail("SO_TYPE didn't seem to work.");
744 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
746 debug("Test setsockopt() works");
749 option_len
= sizeof(option_value
);
751 rc
= getsockopt(sd
, SOL_SOCKET
, SO_SNDBUF
, &option_value
, &option_len
);
753 test_fail("getsockopt() should have worked");
756 if (option_value
!= PIPE_BUF
) {
757 test_fail("SO_SNDBUF didn't seem to work.");
763 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
765 debug("Test setsockopt() works");
768 option_len
= sizeof(option_value
);
770 rc
= getsockopt(sd
, SOL_SOCKET
, SO_RCVBUF
, &option_value
, &option_len
);
772 test_fail("getsockopt() should have worked");
775 if (option_value
!= PIPE_BUF
) {
776 test_fail("SO_RCVBUF didn't seem to work.");
782 debug("leaving test_sockopts()");
791 debug("entering test_read()");
794 rc
= read(-1, buf
, sizeof(buf
));
795 if (!(rc
== -1 && errno
== EBADF
)) {
796 test_fail("read() should have failed with EBADF");
799 fd
= open("/tmp", O_RDONLY
);
801 test_fail("open(\"/tmp\", O_RDONLY) should have worked");
806 debug("leaving test_read()");
809 void test_write(void)
814 debug("entering test_write()");
817 rc
= write(-1, buf
, sizeof(buf
));
818 if (!(rc
== -1 && errno
== EBADF
)) {
819 test_fail("write() should have failed with EBADF");
822 debug("leaving test_write()");
829 struct sockaddr_un addr
;
834 debug("entering test_dup()");
836 UNLINK(TEST_SUN_PATH
);
838 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
839 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
840 addr
.sun_family
= AF_UNIX
;
844 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
845 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
847 test_fail("bind() should have worked");
853 test_fail("dup(sd) should have worked");
856 rc
= fstat(sd
, &info1
);
858 test_fail("fstat(fd, &info1) failed");
861 rc
= fstat(sd2
, &info2
);
863 test_fail("fstat(sd, &info2) failed");
866 if (info1
.st_ino
!= info2
.st_ino
) {
867 test_fail("dup() failed info1.st_ino != info2.st_ino");
873 debug("Test dup() with a closed socket");
877 if (!(rc
== -1 && errno
== EBADF
)) {
878 test_fail("dup(sd) on a closed socket shouldn't have worked");
881 debug("Test dup() with socket descriptor of -1");
885 if (!(rc
== -1 && errno
== EBADF
)) {
886 test_fail("dup(-1) shouldn't have worked");
889 debug("Test dup() when all of the file descriptors are taken");
891 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
893 for (i
= 4; i
< getdtablesize(); i
++) {
894 rc
= open("/dev/null", O_RDONLY
);
896 test_fail("we couldn't open /dev/null for read");
902 if (!(sd2
== -1 && errno
== EMFILE
)) {
903 test_fail("dup(sd) should have failed with errno = EMFILE");
906 for (i
= 3; i
< getdtablesize(); i
++) {
910 UNLINK(TEST_SUN_PATH
);
912 debug("leaving test_dup()");
919 struct sockaddr_un addr
;
924 debug("entering test_dup2()");
925 UNLINK(TEST_SUN_PATH
);
927 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
928 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
929 addr
.sun_family
= AF_UNIX
;
931 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
933 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
935 test_fail("bind() should have worked");
938 fd
= open("/dev/null", O_RDONLY
);
940 test_fail("open(\"/dev/null\", O_RDONLY) failed");
945 test_fail("dup2(sd, fd) failed.");
948 memset(&info1
, '\0', sizeof(struct stat
));
949 memset(&info2
, '\0', sizeof(struct stat
));
951 rc
= fstat(fd
, &info1
);
953 test_fail("fstat(fd, &info1) failed");
956 rc
= fstat(sd
, &info2
);
958 test_fail("fstat(sd, &info2) failed");
961 if (!(info1
.st_ino
== info2
.st_ino
&&
962 major(info1
.st_dev
) == major(info2
.st_dev
) &&
963 minor(info1
.st_dev
) == minor(info2
.st_dev
))) {
965 test_fail("dup2() failed");
971 UNLINK(TEST_SUN_PATH
);
972 debug("leaving test_dup2()");
977 * A toupper() server. This toy server converts a string to upper case.
979 void test_xfer_server(pid_t pid
)
988 socklen_t client_addr_size
;
990 struct sockaddr_un addr
;
991 struct sockaddr_un client_addr
;
997 client_addr_size
= sizeof(struct sockaddr_un
);
999 memset(&buf
, '\0', sizeof(buf
));
1000 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
1001 memset(&client_addr
, '\0', sizeof(struct sockaddr_un
));
1003 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1004 addr
.sun_family
= AF_UNIX
;
1006 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
1008 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
1010 test_fail("bind() should have worked");
1015 test_fail("listen(sd, 8) should have worked");
1018 /* we're ready for connections, time to tell the client to start
1027 FD_SET(sd
, &readfds
);
1029 /* use select() in case the client is really broken and never
1030 * attempts to connect (we don't want to block on accept()
1033 rc
= select(sd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1035 test_fail("[server] select() should not have failed");
1039 test_fail("[server] select() should have returned 1");
1040 printf("[server] select returned %d\n", rc
);
1043 if (!(FD_ISSET(sd
, &readfds
))) {
1044 test_fail("[server] client didn't connect within 10 seconds");
1049 client_sd
= accept(sd
, (struct sockaddr
*) &client_addr
,
1052 if (client_sd
== -1) {
1053 test_fail("accept() should have worked");
1057 debug("[server] client accept()'d");
1060 debug("[server] Reading message");
1061 rc
= read(client_sd
, buf
, sizeof(buf
));
1063 test_fail("read() failed unexpectedly");
1067 debug("[server] we got the following message:");
1070 for (i
= 0; i
< rc
&& i
< 127; i
++) {
1071 buf
[i
] = toupper(buf
[i
]);
1074 debug("[server] Writing message...");
1075 rc
= write(client_sd
, buf
, sizeof(buf
));
1077 test_fail("write(client_sd, buf, sizeof(buf)) failed");
1082 if (rc
< strlen(buf
)) {
1083 test_fail("[server] write didn't write all the bytes");
1086 memset(&buf
, '\0', sizeof(buf
));
1088 debug("[server] Recv message");
1089 rc
= recv(client_sd
, buf
, sizeof(buf
), 0);
1091 test_fail("recv() failed unexpectedly");
1095 debug("[server] we got the following message:");
1098 for (i
= 0; i
< rc
&& i
< 127; i
++) {
1099 buf
[i
] = toupper(buf
[i
]);
1102 debug("[server] Sending message...");
1103 rc
= send(client_sd
, buf
, sizeof(buf
), 0);
1105 test_fail("send(client_sd, buf, sizeof(buf), 0) failed");
1110 if (rc
< strlen(buf
)) {
1111 test_fail("[server] write didn't write all the bytes");
1114 memset(&buf
, '\0', sizeof(buf
));
1116 debug("[server] Recvfrom message");
1117 rc
= recvfrom(client_sd
, buf
, sizeof(buf
), 0, NULL
, 0);
1119 test_fail("recvfrom() failed unexpectedly");
1123 debug("[server] we got the following message:");
1126 for (i
= 0; i
< rc
&& i
< 127; i
++) {
1127 buf
[i
] = toupper(buf
[i
]);
1130 debug("[server] Sendto message...");
1131 rc
= sendto(client_sd
, buf
, sizeof(buf
), 0, NULL
, 0);
1133 test_fail("sendto() failed");
1138 if (rc
< strlen(buf
)) {
1139 test_fail("[server] write didn't write all the bytes");
1142 shutdown(client_sd
, SHUT_RDWR
);
1145 shutdown(sd
, SHUT_RDWR
);
1148 /* wait for client to exit */
1151 rc
= waitpid(pid
, &status
, 0);
1152 } while (rc
== -1 && errno
== EINTR
);
1154 /* we use the exit status to get its error count */
1155 errct
+= WEXITSTATUS(status
);
1158 int server_ready
= 0;
1160 /* signal handler for the client */
1161 void test_xfer_sighdlr(int sig
)
1163 debug("entering signal handler");
1165 /* the server will send SIGUSR1 when it is time for us
1166 * to start the tests
1170 debug("got SIGUSR1, the server is ready for the client");
1173 debug("didn't get SIGUSR1");
1175 debug("leaving signal handler");
1179 * A toupper() client.
1181 void test_xfer_client(void)
1183 struct ucred credentials
;
1184 socklen_t ucred_length
;
1187 struct sockaddr_un addr
;
1188 struct sockaddr_un peer_addr
;
1189 socklen_t peer_addr_len
;
1194 debug("[client] entering test_xfer_client()");
1195 errct
= 0; /* reset error count */
1196 ucred_length
= sizeof(struct ucred
);
1197 memset(&buf
, '\0', sizeof(buf
));
1199 while (server_ready
== 0) {
1200 debug("[client] waiting for the server to signal");
1204 peer_addr_len
= sizeof(struct sockaddr_un
);
1207 debug("Creating symlink to TEST_SUN_PATH");
1209 SYMLINK(TEST_SUN_PATH
, TEST_SYM_A
);
1211 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
1212 strncpy(addr
.sun_path
, TEST_SYM_A
, sizeof(addr
.sun_path
) - 1);
1213 addr
.sun_family
= AF_UNIX
;
1215 debug("[client] creating client socket");
1216 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
1218 debug("[client] connecting to server through the symlink");
1219 rc
= connect(sd
, (struct sockaddr
*) &addr
,
1220 sizeof(struct sockaddr_un
));
1222 test_fail("[client] connect() should have worked");
1224 debug("[client] connected");
1227 debug("[client] testing getpeername()");
1228 memset(&peer_addr
, '\0', sizeof(struct sockaddr_un
));
1229 rc
= getpeername(sd
, (struct sockaddr
*) &peer_addr
, &peer_addr_len
);
1231 test_fail("[client] getpeername() should have worked");
1234 /* we need to use the full path "/usr/src/test/DIR_56/test.sock"
1235 * because that is what is returned by getpeername().
1238 if (!(peer_addr
.sun_family
== AF_UNIX
&&
1239 strncmp(peer_addr
.sun_path
,
1240 fullpath(TEST_SUN_PATH
),
1241 sizeof(peer_addr
.sun_path
) - 1) == 0)) {
1243 test_fail("getpeername() didn't return the right address");
1246 strncpy(buf
, "Hello, World!", sizeof(buf
) - 1);
1247 debug("[client] send to server");
1248 rc
= write(sd
, buf
, sizeof(buf
));
1250 test_fail("[client] write() failed unexpectedly");
1253 memset(buf
, '\0', sizeof(buf
));
1254 debug("[client] read from server");
1255 rc
= read(sd
, buf
, sizeof(buf
));
1257 test_fail("[client] read() failed unexpectedly");
1259 debug("[client] we got the following message:");
1263 if (strncmp(buf
, "HELLO, WORLD!", sizeof(buf
)) != 0) {
1264 test_fail("[client] We didn't get the correct response");
1267 memset(&buf
, '\0', sizeof(buf
));
1268 strncpy(buf
, "Bonjour!", sizeof(buf
) - 1);
1270 debug("[client] send to server");
1271 rc
= send(sd
, buf
, sizeof(buf
), 0);
1273 test_fail("[client] send() failed unexpectedly");
1276 debug("Test passing the client credentials to the server");
1278 memset(&credentials
, '\0', ucred_length
);
1279 rc
= getsockopt(sd
, SOL_SOCKET
, SO_PEERCRED
, &credentials
,
1283 test_fail("[client] getsockopt() failed");
1284 } else if (credentials
.uid
!= geteuid() ||
1285 credentials
.gid
!= getegid()) {
1286 printf("%d=%d=%d %d=%d=%d\n", credentials
.uid
, getuid(),
1287 geteuid(), credentials
.gid
, getgid(), getegid());
1288 test_fail("[client] Credential passing gave us a bad UID/GID");
1291 debug("Testing select()");
1294 tv
.tv_usec
= 500000;
1297 FD_SET(sd
, &readfds
);
1299 rc
= select(sd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1301 test_fail("[client] select() should not have failed");
1305 test_fail("[client] select() should have returned 1");
1308 if (!(FD_ISSET(sd
, &readfds
))) {
1309 test_fail("The server didn't respond within 2.5 seconds");
1312 memset(buf
, '\0', sizeof(buf
));
1313 debug("[client] recv from server");
1314 rc
= recv(sd
, buf
, sizeof(buf
), 0);
1316 test_fail("[client] recv() failed unexpectedly");
1318 debug("[client] we got the following message:");
1322 if (strncmp(buf
, "BONJOUR!", sizeof(buf
)) != 0) {
1323 test_fail("[client] We didn't get the right response.");
1326 memset(&buf
, '\0', sizeof(buf
));
1327 strncpy(buf
, "Hola!", sizeof(buf
) - 1);
1329 debug("[client] sendto to server");
1330 rc
= sendto(sd
, buf
, sizeof(buf
), 0, NULL
, 0);
1332 test_fail("[client] sendto() failed");
1335 debug("Testing select()");
1338 tv
.tv_usec
= 500000;
1341 FD_SET(sd
, &readfds
);
1343 rc
= select(sd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1345 test_fail("[client] select() should not have failed");
1349 test_fail("[client] select() should have returned 1");
1352 if (!(FD_ISSET(sd
, &readfds
))) {
1353 test_fail("[client] The server didn't respond in 2.5 seconds");
1356 memset(buf
, '\0', sizeof(buf
));
1357 debug("[client] recvfrom from server");
1358 rc
= recvfrom(sd
, buf
, sizeof(buf
), 0, NULL
, 0);
1360 test_fail("[cleint] recvfrom() failed unexpectedly");
1362 debug("[client] we got the following message:");
1366 if (strncmp(buf
, "HOLA!", sizeof(buf
)) != 0) {
1367 test_fail("[client] We didn't get the right response.");
1370 debug("[client] closing socket");
1373 debug("[client] leaving test_xfer_client()");
1377 void test_xfer(void)
1382 UNLINK(TEST_SUN_PATH
);
1384 /* the signal handler is only used by the client, but we have to
1385 * install it now. if we don't the server may signal the client
1386 * before the handler is installed.
1388 debug("installing signal handler");
1389 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
1390 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1393 debug("signal handler installed");
1399 test_fail("fork() failed");
1401 } else if (pid
== 0) {
1404 test_fail("we should never get here");
1408 test_xfer_server(pid
);
1409 debug("parent done");
1413 UNLINK(TEST_SUN_PATH
);
1416 void test_simple_client(int type
)
1420 struct sockaddr_un addr
;
1422 sd
= socket(PF_UNIX
, type
, 0);
1424 test_fail("socket");
1428 while (server_ready
== 0) {
1429 debug("[client] waiting for the server");
1433 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1434 addr
.sun_family
= AF_UNIX
;
1436 bzero(buf
, BUFSIZE
);
1437 snprintf(buf
, BUFSIZE
-1, "Hello, My Name is Client.");
1439 if (type
== SOCK_DGRAM
) {
1441 rc
= sendto(sd
, buf
, strlen(buf
) + 1, 0,
1442 (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
1444 test_fail("sendto");
1450 rc
= connect(sd
, (struct sockaddr
*) &addr
,
1451 sizeof(struct sockaddr_un
));
1453 test_fail("connect");
1457 rc
= write(sd
, buf
, strlen(buf
) + 1);
1462 memset(buf
, '\0', BUFSIZE
);
1463 rc
= read(sd
, buf
, BUFSIZE
);
1468 if (strcmp("Hello, My Name is Server.", buf
) != 0) {
1469 test_fail("didn't read the correct string");
1481 void test_simple_server(int type
, pid_t pid
)
1484 int sd
, rc
, client_sd
, status
;
1485 struct sockaddr_un addr
;
1488 addr_len
= sizeof(struct sockaddr_un
);
1490 sd
= socket(PF_UNIX
, type
, 0);
1492 test_fail("socket");
1495 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1496 addr
.sun_family
= AF_UNIX
;
1498 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
1503 if (type
== SOCK_DGRAM
) {
1505 /* ready for client */
1508 rc
= recvfrom(sd
, buf
, BUFSIZE
, 0,
1509 (struct sockaddr
*) &addr
, &addr_len
);
1511 test_fail("recvfrom");
1518 test_fail("listen");
1521 /* we're ready for connections, time to tell the client
1526 client_sd
= accept(sd
, (struct sockaddr
*) &addr
, &addr_len
);
1527 if (client_sd
== -1) {
1528 test_fail("accept");
1531 memset(buf
, '\0', BUFSIZE
);
1532 rc
= read(client_sd
, buf
, BUFSIZE
);
1537 if (strcmp("Hello, My Name is Client.", buf
) != 0) {
1538 test_fail("didn't read the correct string");
1541 /* added for extra fun to make the client block on read() */
1544 bzero(buf
, BUFSIZE
);
1545 snprintf(buf
, BUFSIZE
-1, "Hello, My Name is Server.");
1547 rc
= write(client_sd
, buf
, strlen(buf
) + 1);
1552 rc
= close(client_sd
);
1564 /* wait for client to exit */
1567 rc
= waitpid(pid
, &status
, 0);
1568 } while (rc
== -1 && errno
== EINTR
);
1570 /* we use the exit status to get its error count */
1571 errct
+= WEXITSTATUS(status
);
1574 void test_simple_client_server(int type
)
1578 debug("test_simple_client_server()");
1580 UNLINK(TEST_SUN_PATH
);
1582 /* the signal handler is only used by the client, but we have to
1583 * install it now. if we don't the server may signal the client
1584 * before the handler is installed.
1586 debug("installing signal handler");
1587 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
1588 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1591 debug("signal handler installed");
1597 test_fail("fork() failed");
1599 } else if (pid
== 0) {
1601 test_simple_client(type
);
1602 test_fail("we should never get here");
1606 test_simple_server(type
, pid
);
1607 debug("parent done");
1610 UNLINK(TEST_SUN_PATH
);
1613 void test_vectorio(int type
)
1617 struct iovec iov
[3];
1621 char buf4
[BUFSIZE
*3];
1622 const struct iovec
*iovp
= iov
;
1624 debug("begin vectorio tests");
1626 memset(buf1
, '\0', BUFSIZE
);
1627 strncpy(buf1
, "HELLO ", BUFSIZE
- 1);
1629 memset(buf2
, '\0', BUFSIZE
);
1630 strncpy(buf2
, "WORLD", BUFSIZE
- 1);
1632 memset(buf3
, '\0', BUFSIZE
);
1634 rc
= socketpair(PF_UNIX
, type
, 0, sv
);
1636 test_fail("socketpair");
1639 iov
[0].iov_base
= buf1
;
1640 iov
[0].iov_len
= strlen(buf1
);
1641 iov
[1].iov_base
= buf2
;
1642 iov
[1].iov_len
= strlen(buf2
);
1643 iov
[2].iov_base
= buf3
;
1646 rc
= writev(sv
[0], iovp
, 3);
1648 test_fail("writev");
1651 memset(buf4
, '\0', BUFSIZE
*3);
1653 rc
= read(sv
[1], buf4
, BUFSIZE
*3);
1658 if (strncmp(buf4
, "HELLO WORLD", strlen("HELLO WORLD"))) {
1659 test_fail("the string we read was not 'HELLO WORLD'");
1662 memset(buf1
, '\0', BUFSIZE
);
1663 strncpy(buf1
, "Unit Test Time", BUFSIZE
- 1);
1665 rc
= write(sv
[1], buf1
, strlen(buf1
) + 1);
1670 memset(buf2
, '\0', BUFSIZE
);
1671 memset(buf3
, '\0', BUFSIZE
);
1672 memset(buf4
, '\0', BUFSIZE
*3);
1674 iov
[0].iov_base
= buf2
;
1676 iov
[1].iov_base
= buf3
;
1678 iov
[2].iov_base
= buf4
;
1679 iov
[2].iov_len
= 32;
1681 rc
= readv(sv
[0], iovp
, 3);
1686 if (strncmp(buf2
, "Unit ", 5) || strncmp(buf3
, "Test ", 5) ||
1687 strncmp(buf4
, "Time", 4)) {
1701 debug("done vector io tests");
1704 void test_msg(int type
)
1710 struct iovec iov
[3];
1714 char buf4
[BUFSIZE
*3];
1716 debug("begin sendmsg/recvmsg tests");
1718 memset(buf1
, '\0', BUFSIZE
);
1719 strncpy(buf1
, "HELLO ", BUFSIZE
- 1);
1721 memset(buf2
, '\0', BUFSIZE
);
1722 strncpy(buf2
, "WORLD", BUFSIZE
- 1);
1724 memset(buf3
, '\0', BUFSIZE
);
1726 rc
= socketpair(PF_UNIX
, type
, 0, sv
);
1728 test_fail("socketpair");
1731 iov
[0].iov_base
= buf1
;
1732 iov
[0].iov_len
= strlen(buf1
);
1733 iov
[1].iov_base
= buf2
;
1734 iov
[1].iov_len
= strlen(buf2
);
1735 iov
[2].iov_base
= buf3
;
1738 memset(&msg1
, '\0', sizeof(struct msghdr
));
1739 msg1
.msg_name
= NULL
;
1740 msg1
.msg_namelen
= 0;
1742 msg1
.msg_iovlen
= 3;
1743 msg1
.msg_control
= NULL
;
1744 msg1
.msg_controllen
= 0;
1747 rc
= sendmsg(sv
[0], &msg1
, 0);
1749 test_fail("writev");
1752 memset(buf4
, '\0', BUFSIZE
*3);
1754 rc
= read(sv
[1], buf4
, BUFSIZE
*3);
1759 if (strncmp(buf4
, "HELLO WORLD", strlen("HELLO WORLD"))) {
1760 test_fail("the string we read was not 'HELLO WORLD'");
1763 memset(buf1
, '\0', BUFSIZE
);
1764 strncpy(buf1
, "Unit Test Time", BUFSIZE
- 1);
1766 rc
= write(sv
[1], buf1
, strlen(buf1
) + 1);
1771 memset(buf2
, '\0', BUFSIZE
);
1772 memset(buf3
, '\0', BUFSIZE
);
1773 memset(buf4
, '\0', BUFSIZE
*3);
1775 iov
[0].iov_base
= buf2
;
1777 iov
[1].iov_base
= buf3
;
1779 iov
[2].iov_base
= buf4
;
1780 iov
[2].iov_len
= 32;
1782 memset(&msg2
, '\0', sizeof(struct msghdr
));
1783 msg2
.msg_name
= NULL
;
1784 msg2
.msg_namelen
= 0;
1786 msg2
.msg_iovlen
= 3;
1787 msg2
.msg_control
= NULL
;
1788 msg2
.msg_controllen
= 0;
1791 rc
= recvmsg(sv
[0], &msg2
, 0);
1796 if (strncmp(buf2
, "Unit ", 5) || strncmp(buf3
, "Test ", 5) ||
1797 strncmp(buf4
, "Time", 4)) {
1812 void test_msg_dgram(void)
1817 struct sockaddr_un addr
;
1818 struct iovec iov
[3];
1824 socklen_t addrlen
= sizeof(struct sockaddr_un
);
1826 debug("test msg_dgram");
1828 UNLINK(TEST_SUN_PATH
);
1829 UNLINK(TEST_SUN_PATHB
);
1831 src
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
1833 test_fail("socket");
1836 dst
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
1838 test_fail("socket");
1841 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
1842 addr
.sun_family
= AF_UNIX
;
1843 strncpy(addr
.sun_path
, TEST_SUN_PATHB
, sizeof(addr
.sun_path
) - 1);
1844 rc
= bind(src
, (struct sockaddr
*) &addr
, addrlen
);
1849 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
1850 addr
.sun_family
= AF_UNIX
;
1851 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1853 rc
= bind(dst
, (struct sockaddr
*) &addr
, addrlen
);
1858 memset(&buf1
, '\0', BUFSIZE
);
1859 memset(&buf2
, '\0', BUFSIZE
);
1860 memset(&buf3
, '\0', BUFSIZE
);
1862 strncpy(buf1
, "Minix ", BUFSIZE
-1);
1863 strncpy(buf2
, "is ", BUFSIZE
-1);
1864 strncpy(buf3
, "great!", BUFSIZE
-1);
1866 iov
[0].iov_base
= buf1
;
1868 iov
[1].iov_base
= buf2
;
1870 iov
[2].iov_base
= buf3
;
1871 iov
[2].iov_len
= 32;
1873 memset(&msg1
, '\0', sizeof(struct msghdr
));
1874 msg1
.msg_name
= &addr
;
1875 msg1
.msg_namelen
= addrlen
;
1877 msg1
.msg_iovlen
= 3;
1878 msg1
.msg_control
= NULL
;
1879 msg1
.msg_controllen
= 0;
1882 rc
= sendmsg(src
, &msg1
, 0);
1884 test_fail("sendmsg");
1887 memset(&buf1
, '\0', BUFSIZE
);
1888 memset(&buf2
, '\0', BUFSIZE
);
1890 iov
[0].iov_base
= buf1
;
1892 iov
[1].iov_base
= buf2
;
1893 iov
[1].iov_len
= 32;
1895 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
1896 memset(&msg2
, '\0', sizeof(struct msghdr
));
1897 msg2
.msg_name
= &addr
;
1898 msg2
.msg_namelen
= sizeof(struct sockaddr_un
);
1900 msg2
.msg_iovlen
= 2;
1901 msg2
.msg_control
= NULL
;
1902 msg2
.msg_controllen
= 0;
1905 rc
= recvmsg(dst
, &msg2
, 0);
1907 test_fail("recvmsg");
1910 if (strncmp(buf1
, "Minix is ", 9) || strncmp(buf2
, "great!", 6)) {
1911 test_fail("recvmsg");
1914 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
1915 * because that is what is returned by recvmsg().
1917 if (addr
.sun_family
!= AF_UNIX
|| strcmp(addr
.sun_path
,
1918 fullpath(TEST_SUN_PATHB
))) {
1919 test_fail("recvmsg");
1932 UNLINK(TEST_SUN_PATH
);
1933 UNLINK(TEST_SUN_PATHB
);
1936 void test_scm_credentials(void)
1942 struct cmsghdr
*cmsg
= NULL
;
1943 struct sockaddr_un addr
;
1944 struct iovec iov
[3];
1951 socklen_t addrlen
= sizeof(struct sockaddr_un
);
1953 debug("test_scm_credentials");
1955 UNLINK(TEST_SUN_PATH
);
1956 UNLINK(TEST_SUN_PATHB
);
1958 debug("creating src socket");
1960 src
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
1962 test_fail("socket");
1965 debug("creating dst socket");
1967 dst
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
1969 test_fail("socket");
1972 debug("binding src socket");
1974 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
1975 addr
.sun_family
= AF_UNIX
;
1976 strncpy(addr
.sun_path
, TEST_SUN_PATHB
, sizeof(addr
.sun_path
) - 1);
1977 rc
= bind(src
, (struct sockaddr
*) &addr
, addrlen
);
1982 debug("binding dst socket");
1984 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
1985 addr
.sun_family
= AF_UNIX
;
1986 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1988 rc
= bind(dst
, (struct sockaddr
*) &addr
, addrlen
);
1993 memset(&buf1
, '\0', BUFSIZE
);
1994 memset(&buf2
, '\0', BUFSIZE
);
1995 memset(&buf3
, '\0', BUFSIZE
);
1996 memset(&ctrl
, '\0', BUFSIZE
);
1998 strncpy(buf1
, "Minix ", BUFSIZE
-1);
1999 strncpy(buf2
, "is ", BUFSIZE
-1);
2000 strncpy(buf3
, "great!", BUFSIZE
-1);
2002 iov
[0].iov_base
= buf1
;
2004 iov
[1].iov_base
= buf2
;
2006 iov
[2].iov_base
= buf3
;
2007 iov
[2].iov_len
= 32;
2009 memset(&msg1
, '\0', sizeof(struct msghdr
));
2010 msg1
.msg_name
= &addr
;
2011 msg1
.msg_namelen
= addrlen
;
2013 msg1
.msg_iovlen
= 3;
2014 msg1
.msg_control
= NULL
;
2015 msg1
.msg_controllen
= 0;
2018 debug("sending msg1");
2020 rc
= sendmsg(src
, &msg1
, 0);
2022 test_fail("sendmsg");
2025 memset(&buf1
, '\0', BUFSIZE
);
2026 memset(&buf2
, '\0', BUFSIZE
);
2027 memset(&buf3
, '\0', BUFSIZE
);
2028 memset(&ctrl
, '\0', BUFSIZE
);
2030 iov
[0].iov_base
= buf1
;
2032 iov
[1].iov_base
= buf2
;
2033 iov
[1].iov_len
= 32;
2035 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
2036 memset(&msg2
, '\0', sizeof(struct msghdr
));
2037 msg2
.msg_name
= &addr
;
2038 msg2
.msg_namelen
= sizeof(struct sockaddr_un
);
2040 msg2
.msg_iovlen
= 2;
2041 msg2
.msg_control
= ctrl
;
2042 msg2
.msg_controllen
= BUFSIZE
;
2047 rc
= recvmsg(dst
, &msg2
, 0);
2049 test_fail("recvmsg");
2052 debug("checking results");
2054 if (strncmp(buf1
, "Minix is ", 9) || strncmp(buf2
, "great!", 6)) {
2055 test_fail("recvmsg");
2058 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
2059 * because that is what is returned by recvmsg().
2061 if (addr
.sun_family
!= AF_UNIX
|| strcmp(addr
.sun_path
,
2062 fullpath(TEST_SUN_PATHB
))) {
2063 test_fail("recvmsg");
2066 debug("looking for credentials");
2068 memset(&cred
, '\0', sizeof(struct ucred
));
2069 for (cmsg
= CMSG_FIRSTHDR(&msg2
); cmsg
!= NULL
;
2070 cmsg
= CMSG_NXTHDR(&msg2
, cmsg
)) {
2072 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
2073 cmsg
->cmsg_type
== SCM_CREDENTIALS
) {
2075 memcpy(&cred
, CMSG_DATA(cmsg
), sizeof(struct ucred
));
2080 if (cred
.pid
!= getpid() || cred
.uid
!= geteuid() ||
2081 cred
.gid
!= getegid()) {
2083 test_fail("did no receive the proper credentials");
2096 UNLINK(TEST_SUN_PATH
);
2097 UNLINK(TEST_SUN_PATHB
);
2100 void test_connect(void)
2102 int i
, sd
, sds
[2], rc
;
2104 /* connect() is already tested throughout test56, but
2105 * in most cases the client and server end up on /dev/uds
2106 * minor 0 and minor 1. This test opens some sockets first and
2107 * then calls test_simple_client_server(). This forces the
2108 * client and server minor numbers higher in the descriptor table.
2111 debug("starting test_connect()");
2113 sd
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
2115 test_fail("couldn't create a socket");
2118 rc
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sds
);
2120 test_fail("couldn't create a socketpair");
2123 for (i
= 0; i
< 3; i
++) {
2124 test_simple_client_server(types
[i
]);
2129 test_fail("close() failed");
2134 test_fail("close() failed");
2139 test_fail("close() failed");
2142 debug("exiting test_connect()");
2145 int test_multiproc_read(void)
2147 /* test that when we fork() a process with an open socket descriptor,
2148 * the descriptor in each process points to the same thing.
2156 debug("entering test_multiproc_read()");
2158 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sds
);
2160 test_fail("socketpair");
2164 memset(buf
, '\0', 3);
2167 /* the signal handler is only used by the client, but we have to
2168 * install it now. if we don't the server may signal the client
2169 * before the handler is installed.
2171 debug("installing signal handler");
2172 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
2173 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2177 debug("signal handler installed");
2188 } else if (pid
== 0) {
2190 while (server_ready
== 0) {
2191 debug("waiting for SIGUSR1 from parent");
2195 rc
= read(sds
[1], buf
, 2);
2201 if (!(buf
[0] == 'X' && buf
[1] == '3')) {
2202 test_fail("Didn't read X3");
2209 rc
= write(sds
[0], "MNX3", 4);
2214 rc
= read(sds
[1], buf
, 2);
2219 if (!(buf
[0] == 'M' && buf
[1] == 'N')) {
2220 test_fail("Didn't read MN");
2223 /* time to tell the client to start the test */
2227 rc
= waitpid(pid
, &status
, 0);
2228 } while (rc
== -1 && errno
== EINTR
);
2230 /* we use the exit status to get its error count */
2231 errct
+= WEXITSTATUS(status
);
2237 int test_multiproc_write(void)
2239 /* test that when we fork() a process with an open socket descriptor,
2240 * the descriptor in each process points to the same thing.
2248 debug("entering test_multiproc_write()");
2250 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sds
);
2252 test_fail("socketpair");
2256 memset(buf
, '\0', 7);
2259 /* the signal handler is only used by the client, but we have to
2260 * install it now. if we don't the server may signal the client
2261 * before the handler is installed.
2263 debug("installing signal handler");
2264 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
2265 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2269 debug("signal handler installed");
2280 } else if (pid
== 0) {
2282 while (server_ready
== 0) {
2283 debug("waiting for SIGUSR1 from parent");
2287 rc
= write(sds
[1], "IX3", 3);
2293 rc
= read(sds
[0], buf
, 6);
2299 if (strcmp(buf
, "MINIX3") != 0) {
2300 test_fail("didn't read MINIX3");
2307 rc
= write(sds
[1], "MIN", 3);
2312 /* time to tell the client to start the test */
2316 rc
= waitpid(pid
, &status
, 0);
2317 } while (rc
== -1 && errno
== EINTR
);
2319 /* we use the exit status to get its error count */
2320 errct
+= WEXITSTATUS(status
);
2326 void test_fd_passing_child(int sd
)
2330 struct msghdr msghdr
;
2331 struct cmsghdr
*cmsg
;
2335 memset(buf
, '\0', BUFSIZE
);
2337 fd
= open(TEST_TXT_FILE
, O_CREAT
|O_TRUNC
|O_RDWR
);
2339 test_fail("could not open test.txt");
2342 msghdr
.msg_name
= NULL
;
2343 msghdr
.msg_namelen
= 0;
2347 msghdr
.msg_iov
= &iov
;
2348 msghdr
.msg_iovlen
= 1;
2350 msghdr
.msg_control
= buf
;
2351 msghdr
.msg_controllen
= CMSG_SPACE(sizeof(int));
2353 msghdr
.msg_flags
= 0;
2355 cmsg
= CMSG_FIRSTHDR(&msghdr
);
2356 cmsg
->cmsg_len
= CMSG_SPACE(sizeof(int));
2357 cmsg
->cmsg_level
= SOL_SOCKET
;
2358 cmsg
->cmsg_type
= SCM_RIGHTS
;
2360 ((int *) CMSG_DATA(cmsg
))[0] = fd
;
2362 rc
= sendmsg(sd
, &msghdr
, 0);
2364 test_fail("could not send message");
2367 memset(buf
, '\0', BUFSIZE
);
2368 rc
= read(sd
, buf
, BUFSIZE
);
2370 test_fail("could not read from socket");
2373 if (strcmp(buf
, "done") != 0) {
2374 test_fail("we didn't read the right message");
2377 memset(buf
, '\0', BUFSIZE
);
2378 rc
= lseek(fd
, 0, SEEK_SET
);
2380 test_fail("could not seek to start of test.txt");
2383 rc
= read(fd
, buf
, BUFSIZE
);
2385 test_fail("could not read from test.txt");
2388 if (strcmp(buf
, MSG
) != 0) {
2389 test_fail("other process didn't write MSG to test.txt");
2394 test_fail("could not close test.txt");
2399 test_fail("could not close socket");
2402 rc
= unlink(TEST_TXT_FILE
);
2404 test_fail("could not unlink test.txt");
2410 void test_fd_passing_parent(int sd
)
2414 struct msghdr msghdr
;
2415 struct cmsghdr
*cmsg
;
2419 memset(buf
, '\0', BUFSIZE
);
2421 msghdr
.msg_name
= NULL
;
2422 msghdr
.msg_namelen
= 0;
2426 msghdr
.msg_iov
= &iov
;
2427 msghdr
.msg_iovlen
= 1;
2429 msghdr
.msg_iov
= &iov
;
2430 msghdr
.msg_iovlen
= 1;
2432 msghdr
.msg_control
= buf
;
2433 msghdr
.msg_controllen
= BUFSIZE
;
2435 msghdr
.msg_flags
= 0;
2437 rc
= recvmsg(sd
, &msghdr
, 0);
2439 test_fail("could not recv message.");
2442 cmsg
= CMSG_FIRSTHDR(&msghdr
);
2443 fd
= ((int *) CMSG_DATA(cmsg
))[0];
2445 rc
= write(fd
, MSG
, strlen(MSG
));
2446 if (rc
!= strlen(MSG
)) {
2447 test_fail("could not write the full message to test.txt");
2452 test_fail("could not close test.txt");
2455 memset(buf
, '\0', BUFSIZE
);
2456 strcpy(buf
, "done");
2457 rc
= write(sd
, buf
, BUFSIZE
);
2459 test_fail("could not write to socket");
2464 test_fail("could not close socket");
2468 void test_permissions(void) {
2469 /* Test bind and connect for permission verification
2471 * After creating a UDS socket we change user credentials. At that
2472 * point we should not be allowed to bind or connect to the UDS socket
2477 struct sockaddr_un addr
;
2479 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
2480 addr
.sun_family
= AF_UNIX
;
2481 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
2483 UNLINK(TEST_SUN_PATH
);
2486 if (pid
< 0) test_fail("unable to fork");
2487 else if (pid
== 0) {
2488 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
2489 if (setuid(999) != 0) test_fail("unable to chance uid");
2490 rc
= bind(sd
, (struct sockaddr
*) &addr
,
2491 sizeof(struct sockaddr_un
));
2493 test_fail("bind() should not have worked");
2497 rc
= waitpid(pid
, &status
, 0);
2498 errct
+= WEXITSTATUS(status
);
2501 /* the signal handler is only used by the client, but we have to
2502 * install it now. if we don't the server may signal the client
2503 * before the handler is installed.
2505 debug("installing signal handler");
2506 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
2507 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2510 debug("signal handler installed");
2515 if (pid
< 0) test_fail("unable to fork");
2516 else if (pid
== 0) {
2517 while (server_ready
== 0) {
2518 debug("[client] waiting for the server to signal");
2521 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
2522 if (setuid(999) != 0) test_fail("unable to chance uid");
2523 rc
= connect(sd
, (struct sockaddr
*) &addr
,
2524 sizeof(struct sockaddr_un
));
2526 test_fail("connect should not have worked");
2529 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
2530 rc
= bind(sd
, (struct sockaddr
*) &addr
,
2531 sizeof(struct sockaddr_un
));
2533 test_fail("bind() should have worked");
2538 test_fail("listen(sd, 8) should have worked");
2544 rc
= waitpid(pid
, &status
, 0);
2545 errct
+= WEXITSTATUS(status
);
2548 UNLINK(TEST_SUN_PATH
);
2551 void test_fd_passing(void) {
2557 rc
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sv
);
2559 test_fail("socketpair failed");
2564 test_fail("fork() failed");
2568 test_fail("could not close sv[0]");
2573 test_fail("could not close sv[1]");
2577 } else if (pid
== 0) {
2580 test_fail("could not close sv[0]");
2583 test_fd_passing_child(sv
[1]);
2584 test_fail("should never get here");
2589 test_fail("could not close sv[1]");
2592 test_fd_passing_parent(sv
[0]);
2594 /* wait for client to exit */
2597 rc
= waitpid(pid
, &status
, 0);
2598 } while (rc
== -1 && errno
== EINTR
);
2600 /* we use the exit status to get its error count */
2601 errct
+= WEXITSTATUS(status
);
2605 int main(int argc
, char *argv
[])
2609 debug("entering main()");
2631 for (i
= 0; i
< 3; i
++) {
2632 test_simple_client_server(types
[i
]);
2633 if (types
[i
] != SOCK_DGRAM
) test_vectorio(types
[i
]);
2634 if (types
[i
] != SOCK_DGRAM
) test_msg(types
[i
]);
2639 test_multiproc_read();
2640 test_multiproc_write();
2641 test_scm_credentials();
2645 return -1; /* we should never get here */