PageRenderTime 63ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/test/test56.c

http://www.minix3.org/
C | 2647 lines | 1954 code | 554 blank | 139 comment | 615 complexity | 54b697e43c5bc00740a11ef9fd7d5255 MD5 | raw file
Possible License(s): MIT, WTFPL, AGPL-1.0, BSD-3-Clause, GPL-3.0, LGPL-2.0, JSON, 0BSD

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Test Program for Unix Domain Sockets
  3. *
  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.
  25. *
  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().
  30. *
  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()
  36. */
  37. #define DEBUG 0
  38. #include <ctype.h>
  39. #include <errno.h>
  40. #include <fcntl.h>
  41. #include <signal.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <sys/socket.h>
  46. #include <sys/stat.h>
  47. #include <sys/time.h>
  48. #include <sys/types.h>
  49. #include <sys/uio.h>
  50. #include <sys/un.h>
  51. #include <sys/wait.h>
  52. #include <time.h>
  53. #include <unistd.h>
  54. /* Maximum number of errors that we'll allow to occur before this test
  55. * program gives us and quits.
  56. */
  57. #define MAX_ERROR 4
  58. /* Use the common testing code instead of reinventing the wheel. */
  59. #include "common.c"
  60. /* path of the unix domain socket */
  61. #define TEST_SUN_PATH "test.sock"
  62. #define TEST_SUN_PATHB "testb.sock"
  63. /* filenames for symlinks -- we link these to each other to test ELOOP .*/
  64. #define TEST_SYM_A "test.a"
  65. #define TEST_SYM_B "test.b"
  66. /* text file and test phrase for testing file descriptor passing */
  67. #define TEST_TXT_FILE "test.txt"
  68. #define MSG "This raccoon loves to eat bugs.\n"
  69. /* buffer for send/recv */
  70. #define BUFSIZE (128)
  71. #define ISO8601_FORMAT "%Y-%m-%dT%H:%M:%S"
  72. /* socket types supported */
  73. int types[3] = {SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM};
  74. char sock_fullpath[PATH_MAX + 1];
  75. /* timestamps for debug and error logs */
  76. char *get_timestamp(void)
  77. {
  78. struct tm *tm;
  79. time_t t;
  80. size_t len;
  81. char *s;
  82. len = sizeof(char) * 32;
  83. t = time(NULL);
  84. if (t == -1) {
  85. return NULL;
  86. }
  87. tm = gmtime(&t);
  88. if (tm == NULL) {
  89. return NULL;
  90. }
  91. s = (char *) malloc(len);
  92. if (!s) {
  93. perror("malloc");
  94. return NULL;
  95. }
  96. memset(s, '\0', len);
  97. strftime(s, len - 1, ISO8601_FORMAT, tm);
  98. return s;
  99. }
  100. /* macro to display information about a failed test and increment the errct */
  101. #define test_fail(msg) \
  102. do { \
  103. char *timestamp; \
  104. timestamp = get_timestamp(); \
  105. if (errct == 0) fprintf(stderr, "\n"); \
  106. fprintf(stderr, "[ERROR][%s] (%s Line %d) %s [pid=%d:errno=%d:%s]\n", \
  107. timestamp, __FILE__, __LINE__, msg, getpid(), \
  108. errno, strerror(errno)); \
  109. fflush(stderr); \
  110. if (timestamp != NULL) { \
  111. free(timestamp); \
  112. timestamp = NULL; \
  113. } \
  114. errct++; \
  115. if (errct++ > MAX_ERROR) { \
  116. printf("Too many errors; test aborted\n"); \
  117. quit(); \
  118. exit(1); \
  119. } \
  120. } while (0)
  121. /* Convert name to the full path of the socket. Assumes name is in cwd. */
  122. char *fullpath(char *name)
  123. {
  124. char cwd[PATH_MAX + 1];
  125. if (realpath(".", cwd) == NULL)
  126. test_fail("Couldn't retrieve current working dir");
  127. snprintf(sock_fullpath, PATH_MAX, "%s/%s", cwd, name);
  128. return(sock_fullpath);
  129. }
  130. #if DEBUG == 1
  131. /* macros to display debugging information */
  132. #define debug(msg) \
  133. do { \
  134. char *timestamp; \
  135. timestamp = get_timestamp(); \
  136. fprintf(stdout,"[DEBUG][%s] (%s:%d) %s [pid=%d]\n", \
  137. timestamp, __FILE__, __LINE__, msg, getpid()); \
  138. fflush(stdout); \
  139. if (timestamp != NULL) { \
  140. free(timestamp); \
  141. timestamp = NULL; \
  142. } \
  143. } while (0)
  144. #else
  145. #define debug(msg) \
  146. do { /* nothing */; } while (0)
  147. #endif
  148. #define SOCKET(sd,domain,type,protocol) \
  149. do { \
  150. errno = 0; \
  151. sd = socket(domain, type, protocol); \
  152. if (sd == -1) { \
  153. test_fail("sd = socket(domain, type, protocol) failed");\
  154. } \
  155. } while (0)
  156. #define UNLINK(path) \
  157. do { \
  158. int rc; \
  159. errno = 0; \
  160. rc = unlink(path); \
  161. if (rc == -1 && errno != ENOENT) { \
  162. test_fail("unlink(path) failed"); \
  163. } \
  164. } while(0)
  165. #define SYMLINK(oldpath,newpath) \
  166. do { \
  167. int rc; \
  168. errno = 0; \
  169. rc = symlink(oldpath,newpath); \
  170. if (rc == -1) { \
  171. test_fail("symlink(oldpath,newpath) failed"); \
  172. } \
  173. } while(0)
  174. #define CLOSE(sd) \
  175. do { \
  176. int rc; \
  177. errno = 0; \
  178. rc = close(sd); \
  179. if (rc == -1) { \
  180. test_fail("close(sd) failed"); \
  181. } \
  182. } while (0)
  183. void test_socket(void)
  184. {
  185. struct stat statbuf, statbuf2;
  186. int sd, sd2;
  187. int rc;
  188. int i;
  189. debug("entering test_socket()");
  190. debug("Test socket() with an unsupported address family");
  191. errno = 0;
  192. sd = socket(-1, SOCK_STREAM, 0);
  193. if (!(sd == -1 && errno == EAFNOSUPPORT)) {
  194. test_fail("socket");
  195. if (sd != -1) {
  196. CLOSE(sd);
  197. }
  198. }
  199. debug("Test socket() with all available FDs open by this process");
  200. for (i = 3; i < getdtablesize(); i++) {
  201. rc = open("/dev/null", O_RDONLY);
  202. if (rc == -1) {
  203. test_fail("we couldn't open /dev/null for read");
  204. }
  205. }
  206. errno = 0;
  207. sd = socket(PF_UNIX, SOCK_STREAM, 0);
  208. if (!(sd == -1 && errno == EMFILE)) {
  209. test_fail("socket() call with all fds open should fail");
  210. if (sd != -1) {
  211. CLOSE(sd);
  212. }
  213. }
  214. for (i = 3; i < getdtablesize(); i++) {
  215. CLOSE(i);
  216. }
  217. debug("Test socket() with an mismatched protocol");
  218. errno = 0;
  219. sd = socket(PF_UNIX, SOCK_STREAM, 4);
  220. if (!(sd == -1 && errno == EPROTONOSUPPORT)) {
  221. test_fail("socket() should fail with errno = EPROTONOSUPPORT");
  222. if (sd != -1) {
  223. CLOSE(sd);
  224. }
  225. }
  226. debug("Test socket() success");
  227. /*
  228. * open 2 sockets at once and *then* close them.
  229. * This will test that /dev/uds is cloning properly.
  230. */
  231. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  232. SOCKET(sd2, PF_UNIX, SOCK_STREAM, 0);
  233. rc = fstat(sd, &statbuf);
  234. if (rc == -1) {
  235. test_fail("fstat failed on sd");
  236. }
  237. rc = fstat(sd2, &statbuf2);
  238. if (rc == -1) {
  239. test_fail("fstat failed on sd2");
  240. }
  241. if (statbuf.st_dev == statbuf2.st_dev) {
  242. test_fail("/dev/uds isn't being cloned");
  243. }
  244. CLOSE(sd2);
  245. CLOSE(sd);
  246. debug("leaving test_socket()");
  247. }
  248. void test_header(void)
  249. {
  250. struct sockaddr_un sun;
  251. debug("entering test_header()");
  252. sun.sun_family = AF_UNIX;
  253. sun.sun_path[0] = 'x';
  254. sun.sun_path[1] = 'x';
  255. sun.sun_path[2] = 'x';
  256. sun.sun_path[3] = '\0';
  257. if (SUN_LEN(&sun) != 4) {
  258. test_fail("SUN_LEN(&sun) should be 4");
  259. }
  260. if (PF_UNIX != PF_LOCAL || PF_UNIX != PF_FILE || PF_UNIX != AF_UNIX) {
  261. test_fail("PF_UNIX, PF_LOCAL, PF_FILE, and AF_UNIX");
  262. }
  263. }
  264. void test_socketpair(void)
  265. {
  266. char buf[128];
  267. struct sockaddr_un addr;
  268. int socket_vector[2];
  269. int rc;
  270. int i;
  271. debug("entering test_socketpair()");
  272. UNLINK(TEST_SUN_PATH);
  273. memset(&addr, '\0', sizeof(struct sockaddr_un));
  274. addr.sun_family = AF_UNIX;
  275. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  276. debug("Testing socketpair() success");
  277. rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector);
  278. if (rc == -1) {
  279. test_fail("socketpair() should have worked");
  280. }
  281. debug("Testing a simple read/write using sockets from socketpair()");
  282. memset(buf, '\0', sizeof(buf));
  283. strncpy(buf, "Howdy Partner", sizeof(buf) - 1);
  284. rc = write(socket_vector[0], buf, sizeof(buf));
  285. if (rc == -1) {
  286. test_fail("write(sd, buf, sizeof(buf)) failed unexpectedly");
  287. }
  288. memset(buf, '\0', sizeof(buf));
  289. rc = read(socket_vector[1], buf, sizeof(buf));
  290. if (rc == -1) {
  291. test_fail("read() failed unexpectedly");
  292. }
  293. if (strncmp(buf, "Howdy Partner", strlen("Howdy Partner")) != 0) {
  294. test_fail("We did not read what we wrote");
  295. }
  296. CLOSE(socket_vector[0]);
  297. CLOSE(socket_vector[1]);
  298. debug("Test socketpair() with all FDs open by this process");
  299. for (i = 3; i < getdtablesize(); i++) {
  300. rc = open("/dev/null", O_RDONLY);
  301. if (rc == -1) {
  302. test_fail("we couldn't open /dev/null for read");
  303. }
  304. }
  305. rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector);
  306. if (!(rc == -1 && errno == EMFILE)) {
  307. test_fail("socketpair() should have failed with EMFILE");
  308. }
  309. for (i = 3; i < getdtablesize(); i++) {
  310. CLOSE(i);
  311. }
  312. rc = socketpair(PF_UNIX, SOCK_STREAM, 4, socket_vector);
  313. if (!(rc == -1 && errno == EPROTONOSUPPORT)) {
  314. test_fail("socketpair() should have failed");
  315. }
  316. debug("leaving test_socketpair()");
  317. }
  318. void test_ucred(void)
  319. {
  320. struct ucred credentials;
  321. socklen_t ucred_length;
  322. uid_t euid = geteuid();
  323. gid_t egid = getegid();
  324. int sv[2];
  325. int rc;
  326. debug("Test credentials passing");
  327. ucred_length = sizeof(struct ucred);
  328. rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
  329. if (rc == -1) {
  330. test_fail("socketpair(PF_UNIX, SOCK_STREAM, 0, sv) failed");
  331. }
  332. memset(&credentials, '\0', ucred_length);
  333. rc = getsockopt(sv[0], SOL_SOCKET, SO_PEERCRED, &credentials,
  334. &ucred_length);
  335. if (rc == -1) {
  336. test_fail("getsockopt(SO_PEERCRED) failed");
  337. } else if (credentials.pid != getpid() ||
  338. credentials.uid != geteuid() ||
  339. credentials.gid != getegid()) {
  340. /* printf("%d=%d %d=%d %d=%d",credentials.pid, getpid(),
  341. credentials.uid, geteuid(), credentials.gid, getegid()); */
  342. test_fail("Credential passing gave us the wrong cred");
  343. }
  344. rc = getpeereid(sv[0], &euid, &egid);
  345. if (rc == -1) {
  346. test_fail("getpeereid(sv[0], &euid, &egid) failed");
  347. } else if (credentials.uid != euid || credentials.gid != egid) {
  348. test_fail("getpeereid() didn't give the correct euid/egid");
  349. }
  350. CLOSE(sv[0]);
  351. CLOSE(sv[1]);
  352. }
  353. void test_getsockname(void)
  354. {
  355. int sd;
  356. int rc;
  357. struct sockaddr_un addr, sock_addr;
  358. socklen_t sock_addr_len;
  359. memset(&addr, '\0', sizeof(struct sockaddr_un));
  360. addr.sun_family = AF_UNIX;
  361. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  362. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  363. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  364. if (rc == -1) {
  365. test_fail("bind() should have worked");
  366. }
  367. debug("Test getsockname() success");
  368. memset(&sock_addr, '\0', sizeof(struct sockaddr_un));
  369. sock_addr_len = sizeof(struct sockaddr_un);
  370. rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len);
  371. if (rc == -1) {
  372. test_fail("getsockname() should have worked");
  373. }
  374. if (!(sock_addr.sun_family == AF_UNIX && strncmp(sock_addr.sun_path,
  375. fullpath(TEST_SUN_PATH),
  376. sizeof(sock_addr.sun_path) - 1) == 0)) {
  377. test_fail("getsockname() did return the right address");
  378. fprintf(stderr, "exp: '%s' | got: '%s'\n", addr.sun_path,
  379. sock_addr.sun_path);
  380. }
  381. CLOSE(sd);
  382. }
  383. void test_bind(void)
  384. {
  385. struct sockaddr_un addr;
  386. struct sockaddr_un sock_addr;
  387. socklen_t sock_addr_len;
  388. int sd;
  389. int sd2;
  390. int rc;
  391. debug("entering test_bind()");
  392. UNLINK(TEST_SUN_PATH);
  393. memset(&addr, '\0', sizeof(struct sockaddr_un));
  394. addr.sun_family = AF_UNIX;
  395. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  396. debug("Test bind() success");
  397. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  398. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  399. if (rc == -1) {
  400. test_fail("bind() should have worked");
  401. }
  402. debug("Test getsockname() success");
  403. memset(&sock_addr, '\0', sizeof(struct sockaddr_un));
  404. sock_addr_len = sizeof(struct sockaddr_un);
  405. rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len);
  406. if (rc == -1) {
  407. test_fail("getsockname() should have worked");
  408. }
  409. if (!(sock_addr.sun_family == AF_UNIX &&
  410. strncmp(sock_addr.sun_path,
  411. fullpath(TEST_SUN_PATH),
  412. sizeof(sock_addr.sun_path) - 1) == 0)) {
  413. test_fail("getsockname() didn't return the right addr");
  414. fprintf(stderr, "exp: '%s' | got: '%s'\n", addr.sun_path,
  415. sock_addr.sun_path);
  416. }
  417. debug("Test bind() with a address that has already been bind()'d");
  418. SOCKET(sd2, PF_UNIX, SOCK_STREAM, 0);
  419. errno = 0;
  420. rc = bind(sd2, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  421. if (!((rc == -1) && (errno == EADDRINUSE))) {
  422. test_fail("bind() should have failed with EADDRINUSE");
  423. }
  424. CLOSE(sd2);
  425. CLOSE(sd);
  426. UNLINK(TEST_SUN_PATH);
  427. debug("Test bind() with an empty sun_path");
  428. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  429. memset(addr.sun_path, '\0', sizeof(addr.sun_path));
  430. errno = 0;
  431. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  432. if (!(rc == -1 && errno == ENOENT)) {
  433. test_fail("bind() should have failed with ENOENT");
  434. }
  435. CLOSE(sd);
  436. debug("Test bind() with a NULL address");
  437. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  438. errno = 0;
  439. rc = bind(sd, (struct sockaddr *) NULL, sizeof(struct sockaddr_un));
  440. if (!((rc == -1) && (errno == EFAULT))) {
  441. test_fail("bind() should have failed with EFAULT");
  442. }
  443. CLOSE(sd);
  444. debug("Test bind() using a symlink loop");
  445. UNLINK(TEST_SUN_PATH);
  446. UNLINK(TEST_SYM_A);
  447. UNLINK(TEST_SYM_B);
  448. SYMLINK(TEST_SYM_A, TEST_SYM_B);
  449. SYMLINK(TEST_SYM_B, TEST_SYM_A);
  450. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  451. strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1);
  452. errno = 0;
  453. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  454. if (!((rc == -1) && (errno == ELOOP))) {
  455. test_fail("bind() should have failed with ELOOP");
  456. }
  457. CLOSE(sd);
  458. UNLINK(TEST_SUN_PATH);
  459. UNLINK(TEST_SYM_A);
  460. UNLINK(TEST_SYM_B);
  461. debug("leaving test_bind()");
  462. }
  463. void test_listen(void)
  464. {
  465. int rc;
  466. debug("entering test_listen()");
  467. debug("Test listen() with a bad file descriptor");
  468. errno = 0;
  469. rc = listen(-1, 0);
  470. if (!(rc == -1 && errno == EBADF)) {
  471. test_fail("listen(-1, 0) should have failed");
  472. }
  473. debug("Test listen() with a non-socket file descriptor");
  474. errno = 0;
  475. rc = listen(0, 0);
  476. if (!(rc == -1 && errno == ENOTTY)) {
  477. test_fail("listen(0, 0) should have failed");
  478. }
  479. debug("leaving test_listen()");
  480. }
  481. void test_shutdown(void)
  482. {
  483. int how[3] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
  484. int sd;
  485. int rc;
  486. int i;
  487. debug("entering test_shutdown()");
  488. /* test for each direction (read, write, read-write) */
  489. for (i = 0; i < 3; i++) {
  490. debug("test shutdown() with an invalid descriptor");
  491. errno = 0;
  492. rc = shutdown(-1, how[i]);
  493. if (!(rc == -1 && errno == EBADF)) {
  494. test_fail("shutdown(-1, how[i]) should have failed");
  495. }
  496. debug("test shutdown() with a non-socket descriptor");
  497. errno = 0;
  498. rc = shutdown(0, how[i]);
  499. if (!(rc == -1 && errno == ENOSYS)) {
  500. test_fail("shutdown() should have failed with ENOSYS");
  501. }
  502. debug("test shutdown() with a socket that is not connected");
  503. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  504. errno = 0;
  505. rc = shutdown(sd, how[i]);
  506. if (!(rc == -1 && errno == ENOTCONN)) {
  507. test_fail("shutdown() should have failed");
  508. }
  509. CLOSE(sd);
  510. }
  511. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  512. errno = 0;
  513. rc = shutdown(sd, -1);
  514. if (!(rc == -1 && errno == ENOTCONN)) {
  515. test_fail("shutdown(sd, -1) should have failed with ENOTCONN");
  516. }
  517. CLOSE(sd);
  518. debug("leaving test_shutdown()");
  519. }
  520. void test_close(void)
  521. {
  522. struct sockaddr_un addr;
  523. int sd, sd2;
  524. int rc, i;
  525. debug("entering test_close()");
  526. UNLINK(TEST_SUN_PATH);
  527. memset(&addr, '\0', sizeof(struct sockaddr_un));
  528. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  529. addr.sun_family = AF_UNIX;
  530. debug("Test close() success");
  531. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  532. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  533. if (rc != 0) {
  534. test_fail("bind() should have worked");
  535. }
  536. CLOSE(sd);
  537. debug("Close an already closed file descriptor");
  538. errno = 0;
  539. rc = close(sd);
  540. if (!(rc == -1 && errno == EBADF)) {
  541. test_fail("close(sd) should have failed with EBADF");
  542. }
  543. UNLINK(TEST_SUN_PATH);
  544. debug("dup()'ing a file descriptor and closing both should work");
  545. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  546. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  547. if (rc != 0) {
  548. test_fail("bind() should have worked");
  549. }
  550. errno = 0;
  551. sd2 = dup(sd);
  552. if (sd2 == -1) {
  553. test_fail("dup(sd) should have worked");
  554. } else {
  555. CLOSE(sd2);
  556. CLOSE(sd);
  557. }
  558. UNLINK(TEST_SUN_PATH);
  559. /* Create and close a socket a bunch of times.
  560. * If the implementation doesn't properly free the
  561. * socket during close(), eventually socket() will
  562. * fail when the internal descriptor table is full.
  563. */
  564. for (i = 0; i < 1024; i++) {
  565. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  566. CLOSE(sd);
  567. }
  568. debug("leaving test_close()");
  569. }
  570. void test_sockopts(void)
  571. {
  572. int i;
  573. int rc;
  574. int sd;
  575. int option_value;
  576. socklen_t option_len;
  577. debug("entering test_sockopts()");
  578. for (i = 0; i < 3; i++) {
  579. SOCKET(sd, PF_UNIX, types[i], 0);
  580. debug("Test setsockopt() works");
  581. option_value = 0;
  582. option_len = sizeof(option_value);
  583. errno = 0;
  584. rc = getsockopt(sd, SOL_SOCKET, SO_TYPE, &option_value,
  585. &option_len);
  586. if (rc != 0) {
  587. test_fail("setsockopt() should have worked");
  588. }
  589. if (option_value != types[i]) {
  590. test_fail("SO_TYPE didn't seem to work.");
  591. }
  592. CLOSE(sd);
  593. }
  594. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  595. debug("Test setsockopt() works");
  596. option_value = 0;
  597. option_len = sizeof(option_value);
  598. errno = 0;
  599. rc = getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &option_value, &option_len);
  600. if (rc != 0) {
  601. test_fail("getsockopt() should have worked");
  602. }
  603. if (option_value != PIPE_BUF) {
  604. test_fail("SO_SNDBUF didn't seem to work.");
  605. }
  606. CLOSE(sd);
  607. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  608. debug("Test setsockopt() works");
  609. option_value = 0;
  610. option_len = sizeof(option_value);
  611. errno = 0;
  612. rc = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &option_value, &option_len);
  613. if (rc != 0) {
  614. test_fail("getsockopt() should have worked");
  615. }
  616. if (option_value != PIPE_BUF) {
  617. test_fail("SO_RCVBUF didn't seem to work.");
  618. }
  619. CLOSE(sd);
  620. debug("leaving test_sockopts()");
  621. }
  622. void test_read(void)
  623. {
  624. int rc;
  625. int fd;
  626. char buf[BUFSIZE];
  627. debug("entering test_read()");
  628. errno = 0;
  629. rc = read(-1, buf, sizeof(buf));
  630. if (!(rc == -1 && errno == EBADF)) {
  631. test_fail("read() should have failed with EBADF");
  632. }
  633. fd = open("/tmp", O_RDONLY);
  634. if (fd == -1) {
  635. test_fail("open(\"/tmp\", O_RDONLY) should have worked");
  636. }
  637. CLOSE(fd);
  638. debug("leaving test_read()");
  639. }
  640. void test_write(void)
  641. {
  642. int rc;
  643. char buf[BUFSIZE];
  644. debug("entering test_write()");
  645. errno = 0;
  646. rc = write(-1, buf, sizeof(buf));
  647. if (!(rc == -1 && errno == EBADF)) {
  648. test_fail("write() should have failed with EBADF");
  649. }
  650. debug("leaving test_write()");
  651. }
  652. void test_dup(void)
  653. {
  654. struct stat info1;
  655. struct stat info2;
  656. struct sockaddr_un addr;
  657. int sd, sd2;
  658. int rc;
  659. int i;
  660. debug("entering test_dup()");
  661. UNLINK(TEST_SUN_PATH);
  662. memset(&addr, '\0', sizeof(struct sockaddr_un));
  663. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  664. addr.sun_family = AF_UNIX;
  665. debug("Test dup()");
  666. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  667. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  668. if (rc != 0) {
  669. test_fail("bind() should have worked");
  670. }
  671. errno = 0;
  672. sd2 = dup(sd);
  673. if (sd2 == -1) {
  674. test_fail("dup(sd) should have worked");
  675. }
  676. rc = fstat(sd, &info1);
  677. if (rc == -1) {
  678. test_fail("fstat(fd, &info1) failed");
  679. }
  680. rc = fstat(sd2, &info2);
  681. if (rc == -1) {
  682. test_fail("fstat(sd, &info2) failed");
  683. }
  684. if (info1.st_ino != info2.st_ino) {
  685. test_fail("dup() failed info1.st_ino != info2.st_ino");
  686. }
  687. CLOSE(sd);
  688. CLOSE(sd2);
  689. debug("Test dup() with a closed socket");
  690. errno = 0;
  691. rc = dup(sd);
  692. if (!(rc == -1 && errno == EBADF)) {
  693. test_fail("dup(sd) on a closed socket shouldn't have worked");
  694. }
  695. debug("Test dup() with socket descriptor of -1");
  696. errno = 0;
  697. rc = dup(-1);
  698. if (!(rc == -1 && errno == EBADF)) {
  699. test_fail("dup(-1) shouldn't have worked");
  700. }
  701. debug("Test dup() when all of the file descriptors are taken");
  702. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  703. for (i = 4; i < getdtablesize(); i++) {
  704. rc = open("/dev/null", O_RDONLY);
  705. if (rc == -1) {
  706. test_fail("we couldn't open /dev/null for read");
  707. }
  708. }
  709. errno = 0;
  710. sd2 = dup(sd);
  711. if (!(sd2 == -1 && errno == EMFILE)) {
  712. test_fail("dup(sd) should have failed with errno = EMFILE");
  713. }
  714. for (i = 3; i < getdtablesize(); i++) {
  715. CLOSE(i);
  716. }
  717. UNLINK(TEST_SUN_PATH);
  718. debug("leaving test_dup()");
  719. }
  720. void test_dup2(void)
  721. {
  722. struct stat info1;
  723. struct stat info2;
  724. struct sockaddr_un addr;
  725. int sd;
  726. int fd;
  727. int rc;
  728. debug("entering test_dup2()");
  729. UNLINK(TEST_SUN_PATH);
  730. memset(&addr, '\0', sizeof(struct sockaddr_un));
  731. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  732. addr.sun_family = AF_UNIX;
  733. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  734. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  735. if (rc != 0) {
  736. test_fail("bind() should have worked");
  737. }
  738. fd = open("/dev/null", O_RDONLY);
  739. if (fd == -1) {
  740. test_fail("open(\"/dev/null\", O_RDONLY) failed");
  741. }
  742. fd = dup2(sd, fd);
  743. if (fd == -1) {
  744. test_fail("dup2(sd, fd) failed.");
  745. }
  746. memset(&info1, '\0', sizeof(struct stat));
  747. memset(&info2, '\0', sizeof(struct stat));
  748. rc = fstat(fd, &info1);
  749. if (rc == -1) {
  750. test_fail("fstat(fd, &info1) failed");
  751. }
  752. rc = fstat(sd, &info2);
  753. if (rc == -1) {
  754. test_fail("fstat(sd, &info2) failed");
  755. }
  756. if (!(info1.st_ino == info2.st_ino &&
  757. major(info1.st_dev) == major(info2.st_dev) &&
  758. minor(info1.st_dev) == minor(info2.st_dev))) {
  759. test_fail("dup2() failed");
  760. }
  761. CLOSE(fd);
  762. CLOSE(sd);
  763. UNLINK(TEST_SUN_PATH);
  764. debug("leaving test_dup2()");
  765. }
  766. /*
  767. * A toupper() server. This toy server converts a string to upper case.
  768. */
  769. void test_xfer_server(pid_t pid)
  770. {
  771. int i;
  772. struct timeval tv;
  773. fd_set readfds;
  774. int status;
  775. int rc;
  776. int sd;
  777. char buf[BUFSIZE];
  778. socklen_t client_addr_size;
  779. int client_sd;
  780. struct sockaddr_un addr;
  781. struct sockaddr_un client_addr;
  782. status = 0;
  783. rc = 0;
  784. sd = 0;
  785. client_sd = 0;
  786. client_addr_size = sizeof(struct sockaddr_un);
  787. memset(&buf, '\0', sizeof(buf));
  788. memset(&addr, '\0', sizeof(struct sockaddr_un));
  789. memset(&client_addr, '\0', sizeof(struct sockaddr_un));
  790. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  791. addr.sun_family = AF_UNIX;
  792. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  793. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  794. if (rc == -1) {
  795. test_fail("bind() should have worked");
  796. }
  797. rc = listen(sd, 8);
  798. if (rc == -1) {
  799. test_fail("listen(sd, 8) should have worked");
  800. }
  801. /* we're ready for connections, time to tell the client to start
  802. * the test
  803. */
  804. kill(pid, SIGUSR1);
  805. tv.tv_sec = 10;
  806. tv.tv_usec = 0;
  807. FD_ZERO(&readfds);
  808. FD_SET(sd, &readfds);
  809. /* use select() in case the client is really broken and never
  810. * attempts to connect (we don't want to block on accept()
  811. * forever).
  812. */
  813. rc = select(sd + 1, &readfds, NULL, NULL, &tv);
  814. if (rc == -1) {
  815. test_fail("[server] select() should not have failed");
  816. }
  817. if (rc != 1) {
  818. test_fail("[server] select() should have returned 1");
  819. printf("[server] select returned %d\n", rc);
  820. }
  821. if (!(FD_ISSET(sd, &readfds))) {
  822. test_fail("[server] client didn't connect within 10 seconds");
  823. kill(pid, SIGKILL);
  824. return;
  825. }
  826. client_sd = accept(sd, (struct sockaddr *) &client_addr,
  827. &client_addr_size);
  828. if (client_sd == -1) {
  829. test_fail("accept() should have worked");
  830. kill(pid, SIGKILL);
  831. return;
  832. } else {
  833. debug("[server] client accept()'d");
  834. }
  835. debug("[server] Reading message");
  836. rc = read(client_sd, buf, sizeof(buf));
  837. if (rc == -1) {
  838. test_fail("read() failed unexpectedly");
  839. kill(pid, SIGKILL);
  840. return;
  841. }
  842. debug("[server] we got the following message:");
  843. debug(buf);
  844. for (i = 0; i < rc && i < 127; i++) {
  845. buf[i] = toupper(buf[i]);
  846. }
  847. debug("[server] Writing message...");
  848. rc = write(client_sd, buf, sizeof(buf));
  849. if (rc == -1) {
  850. test_fail("write(client_sd, buf, sizeof(buf)) failed");
  851. kill(pid, SIGKILL);
  852. return;
  853. }
  854. if (rc < strlen(buf)) {
  855. test_fail("[server] write didn't write all the bytes");
  856. }
  857. memset(&buf, '\0', sizeof(buf));
  858. debug("[server] Recv message");
  859. rc = recv(client_sd, buf, sizeof(buf), 0);
  860. if (rc == -1) {
  861. test_fail("recv() failed unexpectedly");
  862. kill(pid, SIGKILL);
  863. return;
  864. }
  865. debug("[server] we got the following message:");
  866. debug(buf);
  867. for (i = 0; i < rc && i < 127; i++) {
  868. buf[i] = toupper(buf[i]);
  869. }
  870. debug("[server] Sending message...");
  871. rc = send(client_sd, buf, sizeof(buf), 0);
  872. if (rc == -1) {
  873. test_fail("send(client_sd, buf, sizeof(buf), 0) failed");
  874. kill(pid, SIGKILL);
  875. return;
  876. }
  877. if (rc < strlen(buf)) {
  878. test_fail("[server] write didn't write all the bytes");
  879. }
  880. memset(&buf, '\0', sizeof(buf));
  881. debug("[server] Recvfrom message");
  882. rc = recvfrom(client_sd, buf, sizeof(buf), 0, NULL, 0);
  883. if (rc == -1) {
  884. test_fail("recvfrom() failed unexpectedly");
  885. kill(pid, SIGKILL);
  886. return;
  887. }
  888. debug("[server] we got the following message:");
  889. debug(buf);
  890. for (i = 0; i < rc && i < 127; i++) {
  891. buf[i] = toupper(buf[i]);
  892. }
  893. debug("[server] Sendto message...");
  894. rc = sendto(client_sd, buf, sizeof(buf), 0, NULL, 0);
  895. if (rc == -1) {
  896. test_fail("sendto() failed");
  897. kill(pid, SIGKILL);
  898. return;
  899. }
  900. if (rc < strlen(buf)) {
  901. test_fail("[server] write didn't write all the bytes");
  902. }
  903. shutdown(client_sd, SHUT_RDWR);
  904. CLOSE(client_sd);
  905. shutdown(sd, SHUT_RDWR);
  906. CLOSE(sd);
  907. /* wait for client to exit */
  908. do {
  909. errno = 0;
  910. rc = waitpid(pid, &status, 0);
  911. } while (rc == -1 && errno == EINTR);
  912. /* we use the exit status to get its error count */
  913. errct += WEXITSTATUS(status);
  914. }
  915. int server_ready = 0;
  916. /* signal handler for the client */
  917. void test_xfer_sighdlr(int sig)
  918. {
  919. debug("entering signal handler");
  920. switch (sig) {
  921. /* the server will send SIGUSR1 when it is time for us
  922. * to start the tests
  923. */
  924. case SIGUSR1:
  925. server_ready = 1;
  926. debug("got SIGUSR1, the server is ready for the client");
  927. break;
  928. default:
  929. debug("didn't get SIGUSR1");
  930. }
  931. debug("leaving signal handler");
  932. }
  933. /*
  934. * A toupper() client.
  935. */
  936. void test_xfer_client(void)
  937. {
  938. struct ucred credentials;
  939. socklen_t ucred_length;
  940. struct timeval tv;
  941. fd_set readfds;
  942. struct sockaddr_un addr;
  943. struct sockaddr_un peer_addr;
  944. socklen_t peer_addr_len;
  945. int sd;
  946. int rc;
  947. char buf[BUFSIZE];
  948. debug("[client] entering test_xfer_client()");
  949. errct = 0; /* reset error count */
  950. ucred_length = sizeof(struct ucred);
  951. memset(&buf, '\0', sizeof(buf));
  952. while (server_ready == 0) {
  953. debug("[client] waiting for the server to signal");
  954. sleep(1);
  955. }
  956. peer_addr_len = sizeof(struct sockaddr_un);
  957. debug("Creating symlink to TEST_SUN_PATH");
  958. SYMLINK(TEST_SUN_PATH, TEST_SYM_A);
  959. memset(&addr, '\0', sizeof(struct sockaddr_un));
  960. strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1);
  961. addr.sun_family = AF_UNIX;
  962. debug("[client] creating client socket");
  963. SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
  964. debug("[client] connecting to server through the symlink");
  965. rc = connect(sd, (struct sockaddr *) &addr,
  966. sizeof(struct sockaddr_un));
  967. if (rc == -1) {
  968. test_fail("[client] connect() should have worked");
  969. } else {
  970. debug("[client] connected");
  971. }
  972. debug("[client] testing getpeername()");
  973. memset(&peer_addr, '\0', sizeof(struct sockaddr_un));
  974. rc = getpeername(sd, (struct sockaddr *) &peer_addr, &peer_addr_len);
  975. if (rc == -1) {
  976. test_fail("[client] getpeername() should have worked");
  977. }
  978. /* we need to use the full path "/usr/src/test/DIR_56/test.sock"
  979. * because that is what is returned by getpeername().
  980. */
  981. if (!(peer_addr.sun_family == AF_UNIX &&
  982. strncmp(peer_addr.sun_path,
  983. fullpath(TEST_SUN_PATH),
  984. sizeof(peer_addr.sun_path) - 1) == 0)) {
  985. test_fail("getpeername() didn't return the right address");
  986. }
  987. strncpy(buf, "Hello, World!", sizeof(buf) - 1);
  988. debug("[client] send to server");
  989. rc = write(sd, buf, sizeof(buf));
  990. if (rc == -1) {
  991. test_fail("[client] write() failed unexpectedly");
  992. }
  993. memset(buf, '\0', sizeof(buf));
  994. debug("[client] read from server");
  995. rc = read(sd, buf, sizeof(buf));
  996. if (rc == -1) {
  997. test_fail("[client] read() failed unexpectedly");
  998. } else {
  999. debug("[client] we got the following message:");
  1000. debug(buf);
  1001. }
  1002. if (strncmp(buf, "HELLO, WORLD!", sizeof(buf)) != 0) {
  1003. test_fail("[client] We didn't get the correct response");
  1004. }
  1005. memset(&buf, '\0', sizeof(buf));
  1006. strncpy(buf, "Bonjour!", sizeof(buf) - 1);
  1007. debug("[client] send to server");
  1008. rc = send(sd, buf, sizeof(buf), 0);
  1009. if (rc == -1) {
  1010. test_fail("[client] send() failed unexpectedly");
  1011. }
  1012. debug("Test passing the client credentials to the server");
  1013. memset(&credentials, '\0', ucred_length);
  1014. rc = getsockopt(sd, SOL_SOCKET, SO_PEERCRED, &credentials,
  1015. &ucred_length);
  1016. if (rc == -1) {
  1017. test_fail("[client] getsockopt() failed");
  1018. } else if (credentials.uid != geteuid() ||
  1019. credentials.gid != getegid()) {
  1020. printf("%d=%d=%d %d=%d=%d\n", credentials.uid, getuid(),
  1021. geteuid(), credentials.gid, getgid(), getegid());
  1022. test_fail("[client] Credential passing gave us a bad UID/GID");
  1023. }
  1024. debug("Testing select()");
  1025. tv.tv_sec = 2;
  1026. tv.tv_usec = 500000;
  1027. FD_ZERO(&readfds);
  1028. FD_SET(sd, &readfds);
  1029. rc = select(sd + 1, &readfds, NULL, NULL, &tv);
  1030. if (rc == -1) {
  1031. test_fail("[client] select() should not have failed");
  1032. }
  1033. if (rc != 1) {
  1034. test_fail("[client] select() should have returned 1");
  1035. }
  1036. if (!(FD_ISSET(sd, &readfds))) {
  1037. test_fail("The server didn't respond within 2.5 seconds");
  1038. }
  1039. memset(buf, '\0', sizeof(buf));
  1040. debug("[client] recv from server");
  1041. rc = recv(sd, buf, sizeof(buf), 0);
  1042. if (rc == -1) {
  1043. test_fail("[client] recv() failed unexpectedly");
  1044. } else {
  1045. debug("[client] we got the following message:");
  1046. debug(buf);
  1047. }
  1048. if (strncmp(buf, "BONJOUR!", sizeof(buf)) != 0) {
  1049. test_fail("[client] We didn't get the right response.");
  1050. }
  1051. memset(&buf, '\0', sizeof(buf));
  1052. strncpy(buf, "Hola!", sizeof(buf) - 1);
  1053. debug("[client] sendto to server");
  1054. rc = sendto(sd, buf, sizeof(buf), 0, NULL, 0);
  1055. if (rc == -1) {
  1056. test_fail("[client] sendto() failed");
  1057. }
  1058. debug("Testing select()");
  1059. tv.tv_sec = 2;
  1060. tv.tv_usec = 500000;
  1061. FD_ZERO(&readfds);
  1062. FD_SET(sd, &readfds);
  1063. rc = select(sd + 1, &readfds, NULL, NULL, &tv);
  1064. if (rc == -1) {
  1065. test_fail("[client] select() should not have failed");
  1066. }
  1067. if (rc != 1) {
  1068. test_fail("[client] select() should have returned 1");
  1069. }
  1070. if (!(FD_ISSET(sd, &readfds))) {
  1071. test_fail("[client] The server didn't respond in 2.5 seconds");
  1072. }
  1073. memset(buf, '\0', sizeof(buf));
  1074. debug("[client] recvfrom from server");
  1075. rc = recvfrom(sd, buf, sizeof(buf), 0, NULL, 0);
  1076. if (rc == -1) {
  1077. test_fail("[cleint] recvfrom() failed unexpectedly");
  1078. } else {
  1079. debug("[client] we got the following message:");
  1080. debug(buf);
  1081. }
  1082. if (strncmp(buf, "HOLA!", sizeof(buf)) != 0) {
  1083. test_fail("[client] We didn't get the right response.");
  1084. }
  1085. debug("[client] closing socket");
  1086. CLOSE(sd);
  1087. debug("[client] leaving test_xfer_client()");
  1088. exit(errct);
  1089. }
  1090. void test_xfer(void)
  1091. {
  1092. pid_t pid;
  1093. UNLINK(TEST_SYM_A);
  1094. UNLINK(TEST_SUN_PATH);
  1095. /* the signal handler is only used by the client, but we have to
  1096. * install it now. if we don't the server may signal the client
  1097. * before the handler is installed.
  1098. */
  1099. debug("installing signal handler");
  1100. if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
  1101. test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
  1102. }
  1103. debug("signal handler installed");
  1104. server_ready = 0;
  1105. pid = fork();
  1106. if (pid == -1) {
  1107. test_fail("fork() failed");
  1108. return;
  1109. } else if (pid == 0) {
  1110. debug("child");
  1111. test_xfer_client();
  1112. test_fail("we should never get here");
  1113. exit(1);
  1114. } else {
  1115. debug("parent");
  1116. test_xfer_server(pid);
  1117. debug("parent done");
  1118. }
  1119. UNLINK(TEST_SYM_A);
  1120. UNLINK(TEST_SUN_PATH);
  1121. }
  1122. void test_simple_client(int type)
  1123. {
  1124. char buf[BUFSIZE];
  1125. int sd, rc;
  1126. struct sockaddr_un addr;
  1127. sd = socket(PF_UNIX, type, 0);
  1128. if (sd == -1) {
  1129. test_fail("socket");
  1130. exit(errct);
  1131. }
  1132. while (server_ready == 0) {
  1133. debug("[client] waiting for the server");
  1134. sleep(1);
  1135. }
  1136. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  1137. addr.sun_family = AF_UNIX;
  1138. bzero(buf, BUFSIZE);
  1139. snprintf(buf, BUFSIZE-1, "Hello, My Name is Client.");
  1140. if (type == SOCK_DGRAM) {
  1141. rc = sendto(sd, buf, strlen(buf) + 1, 0,
  1142. (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  1143. if (rc == -1) {
  1144. test_fail("sendto");
  1145. exit(errct);
  1146. }
  1147. } else {
  1148. rc = connect(sd, (struct sockaddr *) &addr,
  1149. sizeof(struct sockaddr_un));
  1150. if (rc == -1) {
  1151. test_fail("connect");
  1152. exit(errct);
  1153. }
  1154. rc = write(sd, buf, strlen(buf) + 1);
  1155. if (rc == -1) {
  1156. test_fail("write");
  1157. }
  1158. memset(buf, '\0', BUFSIZE);
  1159. rc = read(sd, buf, BUFSIZE);
  1160. if (rc == -1) {
  1161. test_fail("read");
  1162. }
  1163. if (strcmp("Hello, My Name is Server.", buf) != 0) {
  1164. test_fail("didn't read the correct string");
  1165. }
  1166. }
  1167. rc = close(sd);
  1168. if (rc == -1) {
  1169. test_fail("close");
  1170. }
  1171. exit(errct);
  1172. }
  1173. void test_simple_server(int type, pid_t pid)
  1174. {
  1175. char buf[BUFSIZE];
  1176. int sd, rc, client_sd, status;
  1177. struct sockaddr_un addr;
  1178. socklen_t addr_len;
  1179. addr_len = sizeof(struct sockaddr_un);
  1180. sd = socket(PF_UNIX, type, 0);
  1181. if (sd == -1) {
  1182. test_fail("socket");
  1183. }
  1184. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  1185. addr.sun_family = AF_UNIX;
  1186. rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
  1187. if (rc == -1) {
  1188. test_fail("bind");
  1189. }
  1190. if (type == SOCK_DGRAM) {
  1191. /* ready for client */
  1192. kill(pid, SIGUSR1);
  1193. rc = recvfrom(sd, buf, BUFSIZE, 0,
  1194. (struct sockaddr *) &addr, &addr_len);
  1195. if (rc == -1) {
  1196. test_fail("recvfrom");
  1197. }
  1198. } else {
  1199. rc = listen(sd, 5);
  1200. if (rc == -1) {
  1201. test_fail("listen");
  1202. }
  1203. /* we're ready for connections, time to tell the client
  1204. * to start the test
  1205. */
  1206. kill(pid, SIGUSR1);
  1207. client_sd = accept(sd, (struct sockaddr *) &addr, &addr_len);
  1208. if (client_sd == -1) {
  1209. test_fail("accept");
  1210. }
  1211. memset(buf, '\0', BUFSIZE);
  1212. rc = read(client_sd, buf, BUFSIZE);
  1213. if (rc == -1) {
  1214. test_fail("read");
  1215. }
  1216. if (strcmp("Hello, My Name is Client.", buf) != 0) {
  1217. test_fail("didn't read the correct string");
  1218. }
  1219. /* added for extra fun to make the client block on read() */
  1220. sleep(1);
  1221. bzero(buf, BUFSIZE);
  1222. snprintf(buf, BUFSIZE-1, "Hello, My Name is Server.");
  1223. rc = write(client_sd, buf, strlen(buf) + 1);
  1224. if (rc == -1) {
  1225. test_fail("write");
  1226. }
  1227. rc = close(client_sd);
  1228. if (rc == -1) {
  1229. test_fail("close");
  1230. }
  1231. }
  1232. rc = close(sd);
  1233. if (rc == -1) {
  1234. test_fail("close");
  1235. }
  1236. /* wait for client to exit */
  1237. do {
  1238. errno = 0;
  1239. rc = waitpid(pid, &status, 0);
  1240. } while (rc == -1 && errno == EINTR);
  1241. /* we use the exit status to get its error count */
  1242. errct += WEXITSTATUS(status);
  1243. }
  1244. void test_simple_client_server(int type)
  1245. {
  1246. pid_t pid;
  1247. debug("test_simple_client_server()");
  1248. UNLINK(TEST_SUN_PATH);
  1249. /* the signal handler is only used by the client, but we have to
  1250. * install it now. if we don't the server may signal the client
  1251. * before the handler is installed.
  1252. */
  1253. debug("installing signal handler");
  1254. if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
  1255. test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
  1256. }
  1257. debug("signal handler installed");
  1258. server_ready = 0;
  1259. pid = fork();
  1260. if (pid == -1) {
  1261. test_fail("fork() failed");
  1262. return;
  1263. } else if (pid == 0) {
  1264. debug("child");
  1265. test_simple_client(type);
  1266. test_fail("we should never get here");
  1267. exit(1);
  1268. } else {
  1269. debug("parent");
  1270. test_simple_server(type, pid);
  1271. debug("parent done");
  1272. }
  1273. UNLINK(TEST_SUN_PATH);
  1274. }
  1275. void test_vectorio(int type)
  1276. {
  1277. int sv[2];
  1278. int rc;
  1279. struct iovec iov[3];
  1280. char buf1[BUFSIZE];
  1281. char buf2[BUFSIZE];
  1282. char buf3[BUFSIZE];
  1283. char buf4[BUFSIZE*3];
  1284. const struct iovec *iovp = iov;
  1285. debug("begin vectorio tests");
  1286. memset(buf1, '\0', BUFSIZE);
  1287. strncpy(buf1, "HELLO ", BUFSIZE - 1);
  1288. memset(buf2, '\0', BUFSIZE);
  1289. strncpy(buf2, "WORLD", BUFSIZE - 1);
  1290. memset(buf3, '\0', BUFSIZE);
  1291. rc = socketpair(PF_UNIX, type, 0, sv);
  1292. if (rc == -1) {
  1293. test_fail("socketpair");
  1294. }
  1295. iov[0].iov_base = buf1;
  1296. iov[0].iov_len = strlen(buf1);
  1297. iov[1].iov_base = buf2;
  1298. iov[1].iov_len = strlen(buf2);
  1299. iov[2].iov_base = buf3;
  1300. iov[2].iov_len = 1;
  1301. rc = writev(sv[0], iovp, 3);
  1302. if (rc == -1) {
  1303. test_fail("writev");
  1304. }
  1305. memset(buf4, '\0', BUFSIZE*3);
  1306. rc = read(sv[1], buf4, BUFSIZE*3);
  1307. if (rc == -1) {
  1308. test_fail("read");
  1309. }
  1310. if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
  1311. test_fail("the string we read was not 'HELLO WORLD'");
  1312. }
  1313. memset(buf1, '\0', BUFSIZE);
  1314. strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
  1315. rc = write(sv[1], buf1, strlen(buf1) + 1);
  1316. if (rc == -1) {
  1317. test_fail("write");
  1318. }
  1319. memset(buf2, '\0', BUFSIZE);
  1320. memset(buf3, '\0', BUFSIZE);
  1321. memset(buf4, '\0', BUFSIZE*3);
  1322. iov[0].iov_base = buf2;
  1323. iov[0].iov_len = 5;
  1324. iov[1].iov_base = buf3;
  1325. iov[1].iov_len = 5;
  1326. iov[2].iov_base = buf4;
  1327. iov[2].iov_len = 32;
  1328. rc = readv(sv[0], iovp, 3);
  1329. if (rc == -1) {
  1330. test_fail("readv");
  1331. }
  1332. if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
  1333. strncmp(buf4, "Time", 4)) {
  1334. test_fail("readv");
  1335. }
  1336. rc = close(sv[0]);
  1337. if (rc == -1) {
  1338. test_fail("close");
  1339. }
  1340. rc = close(sv[1]);
  1341. if (rc == -1) {
  1342. test_fail("close");
  1343. }
  1344. debug("done vector io tests");
  1345. }
  1346. void test_msg(int type)
  1347. {
  1348. int sv[2];
  1349. int rc;
  1350. struct msghdr msg1;
  1351. struct msghdr msg2;
  1352. struct iovec iov[3];
  1353. char buf1[BUFSIZE];
  1354. char buf2[BUFSIZE];
  1355. char buf3[BUFSIZE];
  1356. char buf4[BUFSIZE*3];
  1357. debug("begin sendmsg/recvmsg tests");
  1358. memset(buf1, '\0', BUFSIZE);
  1359. strncpy(buf1, "HELLO ", BUFSIZE - 1);
  1360. memset(buf2, '\0', BUFSIZE);
  1361. strncpy(buf2, "WORLD", BUFSIZE - 1);
  1362. memset(buf3, '\0', BUFSIZE);
  1363. rc = socketpair(PF_UNIX, type, 0, sv);
  1364. if (rc == -1) {
  1365. test_fail("socketpair");
  1366. }
  1367. iov[0].iov_base = buf1;
  1368. iov[0].iov_len = strlen(buf1);
  1369. iov[1].iov_base = buf2;
  1370. iov[1].iov_len = strlen(buf2);
  1371. iov[2].iov_base = buf3;
  1372. iov[2].iov_len = 1;
  1373. memset(&msg1, '\0', sizeof(struct msghdr));
  1374. msg1.msg_name = NULL;
  1375. msg1.msg_namelen = 0;
  1376. msg1.msg_iov = iov;
  1377. msg1.msg_iovlen = 3;
  1378. msg1.msg_control = NULL;
  1379. msg1.msg_controllen = 0;
  1380. msg1.msg_flags = 0;
  1381. rc = sendmsg(sv[0], &msg1, 0);
  1382. if (rc == -1) {
  1383. test_fail("writev");
  1384. }
  1385. memset(buf4, '\0', BUFSIZE*3);
  1386. rc = read(sv[1], buf4, BUFSIZE*3);
  1387. if (rc == -1) {
  1388. test_fail("read");
  1389. }
  1390. if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
  1391. test_fail("the string we read was not 'HELLO WORLD'");
  1392. }
  1393. memset(buf1, '\0', BUFSIZE);
  1394. strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
  1395. rc = write(sv[1], buf1, strlen(buf1) + 1);
  1396. if (rc == -1) {
  1397. test_fail("write");
  1398. }
  1399. memset(buf2, '\0', BUFSIZE);
  1400. memset(buf3, '\0', BUFSIZE);
  1401. memset(buf4, '\0', BUFSIZE*3);
  1402. iov[0].iov_base = buf2;
  1403. iov[0].iov_len = 5;
  1404. iov[1].iov_base = buf3;
  1405. iov[1].iov_len = 5;
  1406. iov[2].iov_base = buf4;
  1407. iov[2].iov_len = 32;
  1408. memset(&msg2, '\0', sizeof(struct msghdr));
  1409. msg2.msg_name = NULL;
  1410. msg2.msg_namelen = 0;
  1411. msg2.msg_iov = iov;
  1412. msg2.msg_iovlen = 3;
  1413. msg2.msg_control = NULL;
  1414. msg2.msg_controllen = 0;
  1415. msg2.msg_flags = 0;
  1416. rc = recvmsg(sv[0], &msg2, 0);
  1417. if (rc == -1) {
  1418. test_fail("readv");
  1419. }
  1420. if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
  1421. strncmp(buf4, "Time", 4)) {
  1422. test_fail("readv");
  1423. }
  1424. rc = close(sv[0]);
  1425. if (rc == -1) {
  1426. test_fail("close");
  1427. }
  1428. rc = close(sv[1]);
  1429. if (rc == -1) {
  1430. test_fail("close");
  1431. }
  1432. }
  1433. void test_msg_dgram(void)
  1434. {
  1435. int rc;
  1436. int src;
  1437. int dst;
  1438. struct sockaddr_un addr;
  1439. struct iovec iov[3];
  1440. struct msghdr msg1;
  1441. struct msghdr msg2;
  1442. char buf1[BUFSIZE];
  1443. char buf2[BUFSIZE];
  1444. char buf3[BUFSIZE];
  1445. socklen_t addrlen = sizeof(struct sockaddr_un);
  1446. debug("test msg_dgram");
  1447. UNLINK(TEST_SUN_PATH);
  1448. UNLINK(TEST_SUN_PATHB);
  1449. src = socket(PF_UNIX, SOCK_DGRAM, 0);
  1450. if (src == -1) {
  1451. test_fail("socket");
  1452. }
  1453. dst = socket(PF_UNIX, SOCK_DGRAM, 0);
  1454. if (dst == -1) {
  1455. test_fail("socket");
  1456. }
  1457. memset(&addr, '\0', sizeof(struct sockaddr_un));
  1458. addr.sun_family = AF_UNIX;
  1459. strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1);
  1460. rc = bind(src, (struct sockaddr *) &addr, addrlen);
  1461. if (rc == -1) {
  1462. test_fail("bind");
  1463. }
  1464. memset(&addr, '\0', sizeof(struct sockaddr_un));
  1465. addr.sun_family = AF_UNIX;
  1466. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  1467. rc = bind(dst, (struct sockaddr *) &addr, addrlen);
  1468. if (rc == -1) {
  1469. test_fail("bind");
  1470. }
  1471. memset(&buf1, '\0', BUFSIZE);
  1472. memset(&buf2, '\0', BUFSIZE);
  1473. memset(&buf3, '\0', BUFSIZE);
  1474. strncpy(buf1, "Minix ", BUFSIZE-1);
  1475. strncpy(buf2, "is ", BUFSIZE-1);
  1476. strncpy(buf3, "great!", BUFSIZE-1);
  1477. iov[0].iov_base = buf1;
  1478. iov[0].iov_len = 6;
  1479. iov[1].iov_base = buf2;
  1480. iov[1].iov_len = 3;
  1481. iov[2].iov_base = buf3;
  1482. iov[2].iov_len = 32;
  1483. memset(&msg1, '\0', sizeof(struct msghdr));
  1484. msg1.msg_name = &addr;
  1485. msg1.msg_namelen = addrlen;
  1486. msg1.msg_iov = iov;
  1487. msg1.msg_iovlen = 3;
  1488. msg1.msg_control = NULL;
  1489. msg1.msg_controllen = 0;
  1490. msg1.msg_flags = 0;
  1491. rc = sendmsg(src, &msg1, 0);
  1492. if (rc == -1) {
  1493. test_fail("sendmsg");
  1494. }
  1495. memset(&buf1, '\0', BUFSIZE);
  1496. memset(&buf2, '\0', BUFSIZE);
  1497. iov[0].iov_base = buf1;
  1498. iov[0].iov_len = 9;
  1499. iov[1].iov_base = buf2;
  1500. iov[1].iov_len = 32;
  1501. memset(&addr, '\0', sizeof(struct sockaddr_un));
  1502. memset(&msg2, '\0', sizeof(struct msghdr));
  1503. msg2.msg_name = &addr;
  1504. msg2.msg_namelen = sizeof(struct sockaddr_un);
  1505. msg2.msg_iov = iov;
  1506. msg2.msg_iovlen = 2;
  1507. msg2.msg_control = NULL;
  1508. msg2.msg_controllen = 0;
  1509. msg2.msg_flags = 0;
  1510. rc = recvmsg(dst, &msg2, 0);
  1511. if (rc == -1) {
  1512. test_fail("recvmsg");
  1513. }
  1514. if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
  1515. test_fail("recvmsg");
  1516. }
  1517. /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
  1518. * because that is what is returned by recvmsg().
  1519. */
  1520. if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path,
  1521. fullpath(TEST_SUN_PATHB))) {
  1522. test_fail("recvmsg");
  1523. }
  1524. rc = close(dst);
  1525. if (rc == -1) {
  1526. test_fail("close");
  1527. }
  1528. rc = close(src);
  1529. if (rc == -1) {
  1530. test_fail("close");
  1531. }
  1532. UNLINK(TEST_SUN_PATH);
  1533. UNLINK(TEST_SUN_PATHB);
  1534. }
  1535. void test_scm_credentials(void)
  1536. {
  1537. int rc;
  1538. int src;
  1539. int dst;
  1540. struct ucred cred;
  1541. struct cmsghdr *cmsg = NULL;
  1542. struct sockaddr_un addr;
  1543. struct iovec iov[3];
  1544. struct msghdr msg1;
  1545. struct msghdr msg2;
  1546. char buf1[BUFSIZE];
  1547. char buf2[BUFSIZE];
  1548. char buf3[BUFSIZE];
  1549. char ctrl[BUFSIZE];
  1550. socklen_t addrlen = sizeof(struct sockaddr_un);
  1551. debug("test_scm_credentials");
  1552. UNLINK(TEST_SUN_PATH);
  1553. UNLINK(TEST_SUN_PATHB);
  1554. debug("creating src socket");
  1555. src = socket(PF_UNIX, SOCK_DGRAM, 0);
  1556. if (src == -1) {
  1557. test_fail("socket");
  1558. }
  1559. debug("creating dst socket");
  1560. dst = socket(PF_UNIX, SOCK_DGRAM, 0);
  1561. if (dst == -1) {
  1562. test_fail("socket");
  1563. }
  1564. debug("binding src socket");
  1565. memset(&addr, '\0', sizeof(struct sockaddr_un));
  1566. addr.sun_family = AF_UNIX;
  1567. strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1);
  1568. rc = bind(src, (struct sockaddr *) &addr, addrlen);
  1569. if (rc == -1) {
  1570. test_fail("bind");
  1571. }
  1572. debug("binding dst socket");
  1573. memset(&addr, '\0', sizeof(struct sockaddr_un));
  1574. addr.sun_family = AF_UNIX;
  1575. strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
  1576. rc = bind(dst, (struct sockaddr *) &addr, addrlen);
  1577. if (rc == -1) {
  1578. test_fail("bind");
  1579. }
  1580. memset(&buf1, '\0', BUFSIZE);
  1581. memset(&buf2, '\0', BUFSIZE);
  1582. memset(&buf3, '\0', BUFSIZE);
  1583. memset(&ctrl, '\0', BUFSIZE);
  1584. strncpy(buf1, "Minix ", BUFSIZE-1);
  1585. strncpy(buf2, "is ", BUFSIZE-1);
  1586. strncpy(buf3, "great!", BUFSIZE-1);
  1587. iov[0].iov_base = buf1;
  1588. iov[0].iov_len = 6;
  1589. iov[1].iov_base = buf2;
  1590. iov[1].iov_len = 3;
  1591. iov[2].iov_base = buf3;
  1592. iov[2].iov_len = 32;
  1593. memset(&msg1, '\0', sizeof(struct msghdr));
  1594. msg1.msg_name = &addr;
  1595. msg1.msg_namelen = addrlen;
  1596. msg1.msg_iov = iov;
  1597. msg1.msg_iovlen = 3;
  1598. msg1.msg_control = NULL;
  1599. msg1.msg_controllen = 0;
  1600. msg1.msg_flags = 0;
  1601. debug("sending msg1");
  1602. rc = sendmsg(src, &msg1, 0);
  1603. if (rc == -1) {
  1604. test_fail("sendmsg");
  1605. }
  1606. memset(&buf1, '\0', BUFSIZE);
  1607. memset(&buf2, '\0', BUFSIZE);
  1608. memset(&buf3, '\0', BUFSIZE);
  1609. memset(&ctrl, '\0', BUFSIZE);
  1610. iov[0].iov_base = buf1;
  1611. iov[0].iov_len = 9;
  1612. iov[1].iov_base = buf2;
  1613. iov[1].iov_len = 32;
  1614. memset(&addr, '\0', sizeof(struct sockaddr_un));
  1615. memset(&msg2, '\0', sizeof(struct msghdr));
  1616. msg2.msg_name = &addr;
  1617. msg2.msg_namelen = sizeof(struct sockaddr_un);
  1618. msg2.msg_iov = iov;
  1619. msg2.msg_iovlen = 2;
  1620. msg2.msg_control = ctrl;
  1621. msg2.msg_controllen = BUFSIZE;
  1622. msg2.msg_flags = 0;
  1623. debug("recv msg2");
  1624. rc = recvmsg(dst, &msg2, 0);
  1625. if (rc == -1) {
  1626. test_fail("recvmsg");
  1627. }
  1628. debug("checking results");
  1629. if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
  1630. test_fail("recvmsg");
  1631. }
  1632. /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
  1633. * because that is what is returned by recvmsg().
  1634. */
  1635. if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path,
  1636. fullpath(TEST_SUN_PATHB))) {
  1637. test_fail("recvmsg");
  1638. }
  1639. debug("looking for credentials");
  1640. memset(&cred, '\0', sizeof(struct ucred));
  1641. for (cmsg = CMSG_FIRSTHDR(&msg2); cmsg != NULL;
  1642. cmsg = CMSG_NXTHDR(&msg2, cmsg)) {
  1643. if (cmsg->cmsg_level == SOL_SOCKET &&
  1644. cmsg->cmsg_type == SCM_CREDENTIALS) {
  1645. memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct ucred));
  1646. break;
  1647. }
  1648. }
  1649. if (cred.pid != getpid() || cred.uid != geteuid() ||
  1650. cred.gid != getegid()) {
  1651. test_fail("did no receive the proper credentials");
  1652. }
  1653. rc = close(dst);
  1654. if (rc == -1) {
  1655. test_fail("close");
  1656. }
  1657. rc = close(src);
  1658. if (rc == -1) {
  1659. test_fail("close");
  1660. }
  1661. UNLINK(TEST_SUN_PATH);
  1662. UNLINK(TEST_SUN_PATHB);
  1663. }
  1664. void test_connect(void)
  1665. {
  1666. int i, sd, sds[2], rc;
  1667. /* connect() is already tested throughout test56, but
  1668. * in most cases the client and server end up on /dev/uds
  1669. * minor 0 and minor 1. This test opens some sockets first and
  1670. * then calls test_simple_client_server(). This forces the
  1671. * client and server minor numbers higher in the descriptor table.
  1672. */
  1673. debug("starting test_connect()");
  1674. sd = socket(AF_UNIX, SOCK_DGRAM, 0);
  1675. if (sd == -1) {
  1676. test_fail("couldn't create a socket");
  1677. }
  1678. rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sds);
  1679. if (rc == -1) {
  1680. test_fail("couldn't create a socketpair");
  1681. }
  1682. for (i = 0; i < 3; i++) {
  1683. test_simple_client_server(types[i]);
  1684. }
  1685. rc = close(sds[1]);
  1686. if (rc == -1) {
  1687. test_fail("close() failed");
  1688. }
  1689. rc = close(sds[0]);
  1690. if (rc == -1) {
  1691. test_fail("close() failed");
  1692. }
  1693. rc = close(sd);
  1694. if (rc == -1) {
  1695. test_fail("close() failed");
  1696. }
  1697. debug("exiting test_connect()");
  1698. }
  1699. int test_multiproc_read(void)
  1700. {
  1701. /* test that when we fork() a process with an open socket descriptor,
  1702. * the descriptor in each process points to the same thing.
  1703. */
  1704. pid_t pid;
  1705. int sds[2];
  1706. int rc, status;
  1707. char buf[3];
  1708. debug("entering test_multiproc_read()");
  1709. rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
  1710. if (rc == -1) {
  1711. test_fail("socketpair");
  1712. return 1;
  1713. }
  1714. memset(buf, '\0', 3);
  1715. /* the signal handler is only used by the client, but we have to
  1716. * install it now. if we don't the server may signal the client
  1717. * before the handler is installed.
  1718. */
  1719. debug("installing signal handler");
  1720. if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
  1721. test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
  1722. return 1;
  1723. }
  1724. debug("signal handler installed");
  1725. server_ready = 0;
  1726. pid = fork();
  1727. if (pid == -1) {
  1728. test_fail("fork");
  1729. return 1;
  1730. } else if (pid == 0) {
  1731. while (server_ready == 0) {
  1732. debug("waiting for SIGUSR1 from parent");
  1733. sleep(1);
  1734. }
  1735. rc = read(sds[1], buf, 2);
  1736. if (rc == -1) {
  1737. test_fail("read");
  1738. exit(1);
  1739. }
  1740. if (!(buf[0] == 'X' && buf[1] == '3')) {
  1741. test_fail("Didn't read X3");
  1742. exit(1);
  1743. }
  1744. exit(0);
  1745. } else {
  1746. rc = write(sds[0], "MNX3", 4);
  1747. if (rc == -1) {
  1748. test_fail("write");
  1749. }
  1750. rc = read(sds[1], buf, 2);
  1751. if (rc == -1) {
  1752. test_fail("read");
  1753. }
  1754. if (!(buf[0] == 'M' && buf[1] == 'N')) {
  1755. test_fail("Didn't read MN");
  1756. }
  1757. /* time to tell the client to start the test */
  1758. kill(pid, SIGUSR1);
  1759. do {
  1760. rc = waitpid(pid, &status, 0);
  1761. } while (rc == -1 && errno == EINTR);
  1762. /* we use the exit status to get its error count */
  1763. errct += WEXITSTATUS(status);
  1764. }
  1765. return 0;
  1766. }
  1767. int test_multiproc_write(void)
  1768. {
  1769. /* test that when we fork() a process with an open socket descriptor,
  1770. * the descriptor in each process points to the same thing.
  1771. */
  1772. pid_t pid;
  1773. int sds[2];
  1774. int rc, status;
  1775. char buf[7];
  1776. debug("entering test_multiproc_write()");
  1777. rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
  1778. if (rc == -1) {
  1779. test_fail("socketpair");
  1780. return 1;
  1781. }
  1782. memset(buf, '\0', 7);
  1783. /* the signal handler is only used by the client, but we have to
  1784. * install it now. if we don't the server may signal the client
  1785. * before the handler is installed.
  1786. */
  1787. debug("installing signal handler");
  1788. if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
  1789. test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
  1790. return 1;
  1791. }
  1792. debug("signal handler installed");
  1793. server_ready = 0;
  1794. pid = fork();
  1795. if (pid == -1) {
  1796. test_fail("fork");
  1797. return 1;
  1798. } else if (pid == 0) {
  1799. while (server_ready == 0) {
  1800. debug("waiting for SIGUSR1 from paren…

Large files files are truncated, but you can click here to view the full file