diff --git a/tools/regression/sockets/accf_data_attach/accf_data_attach.c b/tools/regression/sockets/accf_data_attach/accf_data_attach.c index bfcda1a03349..27f270ba1c46 100644 --- a/tools/regression/sockets/accf_data_attach/accf_data_attach.c +++ b/tools/regression/sockets/accf_data_attach/accf_data_attach.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -64,7 +65,7 @@ main(void) struct accept_filter_arg afa; struct sockaddr_in sin; socklen_t len; - int lso, ret; + int lso, so, i, ret; /* XXX: PLAIN_TEST_REQUIRE_MODULE "backport" for stable/9 */ const char *_mod_name = "accf_data"; @@ -76,7 +77,7 @@ main(void) } /* XXX: PLAIN_TEST_REQUIRE_MODULE for stable/9 */ - printf("1..11\n"); + printf("1..12\n"); /* * Step 0. Open socket(). @@ -103,6 +104,7 @@ main(void) /* * Step 2. Bind(). Ideally this will succeed. */ + setsockopt(lso, SOL_SOCKET, SO_REUSEADDR, &lso, sizeof(lso)); bzero(&sin, sizeof(sin)); sin.sin_len = sizeof(sin); sin.sin_family = AF_INET; @@ -203,24 +205,53 @@ main(void) printf("ok 10 - getsockopt\n"); /* - * Step 10: Remove accept filter. After removing the accept filter + * Step 10: Set listening socket to non blocking mode. Open + * connection to our listening socket and try to accept. Should + * no succeed. Write a byte of data and try again. Should accept. + */ + i = fcntl(lso, F_GETFL); + if (i < 0) + errx(-1, "not ok 11 - ioctl(F_GETFL): %s", strerror(errno)); + i |= O_NONBLOCK; + if (fcntl(lso, F_SETFL, i) != 0) + errx(-1, "not ok 11 - ioctl(F_SETFL): %s", strerror(errno)); + so = socket(PF_INET, SOCK_STREAM, 0); + if (so == -1) + errx(-1, "not ok 11 - socket: %s", strerror(errno)); + if (connect(so, (struct sockaddr *)&sin, sizeof(sin)) < 0) + errx(-1, "not ok 11 - connect %s", strerror(errno)); + if (accept(lso, NULL, 0) != -1 && errno != EWOULDBLOCK) + errx(-1, "not ok 11 - accept #1 %s", strerror(errno)); + if (write(so, "0", 1) != 1) + errx(-1, "not ok 11 - write %s", strerror(errno)); + /* + * XXXGL: ugly, but we need to make sure that our write reaches + * remote side of the socket. + */ + usleep(10000); + if (accept(lso, NULL, 0) < 1) + errx(-1, "not ok 11 - accept #2 %s", strerror(errno)); + printf("ok 11 - accept\n"); + + /* + * Step 11: Remove accept filter. After removing the accept filter * getsockopt() should fail with EINVAL. */ ret = setsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0); if (ret != 0) - errx(-1, "not ok 11 - setsockopt() after listen() " + errx(-1, "not ok 12 - setsockopt() after listen() " "failed with %d (%s)", errno, strerror(errno)); bzero(&afa, sizeof(afa)); len = sizeof(afa); ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len); if (ret == 0) - errx(-1, "not ok 11 - getsockopt() after removing " + errx(-1, "not ok 12 - getsockopt() after removing " "the accept filter returns valid accept filter %s", afa.af_name); if (errno != EINVAL) - errx(-1, "not ok 11 - getsockopt() after removing the accept" + errx(-1, "not ok 12 - getsockopt() after removing the accept" "filter failed with %d (%s)", errno, strerror(errno)); - printf("ok 11 - setsockopt\n"); + printf("ok 12 - setsockopt\n"); close(lso); return (0);