Add a check to alert on close() lingering when it should not. Signed-off-by: Michal Luczaj <m...@rbox.co> --- tools/testing/vsock/vsock_test.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c index d0f6d253ac72d08a957cb81a3c38fcc72bec5a53..82d0bc20dfa75041f04eada1b4310be2f7c3a0c1 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -1788,13 +1788,16 @@ static void test_stream_connect_retry_server(const struct test_opts *opts) close(fd); } +#define LINGER_TIMEOUT 1 /* seconds */ + static void test_stream_linger_client(const struct test_opts *opts) { struct linger optval = { .l_onoff = 1, - .l_linger = 1 + .l_linger = LINGER_TIMEOUT }; - int fd; + int bytes_unsent, fd; + time_t ts; fd = vsock_stream_connect(opts->peer_cid, opts->peer_port); if (fd < 0) { @@ -1807,7 +1810,28 @@ static void test_stream_linger_client(const struct test_opts *opts) exit(EXIT_FAILURE); } + /* Byte left unread to expose any incorrect behaviour. */ + send_byte(fd, 1, 0); + + /* Reuse LINGER_TIMEOUT to wait for bytes_unsent == 0. */ + timeout_begin(LINGER_TIMEOUT); + do { + if (ioctl(fd, SIOCOUTQ, &bytes_unsent) < 0) { + perror("ioctl(SIOCOUTQ)"); + exit(EXIT_FAILURE); + } + timeout_check("ioctl(SIOCOUTQ) == 0"); + } while (bytes_unsent != 0); + timeout_end(); + + ts = current_nsec(); close(fd); + if ((current_nsec() - ts) / NSEC_PER_SEC > 0) { + fprintf(stderr, "Unexpected lingering on close()\n"); + exit(EXIT_FAILURE); + } + + control_writeln("DONE"); } static void test_stream_linger_server(const struct test_opts *opts) @@ -1820,7 +1844,7 @@ static void test_stream_linger_server(const struct test_opts *opts) exit(EXIT_FAILURE); } - vsock_wait_remote_close(fd); + control_expectln("DONE"); close(fd); } -- 2.49.0