doc: Extend zero-recv test with methods using msghdr
This test program verifies that we can receive and discard datagrams by using recv() with a NULL buffer and zero-length. Extend it to verify it also works using recvmsg() and either an iov with a zero-length NULL buffer or an iov that itself is NULL and zero-length. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> [sbrivio: Fixed printf() message in main of recv-zero.c] Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
01e5611ec3
commit
ba74b1fea1
1 changed files with 52 additions and 8 deletions
|
@ -23,11 +23,27 @@
|
||||||
|
|
||||||
#define DSTPORT 13257U
|
#define DSTPORT 13257U
|
||||||
|
|
||||||
|
enum discard_method {
|
||||||
|
DISCARD_NULL_BUF,
|
||||||
|
DISCARD_ZERO_IOV,
|
||||||
|
DISCARD_NULL_IOV,
|
||||||
|
NUM_METHODS,
|
||||||
|
};
|
||||||
|
|
||||||
/* 127.0.0.1:DSTPORT */
|
/* 127.0.0.1:DSTPORT */
|
||||||
static const struct sockaddr_in lo_dst = SOCKADDR_INIT(INADDR_LOOPBACK, DSTPORT);
|
static const struct sockaddr_in lo_dst = SOCKADDR_INIT(INADDR_LOOPBACK, DSTPORT);
|
||||||
|
|
||||||
static void test_discard(void)
|
static void test_discard(enum discard_method method)
|
||||||
{
|
{
|
||||||
|
struct iovec zero_iov = { .iov_base = NULL, .iov_len = 0, };
|
||||||
|
struct msghdr mh_zero = {
|
||||||
|
.msg_iov = &zero_iov,
|
||||||
|
.msg_iovlen = 1,
|
||||||
|
};
|
||||||
|
struct msghdr mh_null = {
|
||||||
|
.msg_iov = NULL,
|
||||||
|
.msg_iovlen = 0,
|
||||||
|
};
|
||||||
long token1, token2;
|
long token1, token2;
|
||||||
int recv_s, send_s;
|
int recv_s, send_s;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
@ -46,11 +62,36 @@ static void test_discard(void)
|
||||||
send_token(send_s, token1);
|
send_token(send_s, token1);
|
||||||
send_token(send_s, token2);
|
send_token(send_s, token2);
|
||||||
|
|
||||||
/* cppcheck-suppress nullPointer */
|
switch (method) {
|
||||||
rc = recv(recv_s, NULL, 0, MSG_DONTWAIT);
|
case DISCARD_NULL_BUF:
|
||||||
if (rc < 0)
|
/* cppcheck-suppress nullPointer */
|
||||||
die("discarding recv(): %s\n", strerror(errno));
|
rc = recv(recv_s, NULL, 0, MSG_DONTWAIT);
|
||||||
|
if (rc < 0)
|
||||||
|
die("discarding recv(): %s\n", strerror(errno));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DISCARD_ZERO_IOV:
|
||||||
|
rc = recvmsg(recv_s, &mh_zero, MSG_DONTWAIT);
|
||||||
|
if (rc < 0)
|
||||||
|
die("recvmsg() with zero-length buffer: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
if (!((unsigned)mh_zero.msg_flags & MSG_TRUNC))
|
||||||
|
die("Missing MSG_TRUNC flag\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DISCARD_NULL_IOV:
|
||||||
|
rc = recvmsg(recv_s, &mh_null, MSG_DONTWAIT);
|
||||||
|
if (rc < 0)
|
||||||
|
die("recvmsg() with zero-length iov: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
if (!((unsigned)mh_null.msg_flags & MSG_TRUNC))
|
||||||
|
die("Missing MSG_TRUNC flag\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
die("Bad method\n");
|
||||||
|
}
|
||||||
|
|
||||||
recv_token(recv_s, token2);
|
recv_token(recv_s, token2);
|
||||||
|
|
||||||
/* cppcheck-suppress nullPointer */
|
/* cppcheck-suppress nullPointer */
|
||||||
|
@ -63,12 +104,15 @@ static void test_discard(void)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
enum discard_method method;
|
||||||
|
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
test_discard();
|
for (method = 0; method < NUM_METHODS; method++)
|
||||||
|
test_discard(method);
|
||||||
|
|
||||||
printf("Discarding datagrams with a 0-length recv() seems to work\n");
|
printf("Discarding datagrams with 0-length receives seems to work\n");
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue