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>
48 #include <sys/ucred.h>
51 #include <sys/types.h>
58 /* Maximum number of errors that we'll allow to occur before this test
59 * program gives us and quits.
65 /* Use the common testing code instead of reinventing the wheel. */
67 /* path of the unix domain socket */
68 #define TEST_SUN_PATH "test.sock"
69 #define TEST_SUN_PATHB "testb.sock"
71 /* filenames for symlinks -- we link these to each other to test ELOOP .*/
72 #define TEST_SYM_A "test.a"
73 #define TEST_SYM_B "test.b"
75 /* text file and test phrase for testing file descriptor passing */
76 #define TEST_TXT_FILE "test.txt"
77 #define MSG "This raccoon loves to eat bugs.\n"
79 /* buffer for send/recv */
82 #define ISO8601_FORMAT "%Y-%m-%dT%H:%M:%S"
84 /* socket types supported */
85 int types
[3] = {SOCK_STREAM
, SOCK_SEQPACKET
, SOCK_DGRAM
};
86 char sock_fullpath
[PATH_MAX
+ 1];
88 void test_abort_client_server(int abort_type
);
89 void test_abort_client(int abort_type
);
90 void test_abort_server(pid_t pid
, int abort_type
);
92 /* timestamps for debug and error logs */
93 char *get_timestamp(void)
100 len
= sizeof(char) * 32;
111 s
= (char *) malloc(len
);
116 memset(s
, '\0', len
);
118 strftime(s
, len
- 1, ISO8601_FORMAT
, tm
);
122 /* macro to display information about a failed test and increment the errct */
123 void test_fail_fl(char *msg
, char *file
, int line
)
126 timestamp
= get_timestamp();
127 if (errct
== 0) fprintf(stderr
, "\n");
128 fprintf(stderr
, "[ERROR][%s] (%s Line %d) %s [pid=%d:errno=%d:%s]\n",
129 timestamp
, file
, line
, msg
, getpid(),
130 errno
, strerror(errno
));
132 if (timestamp
!= NULL
) {
138 #define test_fail(msg) test_fail_fl(msg, __FILE__, __LINE__)
140 /* Convert name to the full path of the socket. Assumes name is in cwd. */
141 char *fullpath(char *name
)
143 char cwd
[PATH_MAX
+ 1];
145 if (realpath(".", cwd
) == NULL
)
146 test_fail("Couldn't retrieve current working dir");
148 snprintf(sock_fullpath
, PATH_MAX
, "%s/%s", cwd
, name
);
150 return(sock_fullpath
);
154 /* macros to display debugging information */
155 void debug_fl(char *msg
, char *file
, int line
)
158 timestamp
= get_timestamp();
159 fprintf(stdout
,"[DEBUG][%s] (%s:%d) %s [pid=%d]\n",
160 timestamp
, __FILE__
, __LINE__
, msg
, getpid());
162 if (timestamp
!= NULL
) {
167 #define debug(msg) debug_fl(msg, __FILE__, __LINE__)
172 #define SOCKET(sd,domain,type,protocol) \
175 sd = socket(domain, type, protocol); \
177 test_fail("sd = socket(domain, type, protocol) failed");\
181 #define UNLINK(path) \
186 if (rc == -1 && errno != ENOENT) { \
187 test_fail("unlink(path) failed"); \
191 #define SYMLINK(oldpath,newpath) \
195 rc = symlink(oldpath,newpath); \
197 test_fail("symlink(oldpath,newpath) failed"); \
207 test_fail("close(sd) failed"); \
211 void test_socket(void)
213 struct stat statbuf
, statbuf2
;
218 debug("entering test_socket()");
220 debug("Test socket() with an unsupported address family");
223 sd
= socket(-1, SOCK_STREAM
, 0);
224 if (!(sd
== -1 && errno
== EAFNOSUPPORT
)) {
231 debug("Test socket() with all available FDs open by this process");
233 for (i
= 3; i
< getdtablesize(); i
++) {
234 rc
= open("/dev/null", O_RDONLY
);
236 test_fail("we couldn't open /dev/null for read");
241 sd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
242 if (!(sd
== -1 && errno
== EMFILE
)) {
243 test_fail("socket() call with all fds open should fail");
249 for (i
= 3; i
< getdtablesize(); i
++) {
253 debug("Test socket() with an mismatched protocol");
256 sd
= socket(PF_UNIX
, SOCK_STREAM
, 4);
257 if (!(sd
== -1 && errno
== EPROTONOSUPPORT
)) {
258 test_fail("socket() should fail with errno = EPROTONOSUPPORT");
264 debug("Test socket() success");
267 * open 2 sockets at once and *then* close them.
268 * This will test that /dev/uds is cloning properly.
271 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
272 SOCKET(sd2
, PF_UNIX
, SOCK_STREAM
, 0);
274 rc
= fstat(sd
, &statbuf
);
276 test_fail("fstat failed on sd");
279 rc
= fstat(sd2
, &statbuf2
);
281 test_fail("fstat failed on sd2");
285 if (statbuf
.st_dev
== statbuf2
.st_dev
) {
286 test_fail("/dev/uds isn't being cloned");
292 debug("leaving test_socket()");
295 void test_header(void)
297 struct sockaddr_un sun
;
298 debug("entering test_header()");
300 sun
.sun_family
= AF_UNIX
;
301 sun
.sun_path
[0] = 'x';
302 sun
.sun_path
[1] = 'x';
303 sun
.sun_path
[2] = 'x';
304 sun
.sun_path
[3] = '\0';
306 if (SUN_LEN(&sun
) != 5) {
307 test_fail("SUN_LEN(&sun) should be 5");
310 if (PF_UNIX
!= PF_LOCAL
|| PF_UNIX
!= AF_UNIX
) {
311 test_fail("PF_UNIX, PF_LOCAL and AF_UNIX");
315 void test_socketpair(void)
318 struct sockaddr_un addr
;
319 int socket_vector
[2];
323 debug("entering test_socketpair()");
325 UNLINK(TEST_SUN_PATH
);
326 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
327 addr
.sun_family
= AF_UNIX
;
328 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
330 debug("Testing socketpair() success");
332 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, socket_vector
);
334 test_fail("socketpair() should have worked");
337 debug("Testing a simple read/write using sockets from socketpair()");
338 memset(buf
, '\0', sizeof(buf
));
340 strncpy(buf
, "Howdy Partner", sizeof(buf
) - 1);
342 rc
= write(socket_vector
[0], buf
, sizeof(buf
));
344 test_fail("write(sd, buf, sizeof(buf)) failed unexpectedly");
347 memset(buf
, '\0', sizeof(buf
));
349 rc
= read(socket_vector
[1], buf
, sizeof(buf
));
351 test_fail("read() failed unexpectedly");
354 if (strncmp(buf
, "Howdy Partner", strlen("Howdy Partner")) != 0) {
355 test_fail("We did not read what we wrote");
358 CLOSE(socket_vector
[0]);
359 CLOSE(socket_vector
[1]);
361 debug("Test socketpair() with all FDs open by this process");
363 for (i
= 3; i
< getdtablesize(); i
++) {
364 rc
= open("/dev/null", O_RDONLY
);
366 test_fail("we couldn't open /dev/null for read");
370 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, socket_vector
);
371 if (!(rc
== -1 && errno
== EMFILE
)) {
372 test_fail("socketpair() should have failed with EMFILE");
375 for (i
= 3; i
< getdtablesize(); i
++) {
379 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 4, socket_vector
);
380 if (!(rc
== -1 && errno
== EPROTONOSUPPORT
)) {
381 test_fail("socketpair() should have failed");
384 debug("leaving test_socketpair()");
387 void test_ucred(void)
389 struct uucred credentials
;
390 socklen_t ucred_length
;
391 uid_t euid
= geteuid();
392 gid_t egid
= getegid();
396 debug("Test credentials passing");
398 ucred_length
= sizeof(struct uucred
);
400 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sv
);
402 test_fail("socketpair(PF_UNIX, SOCK_STREAM, 0, sv) failed");
405 memset(&credentials
, '\0', ucred_length
);
406 rc
= getsockopt(sv
[0], SOL_SOCKET
, SO_PEERCRED
, &credentials
,
409 test_fail("getsockopt(SO_PEERCRED) failed");
410 } else if (credentials
.cr_ngroups
!= 0 ||
411 credentials
.cr_uid
!= geteuid() ||
412 credentials
.cr_gid
!= getegid()) {
413 /* printf("%d=%d %d=%d %d=%d",credentials.cr_ngroups, 0,
414 credentials.cr_uid, geteuid(), credentials.cr_gid, getegid()); */
415 test_fail("Credential passing gave us the wrong cred");
418 rc
= getpeereid(sv
[0], &euid
, &egid
);
420 test_fail("getpeereid(sv[0], &euid, &egid) failed");
421 } else if (credentials
.cr_uid
!= euid
|| credentials
.cr_gid
!= egid
) {
422 test_fail("getpeereid() didn't give the correct euid/egid");
429 void test_getsockname(void)
433 struct sockaddr_un addr
, sock_addr
;
434 socklen_t sock_addr_len
;
436 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
437 addr
.sun_family
= AF_UNIX
;
438 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
440 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
441 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
443 test_fail("bind() should have worked");
446 debug("Test getsockname() success");
448 memset(&sock_addr
, '\0', sizeof(struct sockaddr_un
));
449 sock_addr_len
= sizeof(struct sockaddr_un
);
451 rc
= getsockname(sd
, (struct sockaddr
*) &sock_addr
, &sock_addr_len
);
453 test_fail("getsockname() should have worked");
456 if (!(sock_addr
.sun_family
== AF_UNIX
&& strncmp(sock_addr
.sun_path
,
457 fullpath(TEST_SUN_PATH
),
458 sizeof(sock_addr
.sun_path
) - 1) == 0)) {
459 test_fail("getsockname() did return the right address");
460 fprintf(stderr
, "exp: '%s' | got: '%s'\n", addr
.sun_path
,
469 struct sockaddr_un addr
;
470 struct sockaddr_un sock_addr
;
471 socklen_t sock_addr_len
;
476 debug("entering test_bind()");
477 UNLINK(TEST_SUN_PATH
);
478 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
479 addr
.sun_family
= AF_UNIX
;
480 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
482 debug("Test bind() success");
484 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
485 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
487 test_fail("bind() should have worked");
490 debug("Test getsockname() success");
492 memset(&sock_addr
, '\0', sizeof(struct sockaddr_un
));
493 sock_addr_len
= sizeof(struct sockaddr_un
);
495 rc
= getsockname(sd
, (struct sockaddr
*) &sock_addr
, &sock_addr_len
);
497 test_fail("getsockname() should have worked");
500 if (!(sock_addr
.sun_family
== AF_UNIX
&&
501 strncmp(sock_addr
.sun_path
,
502 fullpath(TEST_SUN_PATH
),
503 sizeof(sock_addr
.sun_path
) - 1) == 0)) {
505 test_fail("getsockname() didn't return the right addr");
506 fprintf(stderr
, "exp: '%s' | got: '%s'\n", addr
.sun_path
,
510 debug("Test bind() with a address that has already been bind()'d");
512 SOCKET(sd2
, PF_UNIX
, SOCK_STREAM
, 0);
514 rc
= bind(sd2
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
515 if (!((rc
== -1) && (errno
== EADDRINUSE
))) {
516 test_fail("bind() should have failed with EADDRINUSE");
520 UNLINK(TEST_SUN_PATH
);
522 debug("Test bind() with an empty sun_path");
524 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
525 memset(addr
.sun_path
, '\0', sizeof(addr
.sun_path
));
528 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
529 if (!(rc
== -1 && errno
== ENOENT
)) {
530 test_fail("bind() should have failed with ENOENT");
534 debug("Test bind() with a NULL address");
536 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
538 rc
= bind(sd
, (struct sockaddr
*) NULL
, sizeof(struct sockaddr_un
));
539 if (!((rc
== -1) && (errno
== EFAULT
))) {
540 test_fail("bind() should have failed with EFAULT");
544 debug("Test bind() using a symlink loop");
546 UNLINK(TEST_SUN_PATH
);
550 SYMLINK(TEST_SYM_A
, TEST_SYM_B
);
551 SYMLINK(TEST_SYM_B
, TEST_SYM_A
);
553 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
555 strncpy(addr
.sun_path
, TEST_SYM_A
, sizeof(addr
.sun_path
) - 1);
557 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
558 if (!((rc
== -1) && (errno
== ELOOP
))) {
559 test_fail("bind() should have failed with ELOOP");
563 UNLINK(TEST_SUN_PATH
);
567 /* Test bind with garbage in sockaddr_un */
568 memset(&addr
, '?', sizeof(struct sockaddr_un
));
569 addr
.sun_family
= AF_UNIX
;
570 addr
.sun_path
[0] = 'f';
571 addr
.sun_path
[1] = 'o';
572 addr
.sun_path
[2] = 'o';
573 addr
.sun_path
[3] = '\0';
574 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
575 rc
= bind(sd
, (struct sockaddr
*) &addr
, strlen(addr
.sun_path
) + 1);
577 test_fail("bind() should have worked");
582 debug("leaving test_bind()");
585 void test_listen(void)
589 debug("entering test_listen()");
591 debug("Test listen() with a bad file descriptor");
595 if (!(rc
== -1 && errno
== EBADF
)) {
596 test_fail("listen(-1, 0) should have failed");
599 debug("Test listen() with a non-socket file descriptor");
603 /* Test on errno disabled here: there's currently no telling what this
604 * will return. POSIX says it should be ENOTSOCK, MINIX3 libc returns
605 * ENOSYS, and we used to test for ENOTTY here..
608 test_fail("listen(0, 0) should have failed");
611 debug("leaving test_listen()");
614 void test_shutdown(void)
616 int how
[3] = { SHUT_RD
, SHUT_WR
, SHUT_RDWR
};
621 debug("entering test_shutdown()");
623 /* test for each direction (read, write, read-write) */
624 for (i
= 0; i
< 3; i
++) {
626 debug("test shutdown() with an invalid descriptor");
629 rc
= shutdown(-1, how
[i
]);
630 if (!(rc
== -1 && errno
== EBADF
)) {
631 test_fail("shutdown(-1, how[i]) should have failed");
634 debug("test shutdown() with a non-socket descriptor");
637 rc
= shutdown(0, how
[i
]);
638 if (!(rc
== -1 && errno
== ENOSYS
)) {
639 test_fail("shutdown() should have failed with ENOSYS");
642 debug("test shutdown() with a socket that is not connected");
644 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
646 rc
= shutdown(sd
, how
[i
]);
647 if (!(rc
== -1 && errno
== ENOTCONN
)) {
648 test_fail("shutdown() should have failed");
653 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
655 rc
= shutdown(sd
, -1);
656 if (!(rc
== -1 && errno
== ENOTCONN
)) {
657 test_fail("shutdown(sd, -1) should have failed with ENOTCONN");
661 debug("leaving test_shutdown()");
664 void test_close(void)
666 struct sockaddr_un addr
;
670 debug("entering test_close()");
672 UNLINK(TEST_SUN_PATH
);
674 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
675 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
676 addr
.sun_family
= AF_UNIX
;
678 debug("Test close() success");
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");
688 debug("Close an already closed file descriptor");
692 if (!(rc
== -1 && errno
== EBADF
)) {
693 test_fail("close(sd) should have failed with EBADF");
696 UNLINK(TEST_SUN_PATH
);
698 debug("dup()'ing a file descriptor and closing both should work");
700 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
701 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
703 test_fail("bind() should have worked");
709 test_fail("dup(sd) should have worked");
715 UNLINK(TEST_SUN_PATH
);
717 /* Create and close a socket a bunch of times.
718 * If the implementation doesn't properly free the
719 * socket during close(), eventually socket() will
720 * fail when the internal descriptor table is full.
722 for (i
= 0; i
< 1024; i
++) {
723 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
727 debug("leaving test_close()");
730 void test_sockopts(void)
736 socklen_t option_len
;
738 debug("entering test_sockopts()");
740 for (i
= 0; i
< 3; i
++) {
742 SOCKET(sd
, PF_UNIX
, types
[i
], 0);
744 debug("Test setsockopt() works");
747 option_len
= sizeof(option_value
);
749 rc
= getsockopt(sd
, SOL_SOCKET
, SO_TYPE
, &option_value
,
752 test_fail("setsockopt() should have worked");
755 if (option_value
!= types
[i
]) {
756 test_fail("SO_TYPE didn't seem to work.");
764 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
766 debug("Test setsockopt() works");
769 option_len
= sizeof(option_value
);
771 rc
= getsockopt(sd
, SOL_SOCKET
, SO_SNDBUF
, &option_value
, &option_len
);
773 test_fail("getsockopt() should have worked");
776 if (option_value
!= PIPE_BUF
) {
777 test_fail("SO_SNDBUF didn't seem to work.");
783 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
785 debug("Test setsockopt() works");
788 option_len
= sizeof(option_value
);
790 rc
= getsockopt(sd
, SOL_SOCKET
, SO_RCVBUF
, &option_value
, &option_len
);
792 test_fail("getsockopt() should have worked");
795 if (option_value
!= PIPE_BUF
) {
796 test_fail("SO_RCVBUF didn't seem to work.");
802 debug("leaving test_sockopts()");
811 debug("entering test_read()");
814 rc
= read(-1, buf
, sizeof(buf
));
815 if (!(rc
== -1 && errno
== EBADF
)) {
816 test_fail("read() should have failed with EBADF");
819 fd
= open("/tmp", O_RDONLY
);
821 test_fail("open(\"/tmp\", O_RDONLY) should have worked");
826 debug("leaving test_read()");
829 void test_write(void)
834 debug("entering test_write()");
837 rc
= write(-1, buf
, sizeof(buf
));
838 if (!(rc
== -1 && errno
== EBADF
)) {
839 test_fail("write() should have failed with EBADF");
842 debug("leaving test_write()");
849 struct sockaddr_un addr
;
854 debug("entering test_dup()");
856 UNLINK(TEST_SUN_PATH
);
858 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
859 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
860 addr
.sun_family
= AF_UNIX
;
864 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
865 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
867 test_fail("bind() should have worked");
873 test_fail("dup(sd) should have worked");
876 rc
= fstat(sd
, &info1
);
878 test_fail("fstat(fd, &info1) failed");
881 rc
= fstat(sd2
, &info2
);
883 test_fail("fstat(sd, &info2) failed");
886 if (info1
.st_ino
!= info2
.st_ino
) {
887 test_fail("dup() failed info1.st_ino != info2.st_ino");
893 debug("Test dup() with a closed socket");
897 if (!(rc
== -1 && errno
== EBADF
)) {
898 test_fail("dup(sd) on a closed socket shouldn't have worked");
901 debug("Test dup() with socket descriptor of -1");
905 if (!(rc
== -1 && errno
== EBADF
)) {
906 test_fail("dup(-1) shouldn't have worked");
909 debug("Test dup() when all of the file descriptors are taken");
911 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
913 for (i
= 4; i
< getdtablesize(); i
++) {
914 rc
= open("/dev/null", O_RDONLY
);
916 test_fail("we couldn't open /dev/null for read");
922 if (!(sd2
== -1 && errno
== EMFILE
)) {
923 test_fail("dup(sd) should have failed with errno = EMFILE");
926 for (i
= 3; i
< getdtablesize(); i
++) {
930 UNLINK(TEST_SUN_PATH
);
932 debug("leaving test_dup()");
939 struct sockaddr_un addr
;
944 debug("entering test_dup2()");
945 UNLINK(TEST_SUN_PATH
);
947 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
948 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
949 addr
.sun_family
= AF_UNIX
;
951 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
953 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
955 test_fail("bind() should have worked");
958 fd
= open("/dev/null", O_RDONLY
);
960 test_fail("open(\"/dev/null\", O_RDONLY) failed");
965 test_fail("dup2(sd, fd) failed.");
968 memset(&info1
, '\0', sizeof(struct stat
));
969 memset(&info2
, '\0', sizeof(struct stat
));
971 rc
= fstat(fd
, &info1
);
973 test_fail("fstat(fd, &info1) failed");
976 rc
= fstat(sd
, &info2
);
978 test_fail("fstat(sd, &info2) failed");
981 if (!(info1
.st_ino
== info2
.st_ino
&&
982 major(info1
.st_dev
) == major(info2
.st_dev
) &&
983 minor(info1
.st_dev
) == minor(info2
.st_dev
))) {
985 test_fail("dup2() failed");
991 UNLINK(TEST_SUN_PATH
);
992 debug("leaving test_dup2()");
997 * A toupper() server. This toy server converts a string to upper case.
999 void test_xfer_server(pid_t pid
)
1008 socklen_t client_addr_size
;
1010 struct sockaddr_un addr
;
1011 struct sockaddr_un client_addr
;
1017 client_addr_size
= sizeof(struct sockaddr_un
);
1019 memset(&buf
, '\0', sizeof(buf
));
1020 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
1021 memset(&client_addr
, '\0', sizeof(struct sockaddr_un
));
1023 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1024 addr
.sun_family
= AF_UNIX
;
1026 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
1028 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
1030 test_fail("bind() should have worked");
1035 test_fail("listen(sd, 8) should have worked");
1038 /* we're ready for connections, time to tell the client to start
1047 FD_SET(sd
, &readfds
);
1049 /* use select() in case the client is really broken and never
1050 * attempts to connect (we don't want to block on accept()
1053 rc
= select(sd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1055 test_fail("[server] select() should not have failed");
1059 test_fail("[server] select() should have returned 1");
1060 printf("[server] select returned %d\n", rc
);
1063 if (!(FD_ISSET(sd
, &readfds
))) {
1064 test_fail("[server] client didn't connect within 10 seconds");
1069 client_sd
= accept(sd
, (struct sockaddr
*) &client_addr
,
1072 if (client_sd
== -1) {
1073 test_fail("accept() should have worked");
1077 debug("[server] client accept()'d");
1080 debug("[server] Reading message");
1081 rc
= read(client_sd
, buf
, sizeof(buf
));
1083 test_fail("read() failed unexpectedly");
1087 debug("[server] we got the following message:");
1090 for (i
= 0; i
< rc
&& i
< 127; i
++) {
1091 buf
[i
] = toupper(buf
[i
]);
1094 debug("[server] Writing message...");
1095 rc
= write(client_sd
, buf
, sizeof(buf
));
1097 test_fail("write(client_sd, buf, sizeof(buf)) failed");
1102 if (rc
< strlen(buf
)) {
1103 test_fail("[server] write didn't write all the bytes");
1106 memset(&buf
, '\0', sizeof(buf
));
1108 debug("[server] Recv message");
1109 rc
= recv(client_sd
, buf
, sizeof(buf
), 0);
1111 test_fail("recv() failed unexpectedly");
1115 debug("[server] we got the following message:");
1118 for (i
= 0; i
< rc
&& i
< 127; i
++) {
1119 buf
[i
] = toupper(buf
[i
]);
1122 debug("[server] Sending message...");
1123 rc
= send(client_sd
, buf
, sizeof(buf
), 0);
1125 test_fail("send(client_sd, buf, sizeof(buf), 0) failed");
1130 if (rc
< strlen(buf
)) {
1131 test_fail("[server] write didn't write all the bytes");
1134 memset(&buf
, '\0', sizeof(buf
));
1136 debug("[server] Recvfrom message");
1137 rc
= recvfrom(client_sd
, buf
, sizeof(buf
), 0, NULL
, 0);
1139 test_fail("recvfrom() failed unexpectedly");
1143 debug("[server] we got the following message:");
1146 for (i
= 0; i
< rc
&& i
< 127; i
++) {
1147 buf
[i
] = toupper(buf
[i
]);
1150 debug("[server] Sendto message...");
1151 rc
= sendto(client_sd
, buf
, sizeof(buf
), 0, NULL
, 0);
1153 test_fail("sendto() failed");
1158 if (rc
< strlen(buf
)) {
1159 test_fail("[server] write didn't write all the bytes");
1162 shutdown(client_sd
, SHUT_RDWR
);
1165 shutdown(sd
, SHUT_RDWR
);
1168 /* wait for client to exit */
1171 rc
= waitpid(pid
, &status
, 0);
1172 } while (rc
== -1 && errno
== EINTR
);
1174 /* we use the exit status to get its error count */
1175 errct
+= WEXITSTATUS(status
);
1178 int server_ready
= 0;
1180 /* signal handler for the client */
1181 void test_xfer_sighdlr(int sig
)
1183 debug("entering signal handler");
1185 /* the server will send SIGUSR1 when it is time for us
1186 * to start the tests
1190 debug("got SIGUSR1, the server is ready for the client");
1193 debug("didn't get SIGUSR1");
1195 debug("leaving signal handler");
1199 * A toupper() client.
1201 void test_xfer_client(void)
1203 struct uucred credentials
;
1204 socklen_t ucred_length
;
1207 struct sockaddr_un addr
;
1208 struct sockaddr_un peer_addr
;
1209 socklen_t peer_addr_len
;
1214 debug("[client] entering test_xfer_client()");
1215 errct
= 0; /* reset error count */
1216 ucred_length
= sizeof(struct uucred
);
1217 memset(&buf
, '\0', sizeof(buf
));
1219 while (server_ready
== 0) {
1220 debug("[client] waiting for the server to signal");
1224 peer_addr_len
= sizeof(struct sockaddr_un
);
1227 debug("Creating symlink to TEST_SUN_PATH");
1229 SYMLINK(TEST_SUN_PATH
, TEST_SYM_A
);
1231 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
1232 strncpy(addr
.sun_path
, TEST_SYM_A
, sizeof(addr
.sun_path
) - 1);
1233 addr
.sun_family
= AF_UNIX
;
1235 debug("[client] creating client socket");
1236 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
1238 debug("[client] connecting to server through the symlink");
1239 rc
= connect(sd
, (struct sockaddr
*) &addr
,
1240 sizeof(struct sockaddr_un
));
1242 test_fail("[client] connect() should have worked");
1244 debug("[client] connected");
1247 debug("[client] testing getpeername()");
1248 memset(&peer_addr
, '\0', sizeof(struct sockaddr_un
));
1249 rc
= getpeername(sd
, (struct sockaddr
*) &peer_addr
, &peer_addr_len
);
1251 test_fail("[client] getpeername() should have worked");
1254 /* we need to use the full path "/usr/src/test/DIR_56/test.sock"
1255 * because that is what is returned by getpeername().
1258 if (!(peer_addr
.sun_family
== AF_UNIX
&&
1259 strncmp(peer_addr
.sun_path
,
1260 fullpath(TEST_SUN_PATH
),
1261 sizeof(peer_addr
.sun_path
) - 1) == 0)) {
1263 test_fail("getpeername() didn't return the right address");
1266 strncpy(buf
, "Hello, World!", sizeof(buf
) - 1);
1267 debug("[client] send to server");
1268 rc
= write(sd
, buf
, sizeof(buf
));
1270 test_fail("[client] write() failed unexpectedly");
1273 memset(buf
, '\0', sizeof(buf
));
1274 debug("[client] read from server");
1275 rc
= read(sd
, buf
, sizeof(buf
));
1277 test_fail("[client] read() failed unexpectedly");
1279 debug("[client] we got the following message:");
1283 if (strncmp(buf
, "HELLO, WORLD!", sizeof(buf
)) != 0) {
1284 test_fail("[client] We didn't get the correct response");
1287 memset(&buf
, '\0', sizeof(buf
));
1288 strncpy(buf
, "Bonjour!", sizeof(buf
) - 1);
1290 debug("[client] send to server");
1291 rc
= send(sd
, buf
, sizeof(buf
), 0);
1293 test_fail("[client] send() failed unexpectedly");
1296 debug("Test passing the client credentials to the server");
1298 memset(&credentials
, '\0', ucred_length
);
1299 rc
= getsockopt(sd
, SOL_SOCKET
, SO_PEERCRED
, &credentials
,
1303 test_fail("[client] getsockopt() failed");
1304 } else if (credentials
.cr_uid
!= geteuid() ||
1305 credentials
.cr_gid
!= getegid()) {
1306 printf("%d=%d=%d %d=%d=%d\n", credentials
.cr_uid
, getuid(),
1307 geteuid(), credentials
.cr_gid
, getgid(), getegid());
1308 test_fail("[client] Credential passing gave us a bad UID/GID");
1311 debug("Testing select()");
1314 tv
.tv_usec
= 500000;
1317 FD_SET(sd
, &readfds
);
1319 rc
= select(sd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1321 test_fail("[client] select() should not have failed");
1325 test_fail("[client] select() should have returned 1");
1328 if (!(FD_ISSET(sd
, &readfds
))) {
1329 test_fail("The server didn't respond within 2.5 seconds");
1332 memset(buf
, '\0', sizeof(buf
));
1333 debug("[client] recv from server");
1334 rc
= recv(sd
, buf
, sizeof(buf
), 0);
1336 test_fail("[client] recv() failed unexpectedly");
1338 debug("[client] we got the following message:");
1342 if (strncmp(buf
, "BONJOUR!", sizeof(buf
)) != 0) {
1343 test_fail("[client] We didn't get the right response.");
1346 memset(&buf
, '\0', sizeof(buf
));
1347 strncpy(buf
, "Hola!", sizeof(buf
) - 1);
1349 debug("[client] sendto to server");
1350 rc
= sendto(sd
, buf
, sizeof(buf
), 0, NULL
, 0);
1352 test_fail("[client] sendto() failed");
1355 debug("Testing select()");
1358 tv
.tv_usec
= 500000;
1361 FD_SET(sd
, &readfds
);
1363 rc
= select(sd
+ 1, &readfds
, NULL
, NULL
, &tv
);
1365 test_fail("[client] select() should not have failed");
1369 test_fail("[client] select() should have returned 1");
1372 if (!(FD_ISSET(sd
, &readfds
))) {
1373 test_fail("[client] The server didn't respond in 2.5 seconds");
1376 memset(buf
, '\0', sizeof(buf
));
1377 debug("[client] recvfrom from server");
1378 rc
= recvfrom(sd
, buf
, sizeof(buf
), 0, NULL
, 0);
1380 test_fail("[cleint] recvfrom() failed unexpectedly");
1382 debug("[client] we got the following message:");
1386 if (strncmp(buf
, "HOLA!", sizeof(buf
)) != 0) {
1387 test_fail("[client] We didn't get the right response.");
1390 debug("[client] closing socket");
1393 debug("[client] leaving test_xfer_client()");
1397 void test_xfer(void)
1402 UNLINK(TEST_SUN_PATH
);
1404 /* the signal handler is only used by the client, but we have to
1405 * install it now. if we don't the server may signal the client
1406 * before the handler is installed.
1408 debug("installing signal handler");
1409 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
1410 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1413 debug("signal handler installed");
1419 test_fail("fork() failed");
1421 } else if (pid
== 0) {
1424 test_fail("we should never get here");
1428 test_xfer_server(pid
);
1429 debug("parent done");
1433 UNLINK(TEST_SUN_PATH
);
1436 void test_simple_client(int type
)
1440 struct sockaddr_un addr
;
1442 sd
= socket(PF_UNIX
, type
, 0);
1444 test_fail("socket");
1448 while (server_ready
== 0) {
1449 debug("[client] waiting for the server");
1453 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1454 addr
.sun_family
= AF_UNIX
;
1456 bzero(buf
, BUFSIZE
);
1457 snprintf(buf
, BUFSIZE
-1, "Hello, My Name is Client.");
1459 if (type
== SOCK_DGRAM
) {
1461 rc
= sendto(sd
, buf
, strlen(buf
) + 1, 0,
1462 (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
1464 test_fail("sendto");
1470 rc
= connect(sd
, (struct sockaddr
*) &addr
,
1471 sizeof(struct sockaddr_un
));
1473 test_fail("connect");
1477 rc
= write(sd
, buf
, strlen(buf
) + 1);
1483 memset(buf
, '\0', BUFSIZE
);
1484 rc
= read(sd
, buf
, BUFSIZE
);
1489 if (strcmp("Hello, My Name is Server.", buf
) != 0) {
1490 test_fail("didn't read the correct string");
1502 void test_simple_server(int type
, pid_t pid
)
1505 int sd
, rc
, client_sd
, status
;
1506 struct sockaddr_un addr
;
1509 addr_len
= sizeof(struct sockaddr_un
);
1511 sd
= socket(PF_UNIX
, type
, 0);
1513 test_fail("socket");
1516 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1517 addr
.sun_family
= AF_UNIX
;
1519 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
1524 if (type
== SOCK_DGRAM
) {
1526 /* ready for client */
1529 rc
= recvfrom(sd
, buf
, BUFSIZE
, 0,
1530 (struct sockaddr
*) &addr
, &addr_len
);
1532 test_fail("recvfrom");
1539 test_fail("listen");
1542 /* we're ready for connections, time to tell the client
1547 client_sd
= accept(sd
, (struct sockaddr
*) &addr
, &addr_len
);
1548 if (client_sd
== -1) {
1549 test_fail("accept");
1552 memset(buf
, '\0', BUFSIZE
);
1553 rc
= read(client_sd
, buf
, BUFSIZE
);
1558 if (strcmp("Hello, My Name is Client.", buf
) != 0) {
1559 test_fail("didn't read the correct string");
1562 /* added for extra fun to make the client block on read() */
1565 bzero(buf
, BUFSIZE
);
1566 snprintf(buf
, BUFSIZE
-1, "Hello, My Name is Server.");
1568 rc
= write(client_sd
, buf
, strlen(buf
) + 1);
1572 rc
= close(client_sd
);
1583 /* wait for client to exit */
1586 rc
= waitpid(pid
, &status
, 0);
1587 } while (rc
== -1 && errno
== EINTR
);
1589 /* we use the exit status to get its error count */
1590 errct
+= WEXITSTATUS(status
);
1593 void test_abort_client_server(int abort_type
)
1596 debug("test_simple_client_server()");
1598 UNLINK(TEST_SUN_PATH
);
1600 /* the signal handler is only used by the client, but we have to
1601 * install it now. if we don't the server may signal the client
1602 * before the handler is installed.
1604 debug("installing signal handler");
1605 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
1606 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1609 debug("signal handler installed");
1615 test_fail("fork() failed");
1617 } else if (pid
== 0) {
1619 test_abort_client(abort_type
);
1620 test_fail("we should never get here");
1624 test_abort_server(pid
, abort_type
);
1625 debug("parent done");
1628 UNLINK(TEST_SUN_PATH
);
1631 void test_abort_client(int abort_type
)
1635 struct sockaddr_un addr
;
1637 sd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
1639 test_fail("socket");
1643 while (server_ready
== 0) {
1644 debug("[client] waiting for the server");
1648 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1649 addr
.sun_family
= AF_UNIX
;
1651 bzero(buf
, BUFSIZE
);
1652 snprintf(buf
, BUFSIZE
-1, "Hello, My Name is Client.");
1654 rc
= connect(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
1656 test_fail("connect");
1660 if (abort_type
== 2) {
1661 /* Give server a chance to close connection */
1663 rc
= write(sd
, buf
, strlen(buf
) + 1);
1665 test_fail("write should have failed\n");
1667 if (errno
!= ECONNRESET
) {
1668 test_fail("errno should've been ECONNRESET\n");
1680 void test_abort_server(pid_t pid
, int abort_type
)
1683 int sd
, rc
, client_sd
, status
;
1684 struct sockaddr_un addr
;
1687 addr_len
= sizeof(struct sockaddr_un
);
1689 sd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
1691 test_fail("socket");
1694 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
1695 addr
.sun_family
= AF_UNIX
;
1697 rc
= bind(sd
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_un
));
1704 test_fail("listen");
1707 /* we're ready for connections, time to tell the client
1712 client_sd
= accept(sd
, (struct sockaddr
*) &addr
, &addr_len
);
1713 if (client_sd
== -1) {
1714 test_fail("accept");
1717 if (abort_type
== 1) {
1718 memset(buf
, '\0', BUFSIZE
);
1719 rc
= read(client_sd
, buf
, BUFSIZE
);
1721 test_fail("read should've failed\n");
1723 if (errno
!= ECONNRESET
) {
1724 test_fail("errno should've been ECONNRESET\n");
1726 } /* else if (abort_type == 2) { */
1727 rc
= close(client_sd
);
1738 /* wait for client to exit */
1741 rc
= waitpid(pid
, &status
, 0);
1742 } while (rc
== -1 && errno
== EINTR
);
1744 /* we use the exit status to get its error count */
1745 errct
+= WEXITSTATUS(status
);
1748 void test_simple_client_server(int type
)
1751 debug("test_simple_client_server()");
1753 UNLINK(TEST_SUN_PATH
);
1755 /* the signal handler is only used by the client, but we have to
1756 * install it now. if we don't the server may signal the client
1757 * before the handler is installed.
1759 debug("installing signal handler");
1760 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
1761 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1764 debug("signal handler installed");
1770 test_fail("fork() failed");
1772 } else if (pid
== 0) {
1774 test_simple_client(type
);
1775 test_fail("we should never get here");
1779 test_simple_server(type
, pid
);
1780 debug("parent done");
1783 UNLINK(TEST_SUN_PATH
);
1786 void test_vectorio(int type
)
1790 struct iovec iov
[3];
1794 char buf4
[BUFSIZE
*3];
1795 const struct iovec
*iovp
= iov
;
1797 debug("begin vectorio tests");
1799 memset(buf1
, '\0', BUFSIZE
);
1800 strncpy(buf1
, "HELLO ", BUFSIZE
- 1);
1802 memset(buf2
, '\0', BUFSIZE
);
1803 strncpy(buf2
, "WORLD", BUFSIZE
- 1);
1805 memset(buf3
, '\0', BUFSIZE
);
1807 rc
= socketpair(PF_UNIX
, type
, 0, sv
);
1809 test_fail("socketpair");
1812 iov
[0].iov_base
= buf1
;
1813 iov
[0].iov_len
= strlen(buf1
);
1814 iov
[1].iov_base
= buf2
;
1815 iov
[1].iov_len
= strlen(buf2
);
1816 iov
[2].iov_base
= buf3
;
1819 rc
= writev(sv
[0], iovp
, 3);
1821 test_fail("writev");
1824 memset(buf4
, '\0', BUFSIZE
*3);
1826 rc
= read(sv
[1], buf4
, BUFSIZE
*3);
1831 if (strncmp(buf4
, "HELLO WORLD", strlen("HELLO WORLD"))) {
1832 test_fail("the string we read was not 'HELLO WORLD'");
1835 memset(buf1
, '\0', BUFSIZE
);
1836 strncpy(buf1
, "Unit Test Time", BUFSIZE
- 1);
1838 rc
= write(sv
[1], buf1
, strlen(buf1
) + 1);
1843 memset(buf2
, '\0', BUFSIZE
);
1844 memset(buf3
, '\0', BUFSIZE
);
1845 memset(buf4
, '\0', BUFSIZE
*3);
1847 iov
[0].iov_base
= buf2
;
1849 iov
[1].iov_base
= buf3
;
1851 iov
[2].iov_base
= buf4
;
1852 iov
[2].iov_len
= 32;
1854 rc
= readv(sv
[0], iovp
, 3);
1859 if (strncmp(buf2
, "Unit ", 5) || strncmp(buf3
, "Test ", 5) ||
1860 strncmp(buf4
, "Time", 4)) {
1874 debug("done vector io tests");
1877 void test_msg(int type
)
1883 struct iovec iov
[3];
1887 char buf4
[BUFSIZE
*3];
1889 debug("begin sendmsg/recvmsg tests");
1891 memset(buf1
, '\0', BUFSIZE
);
1892 strncpy(buf1
, "HELLO ", BUFSIZE
- 1);
1894 memset(buf2
, '\0', BUFSIZE
);
1895 strncpy(buf2
, "WORLD", BUFSIZE
- 1);
1897 memset(buf3
, '\0', BUFSIZE
);
1899 rc
= socketpair(PF_UNIX
, type
, 0, sv
);
1901 test_fail("socketpair");
1904 iov
[0].iov_base
= buf1
;
1905 iov
[0].iov_len
= strlen(buf1
);
1906 iov
[1].iov_base
= buf2
;
1907 iov
[1].iov_len
= strlen(buf2
);
1908 iov
[2].iov_base
= buf3
;
1911 memset(&msg1
, '\0', sizeof(struct msghdr
));
1912 msg1
.msg_name
= NULL
;
1913 msg1
.msg_namelen
= 0;
1915 msg1
.msg_iovlen
= 3;
1916 msg1
.msg_control
= NULL
;
1917 msg1
.msg_controllen
= 0;
1920 rc
= sendmsg(sv
[0], &msg1
, 0);
1922 test_fail("writev");
1925 memset(buf4
, '\0', BUFSIZE
*3);
1927 rc
= read(sv
[1], buf4
, BUFSIZE
*3);
1932 if (strncmp(buf4
, "HELLO WORLD", strlen("HELLO WORLD"))) {
1933 test_fail("the string we read was not 'HELLO WORLD'");
1936 memset(buf1
, '\0', BUFSIZE
);
1937 strncpy(buf1
, "Unit Test Time", BUFSIZE
- 1);
1939 rc
= write(sv
[1], buf1
, strlen(buf1
) + 1);
1944 memset(buf2
, '\0', BUFSIZE
);
1945 memset(buf3
, '\0', BUFSIZE
);
1946 memset(buf4
, '\0', BUFSIZE
*3);
1948 iov
[0].iov_base
= buf2
;
1950 iov
[1].iov_base
= buf3
;
1952 iov
[2].iov_base
= buf4
;
1953 iov
[2].iov_len
= 32;
1955 memset(&msg2
, '\0', sizeof(struct msghdr
));
1956 msg2
.msg_name
= NULL
;
1957 msg2
.msg_namelen
= 0;
1959 msg2
.msg_iovlen
= 3;
1960 msg2
.msg_control
= NULL
;
1961 msg2
.msg_controllen
= 0;
1964 rc
= recvmsg(sv
[0], &msg2
, 0);
1969 if (strncmp(buf2
, "Unit ", 5) || strncmp(buf3
, "Test ", 5) ||
1970 strncmp(buf4
, "Time", 4)) {
1985 void test_msg_dgram(void)
1990 struct sockaddr_un addr
;
1991 struct iovec iov
[3];
1997 socklen_t addrlen
= sizeof(struct sockaddr_un
);
1999 debug("test msg_dgram");
2001 UNLINK(TEST_SUN_PATH
);
2002 UNLINK(TEST_SUN_PATHB
);
2004 src
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
2006 test_fail("socket");
2009 dst
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
2011 test_fail("socket");
2014 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
2015 addr
.sun_family
= AF_UNIX
;
2016 strncpy(addr
.sun_path
, TEST_SUN_PATHB
, sizeof(addr
.sun_path
) - 1);
2017 rc
= bind(src
, (struct sockaddr
*) &addr
, addrlen
);
2022 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
2023 addr
.sun_family
= AF_UNIX
;
2024 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
2026 rc
= bind(dst
, (struct sockaddr
*) &addr
, addrlen
);
2031 memset(&buf1
, '\0', BUFSIZE
);
2032 memset(&buf2
, '\0', BUFSIZE
);
2033 memset(&buf3
, '\0', BUFSIZE
);
2035 strncpy(buf1
, "Minix ", BUFSIZE
-1);
2036 strncpy(buf2
, "is ", BUFSIZE
-1);
2037 strncpy(buf3
, "great!", BUFSIZE
-1);
2039 iov
[0].iov_base
= buf1
;
2041 iov
[1].iov_base
= buf2
;
2043 iov
[2].iov_base
= buf3
;
2044 iov
[2].iov_len
= 32;
2046 memset(&msg1
, '\0', sizeof(struct msghdr
));
2047 msg1
.msg_name
= &addr
;
2048 msg1
.msg_namelen
= addrlen
;
2050 msg1
.msg_iovlen
= 3;
2051 msg1
.msg_control
= NULL
;
2052 msg1
.msg_controllen
= 0;
2055 rc
= sendmsg(src
, &msg1
, 0);
2057 test_fail("sendmsg");
2060 memset(&buf1
, '\0', BUFSIZE
);
2061 memset(&buf2
, '\0', BUFSIZE
);
2063 iov
[0].iov_base
= buf1
;
2065 iov
[1].iov_base
= buf2
;
2066 iov
[1].iov_len
= 32;
2068 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
2069 memset(&msg2
, '\0', sizeof(struct msghdr
));
2070 msg2
.msg_name
= &addr
;
2071 msg2
.msg_namelen
= sizeof(struct sockaddr_un
);
2073 msg2
.msg_iovlen
= 2;
2074 msg2
.msg_control
= NULL
;
2075 msg2
.msg_controllen
= 0;
2078 rc
= recvmsg(dst
, &msg2
, 0);
2080 test_fail("recvmsg");
2083 if (strncmp(buf1
, "Minix is ", 9) || strncmp(buf2
, "great!", 6)) {
2084 test_fail("recvmsg");
2087 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
2088 * because that is what is returned by recvmsg().
2090 if (addr
.sun_family
!= AF_UNIX
|| strcmp(addr
.sun_path
,
2091 fullpath(TEST_SUN_PATHB
))) {
2092 test_fail("recvmsg");
2105 UNLINK(TEST_SUN_PATH
);
2106 UNLINK(TEST_SUN_PATHB
);
2109 void test_scm_credentials(void)
2115 struct cmsghdr
*cmsg
= NULL
;
2116 struct sockaddr_un addr
;
2117 struct iovec iov
[3];
2124 socklen_t addrlen
= sizeof(struct sockaddr_un
);
2126 debug("test_scm_credentials");
2128 UNLINK(TEST_SUN_PATH
);
2129 UNLINK(TEST_SUN_PATHB
);
2131 debug("creating src socket");
2133 src
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
2135 test_fail("socket");
2138 debug("creating dst socket");
2140 dst
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
2142 test_fail("socket");
2145 debug("binding src socket");
2147 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
2148 addr
.sun_family
= AF_UNIX
;
2149 strncpy(addr
.sun_path
, TEST_SUN_PATHB
, sizeof(addr
.sun_path
) - 1);
2150 rc
= bind(src
, (struct sockaddr
*) &addr
, addrlen
);
2155 debug("binding dst socket");
2157 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
2158 addr
.sun_family
= AF_UNIX
;
2159 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
2161 rc
= bind(dst
, (struct sockaddr
*) &addr
, addrlen
);
2166 memset(&buf1
, '\0', BUFSIZE
);
2167 memset(&buf2
, '\0', BUFSIZE
);
2168 memset(&buf3
, '\0', BUFSIZE
);
2169 memset(&ctrl
, '\0', BUFSIZE
);
2171 strncpy(buf1
, "Minix ", BUFSIZE
-1);
2172 strncpy(buf2
, "is ", BUFSIZE
-1);
2173 strncpy(buf3
, "great!", BUFSIZE
-1);
2175 iov
[0].iov_base
= buf1
;
2177 iov
[1].iov_base
= buf2
;
2179 iov
[2].iov_base
= buf3
;
2180 iov
[2].iov_len
= 32;
2182 memset(&msg1
, '\0', sizeof(struct msghdr
));
2183 msg1
.msg_name
= &addr
;
2184 msg1
.msg_namelen
= addrlen
;
2186 msg1
.msg_iovlen
= 3;
2187 msg1
.msg_control
= NULL
;
2188 msg1
.msg_controllen
= 0;
2191 debug("sending msg1");
2193 rc
= sendmsg(src
, &msg1
, 0);
2195 test_fail("sendmsg");
2198 memset(&buf1
, '\0', BUFSIZE
);
2199 memset(&buf2
, '\0', BUFSIZE
);
2200 memset(&buf3
, '\0', BUFSIZE
);
2201 memset(&ctrl
, '\0', BUFSIZE
);
2203 iov
[0].iov_base
= buf1
;
2205 iov
[1].iov_base
= buf2
;
2206 iov
[1].iov_len
= 32;
2208 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
2209 memset(&msg2
, '\0', sizeof(struct msghdr
));
2210 msg2
.msg_name
= &addr
;
2211 msg2
.msg_namelen
= sizeof(struct sockaddr_un
);
2213 msg2
.msg_iovlen
= 2;
2214 msg2
.msg_control
= ctrl
;
2215 msg2
.msg_controllen
= BUFSIZE
;
2220 rc
= recvmsg(dst
, &msg2
, 0);
2222 test_fail("recvmsg");
2225 debug("checking results");
2227 if (strncmp(buf1
, "Minix is ", 9) || strncmp(buf2
, "great!", 6)) {
2228 test_fail("recvmsg");
2231 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
2232 * because that is what is returned by recvmsg().
2234 if (addr
.sun_family
!= AF_UNIX
|| strcmp(addr
.sun_path
,
2235 fullpath(TEST_SUN_PATHB
))) {
2236 test_fail("recvmsg");
2239 debug("looking for credentials");
2241 memset(&cred
, '\0', sizeof(struct uucred
));
2242 for (cmsg
= CMSG_FIRSTHDR(&msg2
); cmsg
!= NULL
;
2243 cmsg
= CMSG_NXTHDR(&msg2
, cmsg
)) {
2245 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
2246 cmsg
->cmsg_type
== SCM_CREDS
) {
2248 memcpy(&cred
, CMSG_DATA(cmsg
), sizeof(struct uucred
));
2253 if (cred
.cr_ngroups
!= 0 || cred
.cr_uid
!= geteuid() ||
2254 cred
.cr_gid
!= getegid()) {
2256 test_fail("did no receive the proper credentials");
2269 UNLINK(TEST_SUN_PATH
);
2270 UNLINK(TEST_SUN_PATHB
);
2273 void test_connect(void)
2275 int i
, sd
, sds
[2], rc
;
2277 /* connect() is already tested throughout test56, but
2278 * in most cases the client and server end up on /dev/uds
2279 * minor 0 and minor 1. This test opens some sockets first and
2280 * then calls test_simple_client_server(). This forces the
2281 * client and server minor numbers higher in the descriptor table.
2284 debug("starting test_connect()");
2286 sd
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
2288 test_fail("couldn't create a socket");
2291 rc
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sds
);
2293 test_fail("couldn't create a socketpair");
2296 for (i
= 0; i
< 3; i
++) {
2297 test_simple_client_server(types
[i
]);
2302 test_fail("close() failed");
2307 test_fail("close() failed");
2312 test_fail("close() failed");
2315 debug("exiting test_connect()");
2318 int test_multiproc_read(void)
2320 /* test that when we fork() a process with an open socket descriptor,
2321 * the descriptor in each process points to the same thing.
2329 debug("entering test_multiproc_read()");
2331 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sds
);
2333 test_fail("socketpair");
2337 memset(buf
, '\0', 3);
2340 /* the signal handler is only used by the client, but we have to
2341 * install it now. if we don't the server may signal the client
2342 * before the handler is installed.
2344 debug("installing signal handler");
2345 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
2346 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2350 debug("signal handler installed");
2361 } else if (pid
== 0) {
2363 while (server_ready
== 0) {
2364 debug("waiting for SIGUSR1 from parent");
2368 rc
= read(sds
[1], buf
, 2);
2374 if (!(buf
[0] == 'X' && buf
[1] == '3')) {
2375 test_fail("Didn't read X3");
2382 rc
= write(sds
[0], "MNX3", 4);
2387 rc
= read(sds
[1], buf
, 2);
2392 if (!(buf
[0] == 'M' && buf
[1] == 'N')) {
2393 test_fail("Didn't read MN");
2396 /* time to tell the client to start the test */
2400 rc
= waitpid(pid
, &status
, 0);
2401 } while (rc
== -1 && errno
== EINTR
);
2403 /* we use the exit status to get its error count */
2404 errct
+= WEXITSTATUS(status
);
2410 int test_multiproc_write(void)
2412 /* test that when we fork() a process with an open socket descriptor,
2413 * the descriptor in each process points to the same thing.
2421 debug("entering test_multiproc_write()");
2423 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sds
);
2425 test_fail("socketpair");
2429 memset(buf
, '\0', 7);
2432 /* the signal handler is only used by the client, but we have to
2433 * install it now. if we don't the server may signal the client
2434 * before the handler is installed.
2436 debug("installing signal handler");
2437 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
2438 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2442 debug("signal handler installed");
2453 } else if (pid
== 0) {
2455 while (server_ready
== 0) {
2456 debug("waiting for SIGUSR1 from parent");
2460 rc
= write(sds
[1], "IX3", 3);
2466 rc
= read(sds
[0], buf
, 6);
2472 if (strcmp(buf
, "MINIX3") != 0) {
2473 test_fail("didn't read MINIX3");
2480 rc
= write(sds
[1], "MIN", 3);
2485 /* time to tell the client to start the test */
2489 rc
= waitpid(pid
, &status
, 0);
2490 } while (rc
== -1 && errno
== EINTR
);
2492 /* we use the exit status to get its error count */
2493 errct
+= WEXITSTATUS(status
);
2499 void test_fd_passing_child(int sd
)
2503 struct msghdr msghdr
;
2504 struct cmsghdr
*cmsg
;
2508 memset(buf
, '\0', BUFSIZE
);
2510 fd
= open(TEST_TXT_FILE
, O_CREAT
|O_TRUNC
|O_RDWR
);
2512 test_fail("could not open test.txt");
2515 msghdr
.msg_name
= NULL
;
2516 msghdr
.msg_namelen
= 0;
2520 msghdr
.msg_iov
= &iov
;
2521 msghdr
.msg_iovlen
= 1;
2523 msghdr
.msg_control
= buf
;
2524 msghdr
.msg_controllen
= CMSG_SPACE(sizeof(int));
2526 msghdr
.msg_flags
= 0;
2528 cmsg
= CMSG_FIRSTHDR(&msghdr
);
2529 cmsg
->cmsg_len
= CMSG_SPACE(sizeof(int));
2530 cmsg
->cmsg_level
= SOL_SOCKET
;
2531 cmsg
->cmsg_type
= SCM_RIGHTS
;
2533 ((int *) CMSG_DATA(cmsg
))[0] = fd
;
2535 rc
= sendmsg(sd
, &msghdr
, 0);
2537 test_fail("could not send message");
2540 memset(buf
, '\0', BUFSIZE
);
2541 rc
= read(sd
, buf
, BUFSIZE
);
2543 test_fail("could not read from socket");
2546 if (strcmp(buf
, "done") != 0) {
2547 test_fail("we didn't read the right message");
2550 memset(buf
, '\0', BUFSIZE
);
2551 rc
= lseek(fd
, 0, SEEK_SET
);
2553 test_fail("could not seek to start of test.txt");
2556 rc
= read(fd
, buf
, BUFSIZE
);
2558 test_fail("could not read from test.txt");
2561 if (strcmp(buf
, MSG
) != 0) {
2562 test_fail("other process didn't write MSG to test.txt");
2567 test_fail("could not close test.txt");
2572 test_fail("could not close socket");
2575 rc
= unlink(TEST_TXT_FILE
);
2577 test_fail("could not unlink test.txt");
2583 void test_fd_passing_parent(int sd
)
2587 struct msghdr msghdr
;
2588 struct cmsghdr
*cmsg
;
2592 memset(buf
, '\0', BUFSIZE
);
2594 msghdr
.msg_name
= NULL
;
2595 msghdr
.msg_namelen
= 0;
2599 msghdr
.msg_iov
= &iov
;
2600 msghdr
.msg_iovlen
= 1;
2602 msghdr
.msg_iov
= &iov
;
2603 msghdr
.msg_iovlen
= 1;
2605 msghdr
.msg_control
= buf
;
2606 msghdr
.msg_controllen
= BUFSIZE
;
2608 msghdr
.msg_flags
= 0;
2610 rc
= recvmsg(sd
, &msghdr
, 0);
2612 test_fail("could not recv message.");
2615 cmsg
= CMSG_FIRSTHDR(&msghdr
);
2616 fd
= ((int *) CMSG_DATA(cmsg
))[0];
2618 rc
= write(fd
, MSG
, strlen(MSG
));
2619 if (rc
!= strlen(MSG
)) {
2620 test_fail("could not write the full message to test.txt");
2625 test_fail("could not close test.txt");
2628 memset(buf
, '\0', BUFSIZE
);
2629 strcpy(buf
, "done");
2630 rc
= write(sd
, buf
, BUFSIZE
);
2632 test_fail("could not write to socket");
2637 test_fail("could not close socket");
2641 void test_permissions(void) {
2642 /* Test bind and connect for permission verification
2644 * After creating a UDS socket we change user credentials. At that
2645 * point we should not be allowed to bind or connect to the UDS socket
2650 struct sockaddr_un addr
;
2652 memset(&addr
, '\0', sizeof(struct sockaddr_un
));
2653 addr
.sun_family
= AF_UNIX
;
2654 strncpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
) - 1);
2656 UNLINK(TEST_SUN_PATH
);
2659 if (pid
< 0) test_fail("unable to fork");
2660 else if (pid
== 0) {
2661 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
2662 if (setuid(999) != 0) test_fail("unable to chance uid");
2663 rc
= bind(sd
, (struct sockaddr
*) &addr
,
2664 sizeof(struct sockaddr_un
));
2666 test_fail("bind() should not have worked");
2670 rc
= waitpid(pid
, &status
, 0);
2671 errct
+= WEXITSTATUS(status
);
2674 /* the signal handler is only used by the client, but we have to
2675 * install it now. if we don't the server may signal the client
2676 * before the handler is installed.
2678 debug("installing signal handler");
2679 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
2680 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
2683 debug("signal handler installed");
2688 if (pid
< 0) test_fail("unable to fork");
2689 else if (pid
== 0) {
2690 while (server_ready
== 0) {
2691 debug("[client] waiting for the server to signal");
2694 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
2695 if (setuid(999) != 0) test_fail("unable to chance uid");
2696 rc
= connect(sd
, (struct sockaddr
*) &addr
,
2697 sizeof(struct sockaddr_un
));
2699 test_fail("connect should not have worked");
2702 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
2703 rc
= bind(sd
, (struct sockaddr
*) &addr
,
2704 sizeof(struct sockaddr_un
));
2706 test_fail("bind() should have worked");
2711 test_fail("listen(sd, 8) should have worked");
2717 rc
= waitpid(pid
, &status
, 0);
2718 errct
+= WEXITSTATUS(status
);
2721 UNLINK(TEST_SUN_PATH
);
2724 void test_fd_passing(void) {
2730 rc
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sv
);
2732 test_fail("socketpair failed");
2737 test_fail("fork() failed");
2741 test_fail("could not close sv[0]");
2746 test_fail("could not close sv[1]");
2750 } else if (pid
== 0) {
2753 test_fail("could not close sv[0]");
2756 test_fd_passing_child(sv
[1]);
2757 test_fail("should never get here");
2762 test_fail("could not close sv[1]");
2765 test_fd_passing_parent(sv
[0]);
2767 /* wait for client to exit */
2770 rc
= waitpid(pid
, &status
, 0);
2771 } while (rc
== -1 && errno
== EINTR
);
2773 /* we use the exit status to get its error count */
2774 errct
+= WEXITSTATUS(status
);
2782 fd_set readfds
, writefds
;
2791 tv
.tv_usec
= 0; /* 2 sec time out */
2793 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, socks
) < 0) {
2794 test_fail("Can't open socket pair.");
2796 FD_SET(socks
[0], &readfds
);
2797 nfds
= socks
[0] + 1;
2799 /* Close the write end of the socket to generate EOF on read end */
2800 if ((res
= shutdown(socks
[1], SHUT_WR
)) != 0) {
2801 test_fail("shutdown failed\n");
2804 res
= select(nfds
, &readfds
, NULL
, NULL
, &tv
);
2806 test_fail("select should've returned 1 ready fd\n");
2808 if (!(FD_ISSET(socks
[0], &readfds
))) {
2809 test_fail("The server didn't respond within 2 seconds");
2811 /* Now try to read from empty, closed pipe */
2812 if (read(socks
[0], buf
, sizeof(buf
)) != 0) {
2813 test_fail("reading from empty, closed pipe should return EOF");
2818 /* Try again the other way around: create a socketpair, close the
2819 * read end, and try to write. This should cause an EPIPE */
2822 tv
.tv_usec
= 0; /* 2 sec time out */
2824 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, socks
) < 0) {
2825 test_fail("Can't open socket pair.");
2827 FD_SET(socks
[1], &writefds
);
2828 nfds
= socks
[1] + 1;
2830 /* kill the read end of the socket to generate EPIPE on write end */
2831 if ((res
= shutdown(socks
[0], SHUT_RD
)) != 0) {
2832 test_fail("shutdown failed\n");
2835 res
= select(nfds
, NULL
, &writefds
, NULL
, &tv
);
2837 test_fail("select should've returned 1 ready fd\n");
2839 if (!(FD_ISSET(socks
[1], &writefds
))) {
2840 test_fail("The server didn't respond within 2 seconds");
2843 /* Now try to write to closed pipe */
2845 if ((res
= write(socks
[1], buf
, sizeof(buf
))) != -1) {
2846 printf("write res = %d\n", res
);
2847 test_fail("writing to empty, closed pipe should fail");
2849 if (errno
!= EPIPE
) {
2850 printf("errno = %d\n", errno
);
2851 test_fail("writing to closed pipe should return EPIPE\n");
2857 void test_select_close(void)
2863 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, socks
) < 0) {
2864 test_fail("Can't open socket pair.");
2873 test_fail("Can't fork.");
2881 FD_SET(socks
[0], &readfds
);
2883 tv
.tv_usec
= 0; /* 2 sec time out */
2885 res
= select(socks
[0] + 1, &readfds
, NULL
, NULL
, &tv
);
2887 test_fail("select should've returned 1 ready fd\n");
2889 if (!(FD_ISSET(socks
[0], &readfds
))) {
2890 test_fail("The server didn't respond within 2 seconds");
2901 struct stat st1
, st2
;
2903 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, socks
) < 0) {
2904 test_fail("Can't open socket pair.");
2907 if (fstat(socks
[0], &st1
) < 0 || fstat(socks
[1], &st2
) < 0) {
2908 test_fail("fstat failed.");
2911 if ((st1
.st_mode
& (S_IRUSR
|S_IWUSR
)) == S_IRUSR
&&
2912 (st2
.st_mode
& (S_IRUSR
|S_IWUSR
)) == S_IWUSR
) {
2913 test_fail("fstat failed.");
2916 if (fchmod(socks
[0], S_IRUSR
) < 0 ||
2917 fstat(socks
[0], &st1
) < 0 ||
2918 (st1
.st_mode
& (S_IRUSR
|S_IWUSR
)) != S_IRUSR
) {
2919 test_fail("fchmod/fstat mode set/check failed (1).");
2922 if (fchmod(socks
[1], S_IWUSR
) < 0 || fstat(socks
[1], &st2
) < 0 ||
2923 (st2
.st_mode
& (S_IRUSR
|S_IWUSR
)) != S_IWUSR
) {
2924 test_fail("fchmod/fstat mode set/check failed (2).");
2932 check_select(int sd
, int rd
, int wr
, int block
)
2934 fd_set read_set
, write_set
;
2939 FD_SET(sd
, &read_set
);
2941 FD_ZERO(&write_set
);
2943 FD_SET(sd
, &write_set
);
2945 tv
.tv_sec
= block
? 2 : 0;
2948 if (select(sd
+ 1, &read_set
, &write_set
, NULL
, &tv
) < 0)
2949 test_fail("select() failed unexpectedly");
2951 if (rd
!= -1 && !!FD_ISSET(sd
, &read_set
) != rd
)
2952 test_fail("select() mismatch on read operation");
2954 if (wr
!= -1 && !!FD_ISSET(sd
, &write_set
) != wr
)
2955 test_fail("select() mismatch on write operation");
2960 * - a nonblocking connecting socket for which there is no accepter, will
2961 * return EINPROGRESS and complete in the background later;
2962 * - a nonblocking listening socket will return EAGAIN on accept;
2963 * - connecting a connecting socket yields EALREADY;
2964 * - connecting a connected socket yields EISCONN;
2965 * - selecting for read and write on a connecting socket will only satisfy the
2966 * write only once it is connected;
2967 * - doing a nonblocking write on a connecting socket yields EAGAIN;
2968 * - doing a nonblocking read on a connected socket with no pending data yields
2976 int server_sd
, client_sd
;
2977 struct sockaddr_un server_addr
, client_addr
, addr
;
2980 memset(buf
, 0, sizeof(buf
));
2982 memset(&server_addr
, 0, sizeof(server_addr
));
2983 strlcpy(server_addr
.sun_path
, TEST_SUN_PATH
,
2984 sizeof(server_addr
.sun_path
));
2985 server_addr
.sun_family
= AF_UNIX
;
2987 client_addr
= server_addr
;
2989 SOCKET(server_sd
, PF_UNIX
, SOCK_STREAM
, 0);
2991 if (bind(server_sd
, (struct sockaddr
*) &server_addr
,
2992 sizeof(struct sockaddr_un
)) == -1)
2993 test_fail("bind() should have worked");
2995 if (listen(server_sd
, 8) == -1)
2996 test_fail("listen() should have worked");
2998 fcntl(server_sd
, F_SETFL
, fcntl(server_sd
, F_GETFL
) | O_NONBLOCK
);
3000 check_select(server_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3003 if (accept(server_sd
, (struct sockaddr
*) &addr
, &len
) != -1 ||
3005 test_fail("accept() should have yielded EAGAIN");
3007 SOCKET(client_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3009 fcntl(client_sd
, F_SETFL
, fcntl(client_sd
, F_GETFL
) | O_NONBLOCK
);
3011 if (connect(client_sd
, (struct sockaddr
*) &client_addr
,
3012 sizeof(struct sockaddr_un
)) != -1 || errno
!= EINPROGRESS
)
3013 test_fail("connect() should have yielded EINPROGRESS");
3015 check_select(client_sd
, 0 /*read*/, 0 /*write*/, 0 /*block*/);
3017 if (connect(client_sd
, (struct sockaddr
*) &client_addr
,
3018 sizeof(struct sockaddr_un
)) != -1 || errno
!= EALREADY
)
3019 test_fail("connect() should have yielded EALREADY");
3021 if (recv(client_sd
, buf
, sizeof(buf
), 0) != -1 || errno
!= EAGAIN
)
3022 test_fail("recv() should have yielded EAGAIN");
3024 /* This may be an implementation aspect, or even plain wrong (?). */
3025 if (send(client_sd
, buf
, sizeof(buf
), 0) != -1 || errno
!= EAGAIN
)
3026 test_fail("send() should have yielded EAGAIN");
3032 check_select(server_sd
, 1 /*read*/, 1 /*write*/, 0 /*block*/);
3035 client_sd
= accept(server_sd
, (struct sockaddr
*) &addr
, &len
);
3036 if (client_sd
== -1)
3037 test_fail("accept() should have succeeded");
3039 check_select(server_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3043 /* Let the socket become writable in the parent process. */
3046 if (write(client_sd
, buf
, 1) != 1)
3047 test_fail("write() should have succeeded");
3049 /* Wait for the client side to close. */
3050 check_select(client_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3051 check_select(client_sd
, 1 /*read*/, -1 /*write*/, 1 /*block*/);
3052 check_select(client_sd
, 1 /*read*/, 1 /*write*/, 0 /*block*/);
3056 test_fail("can't fork");
3063 check_select(client_sd
, 0 /*read*/, 1 /*write*/, 1 /*block*/);
3064 check_select(client_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3066 if (connect(client_sd
, (struct sockaddr
*) &client_addr
,
3067 sizeof(struct sockaddr_un
)) != -1 || errno
!= EISCONN
)
3068 test_fail("connect() should have yielded EISCONN");
3070 check_select(client_sd
, 1 /*read*/, -1 /*write*/, 1 /*block*/);
3071 check_select(client_sd
, 1 /*read*/, 1 /*write*/, 0 /*block*/);
3073 if (read(client_sd
, buf
, 1) != 1)
3074 test_fail("read() should have succeeded");
3076 check_select(client_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3078 if (read(client_sd
, buf
, 1) != -1 || errno
!= EAGAIN
)
3079 test_fail("read() should have yielded EAGAIN");
3081 /* Let the child process block on the select waiting for the close. */
3086 if (wait(&status
) <= 0)
3087 test_fail("wait() should have succeeded");
3088 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0)
3089 test_fail("child process failed the test");
3091 UNLINK(TEST_SUN_PATH
);
3095 * Verify that a nonblocking connect for which there is an accepter, succeeds
3096 * immediately. A pretty lame test, only here for completeness.
3099 test_connect_nb(void)
3102 int server_sd
, client_sd
;
3103 struct sockaddr_un server_addr
, client_addr
, addr
;
3106 memset(&server_addr
, 0, sizeof(server_addr
));
3107 strlcpy(server_addr
.sun_path
, TEST_SUN_PATH
,
3108 sizeof(server_addr
.sun_path
));
3109 server_addr
.sun_family
= AF_UNIX
;
3111 client_addr
= server_addr
;
3113 SOCKET(server_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3115 if (bind(server_sd
, (struct sockaddr
*) &server_addr
,
3116 sizeof(struct sockaddr_un
)) == -1)
3117 test_fail("bind() should have worked");
3119 if (listen(server_sd
, 8) == -1)
3120 test_fail("listen() should have worked");
3125 if (accept(server_sd
, (struct sockaddr
*) &addr
, &len
) == -1)
3126 test_fail("accept() should have succeeded");
3130 test_fail("can't fork");
3139 SOCKET(client_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3141 fcntl(client_sd
, F_SETFL
, fcntl(client_sd
, F_GETFL
) | O_NONBLOCK
);
3143 if (connect(client_sd
, (struct sockaddr
*) &client_addr
,
3144 sizeof(struct sockaddr_un
)) != 0)
3145 test_fail("connect() should have succeeded");
3149 if (wait(&status
) <= 0)
3150 test_fail("wait() should have succeeded");
3151 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0)
3152 test_fail("child process failed the test");
3154 UNLINK(TEST_SUN_PATH
);
3158 dummy_handler(int sig
)
3165 * - interrupting a blocking connect will return EINTR but complete in the
3167 * - doing a blocking write on an asynchronously connecting socket succeeds
3168 * once the socket is connected.
3169 * - doing a nonblocking write on a connected socket with lots of pending data
3175 struct sigaction act
, oact
;
3178 int server_sd
, client_sd
;
3179 struct sockaddr_un server_addr
, client_addr
, addr
;
3182 memset(buf
, 0, sizeof(buf
));
3184 memset(&server_addr
, 0, sizeof(server_addr
));
3185 strlcpy(server_addr
.sun_path
, TEST_SUN_PATH
,
3186 sizeof(server_addr
.sun_path
));
3187 server_addr
.sun_family
= AF_UNIX
;
3189 client_addr
= server_addr
;
3191 SOCKET(server_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3193 if (bind(server_sd
, (struct sockaddr
*) &server_addr
,
3194 sizeof(struct sockaddr_un
)) == -1)
3195 test_fail("bind() should have worked");
3197 if (listen(server_sd
, 8) == -1)
3198 test_fail("listen() should have worked");
3200 SOCKET(client_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3202 memset(&act
, 0, sizeof(act
));
3203 act
.sa_handler
= dummy_handler
;
3204 if (sigaction(SIGALRM
, &act
, &oact
) == -1)
3205 test_fail("sigaction() should have succeeded");
3209 if (connect(client_sd
, (struct sockaddr
*) &client_addr
,
3210 sizeof(struct sockaddr_un
)) != -1 || errno
!= EINTR
)
3211 test_fail("connect() should have yielded EINTR");
3213 check_select(client_sd
, 0 /*read*/, 0 /*write*/, 0 /*block*/);
3219 check_select(server_sd
, 1 /*read*/, 1 /*write*/, 0 /*block*/);
3222 client_sd
= accept(server_sd
, (struct sockaddr
*) &addr
, &len
);
3223 if (client_sd
== -1)
3224 test_fail("accept() should have succeeded");
3226 check_select(server_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3230 check_select(client_sd
, 1 /*read*/, -1 /*write*/, 1 /*block*/);
3231 check_select(client_sd
, 1 /*read*/, 1 /*write*/, 0 /*block*/);
3233 if (recv(client_sd
, buf
, sizeof(buf
), 0) != sizeof(buf
))
3234 test_fail("recv() should have yielded bytes");
3236 /* No partial transfers should be happening. */
3237 check_select(client_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3239 fcntl(client_sd
, F_SETFL
, fcntl(client_sd
, F_GETFL
) |
3242 /* We can only test nonblocking writes by filling the pipe. */
3243 while ((r
= write(client_sd
, buf
, sizeof(buf
))) > 0);
3245 if (r
!= -1 || errno
!= EAGAIN
)
3246 test_fail("write() should have yielded EAGAIN");
3248 check_select(client_sd
, 0 /*read*/, 0 /*write*/, 0 /*block*/);
3250 if (write(client_sd
, buf
, 1) != -1 || errno
!= EAGAIN
)
3251 test_fail("write() should have yielded EAGAIN");
3255 test_fail("can't fork");
3262 if (send(client_sd
, buf
, sizeof(buf
), 0) != sizeof(buf
))
3263 test_fail("send() should have succeded");
3265 check_select(client_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3267 if (wait(&status
) <= 0)
3268 test_fail("wait() should have succeeded");
3269 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0)
3270 test_fail("child process failed the test");
3272 check_select(client_sd
, 1 /*read*/, 1 /*write*/, 0 /*block*/);
3276 sigaction(SIGALRM
, &oact
, NULL
);
3278 UNLINK(TEST_SUN_PATH
);
3282 * Verify that closing a connecting socket before it is accepted will result in
3283 * no activity on the accepting side later.
3286 test_connect_close(void)
3288 int server_sd
, client_sd
;
3289 struct sockaddr_un server_addr
, client_addr
;
3292 memset(&server_addr
, 0, sizeof(server_addr
));
3293 strlcpy(server_addr
.sun_path
, TEST_SUN_PATH
,
3294 sizeof(server_addr
.sun_path
));
3295 server_addr
.sun_family
= AF_UNIX
;
3297 client_addr
= server_addr
;
3299 SOCKET(server_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3301 if (bind(server_sd
, (struct sockaddr
*) &server_addr
,
3302 sizeof(struct sockaddr_un
)) == -1)
3303 test_fail("bind() should have worked");
3305 if (listen(server_sd
, 8) == -1)
3306 test_fail("listen() should have worked");
3308 fcntl(server_sd
, F_SETFL
, fcntl(server_sd
, F_GETFL
) | O_NONBLOCK
);
3310 check_select(server_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3312 SOCKET(client_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3314 fcntl(client_sd
, F_SETFL
, fcntl(client_sd
, F_GETFL
) | O_NONBLOCK
);
3316 if (connect(client_sd
, (struct sockaddr
*) &client_addr
,
3317 sizeof(struct sockaddr_un
)) != -1 || errno
!= EINPROGRESS
)
3318 test_fail("connect() should have yielded EINPROGRESS");
3320 check_select(client_sd
, 0 /*read*/, 0 /*write*/, 0 /*block*/);
3321 check_select(server_sd
, 1 /*read*/, 1 /*write*/, 0 /*block*/);
3325 check_select(server_sd
, 0 /*read*/, 1 /*write*/, 0 /*block*/);
3327 len
= sizeof(client_addr
);
3328 if (accept(server_sd
, (struct sockaddr
*) &client_addr
, &len
) != -1 ||
3330 test_fail("accept() should have yielded EAGAIN");
3334 UNLINK(TEST_SUN_PATH
);
3338 * Verify that closing a listening socket will cause a blocking connect to fail
3339 * with ECONNRESET, and that a subsequent write will yield EPIPE.
3342 test_listen_close(void)
3345 int server_sd
, client_sd
;
3346 struct sockaddr_un server_addr
, client_addr
, addr
;
3350 memset(&server_addr
, 0, sizeof(server_addr
));
3351 strlcpy(server_addr
.sun_path
, TEST_SUN_PATH
,
3352 sizeof(server_addr
.sun_path
));
3353 server_addr
.sun_family
= AF_UNIX
;
3355 client_addr
= server_addr
;
3357 SOCKET(server_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3359 if (bind(server_sd
, (struct sockaddr
*) &server_addr
,
3360 sizeof(struct sockaddr_un
)) == -1)
3361 test_fail("bind() should have worked");
3363 if (listen(server_sd
, 8) == -1)
3364 test_fail("listen() should have worked");
3372 test_fail("can't fork");
3379 SOCKET(client_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3382 if (write(client_sd
, &byte
, 1) != -1 || errno
!= ENOTCONN
)
3383 /* Yes, you fucked up the fix for the FIXME below. */
3384 test_fail("write() should have yielded ENOTCONN");
3386 if (connect(client_sd
, (struct sockaddr
*) &client_addr
,
3387 sizeof(struct sockaddr_un
)) != -1 || errno
!= ECONNRESET
)
3388 test_fail("connect() should have yielded ECONNRESET");
3391 * FIXME: currently UDS cannot distinguish between sockets that have
3392 * not yet been connected, and sockets that have been disconnected.
3393 * Thus, we get the same error for both: ENOTCONN instead of EPIPE.
3396 if (write(client_sd
, &byte
, 1) != -1 || errno
!= EPIPE
)
3397 test_fail("write() should have yielded EPIPE");
3402 if (wait(&status
) <= 0)
3403 test_fail("wait() should have succeeded");
3404 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0)
3405 test_fail("child process failed the test");
3407 UNLINK(TEST_SUN_PATH
);
3411 * Verify that closing a listening socket will cause a nonblocking connect to
3412 * result in the socket becoming readable and writable, and yielding ECONNRESET
3413 * and EPIPE on the next two writes, respectively.
3416 test_listen_close_nb(void)
3419 int server_sd
, client_sd
;
3420 struct sockaddr_un server_addr
, client_addr
, addr
;
3424 memset(&server_addr
, 0, sizeof(server_addr
));
3425 strlcpy(server_addr
.sun_path
, TEST_SUN_PATH
,
3426 sizeof(server_addr
.sun_path
));
3427 server_addr
.sun_family
= AF_UNIX
;
3429 client_addr
= server_addr
;
3431 SOCKET(server_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3433 if (bind(server_sd
, (struct sockaddr
*) &server_addr
,
3434 sizeof(struct sockaddr_un
)) == -1)
3435 test_fail("bind() should have worked");
3437 if (listen(server_sd
, 8) == -1)
3438 test_fail("listen() should have worked");
3446 test_fail("can't fork");
3453 SOCKET(client_sd
, PF_UNIX
, SOCK_STREAM
, 0);
3455 fcntl(client_sd
, F_SETFL
, fcntl(client_sd
, F_GETFL
) | O_NONBLOCK
);
3457 if (connect(client_sd
, (struct sockaddr
*) &client_addr
,
3458 sizeof(struct sockaddr_un
)) != -1 || errno
!= EINPROGRESS
)
3459 test_fail("connect() should have yielded EINPROGRESS");
3461 check_select(client_sd
, 0 /*read*/, 0 /*write*/, 0 /*block*/);
3462 check_select(client_sd
, 1 /*read*/, 1 /*write*/, 1 /*block*/);
3465 if (write(client_sd
, &byte
, 1) != -1 || errno
!= ECONNRESET
)
3466 test_fail("write() should have yielded ECONNRESET");
3469 * FIXME: currently UDS cannot distinguish between sockets that have
3470 * not yet been connected, and sockets that have been disconnected.
3471 * Thus, we get the same error for both: ENOTCONN instead of EPIPE.
3474 if (write(client_sd
, &byte
, 1) != -1 || errno
!= EPIPE
)
3475 test_fail("write() should have yielded EPIPE");
3478 check_select(client_sd
, 1 /*read*/, 1 /*write*/, 0 /*block*/);
3482 if (wait(&status
) <= 0)
3483 test_fail("wait() should have succeeded");
3484 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0)
3485 test_fail("child process failed the test");
3487 UNLINK(TEST_SUN_PATH
);
3490 int main(int argc
, char *argv
[])
3494 debug("entering main()");
3516 for (i
= 0; i
< 3; i
++) {
3517 test_simple_client_server(types
[i
]);
3518 if (types
[i
] != SOCK_DGRAM
) test_vectorio(types
[i
]);
3519 if (types
[i
] != SOCK_DGRAM
) test_msg(types
[i
]);
3521 test_abort_client_server(1);
3522 test_abort_client_server(2);
3525 test_multiproc_read();
3526 test_multiproc_write();
3527 test_scm_credentials();
3530 test_select_close();
3535 test_connect_close();
3536 test_listen_close();
3537 test_listen_close_nb();
3541 return -1; /* we should never get here */