From aaf526ce325b57383c4b4fa3b62fe84421a38f80 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Tue, 19 Jul 2016 15:09:05 +0000 Subject: [PATCH] tests: add recv_mmsg and send_mmsg functions to libtests * tests/tests.h (recv_mmsg, send_mmsg): New prototype. * tests/libmmsg.c: New file. * tests/Makefile.am (libtests_a_SOURCES): Add it. * tests/mmsg.c Do not check for __NR_sendmmsg, __NR_recvmmsg, HAVE_SENDMMSG, and HAVE_RECVMMSG. Do not include unused headers. (recv_mmsg, send_mmsg): Remove. --- tests/Makefile.am | 1 + tests/libmmsg.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++ tests/mmsg.c | 58 +++------------------------------------ tests/tests.h | 6 +++++ 4 files changed, 80 insertions(+), 54 deletions(-) create mode 100644 tests/libmmsg.c diff --git a/tests/Makefile.am b/tests/Makefile.am index c537a9ea..3c873625 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -47,6 +47,7 @@ libtests_a_SOURCES = \ hexdump_strdup.c \ hexquote_strndup.c \ inode_of_sockfd.c \ + libmmsg.c \ libsocketcall.c \ overflowuid.c \ print_quoted_string.c \ diff --git a/tests/libmmsg.c b/tests/libmmsg.c new file mode 100644 index 00000000..07feb7c5 --- /dev/null +++ b/tests/libmmsg.c @@ -0,0 +1,69 @@ +/* + * Wrappers for recvmmsg and sendmmsg syscalls. + * + * Copyright (c) 2016 Dmitry V. Levin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" +#include +#include + +#ifndef __NR_recvmmsg +# define __NR_recvmmsg -1 +#endif +#define SC_recvmmsg 19 + +#ifndef __NR_sendmmsg +# define __NR_sendmmsg -1 +#endif +#define SC_sendmmsg 20 + +int +recv_mmsg(const int fd, struct mmsghdr *const vec, + const unsigned int vlen, const unsigned int flags, + struct timespec *const timeout) +{ + int rc = socketcall(__NR_recvmmsg, SC_recvmmsg, + fd, (long) vec, vlen, flags, (long) timeout); + + if (rc < 0 && ENOSYS == errno) + perror_msg_and_skip("recvmmsg"); + + return rc; +} + +int +send_mmsg(const int fd, struct mmsghdr *const vec, + const unsigned int vlen, const unsigned int flags) +{ + int rc = socketcall(__NR_sendmmsg, SC_sendmmsg, + fd, (long) vec, vlen, flags, 0); + + if (rc < 0 && ENOSYS == errno) + perror_msg_and_skip("sendmmsg"); + + return rc; +} diff --git a/tests/mmsg.c b/tests/mmsg.c index 0c7fed53..44b62144 100644 --- a/tests/mmsg.c +++ b/tests/mmsg.c @@ -27,54 +27,10 @@ */ #include "tests.h" -# include +#include +#include -#if (defined __NR_sendmmsg || defined HAVE_SENDMMSG) \ - && (defined __NR_recvmmsg || defined HAVE_RECVMMSG) - -# include -# include -# include -# include - -# include "msghdr.h" - -static int -send_mmsg(int fd, struct mmsghdr *vec, unsigned int vlen, unsigned int flags) -{ - int rc; -#ifdef __NR_sendmmsg - rc = syscall(__NR_sendmmsg, (long) fd, vec, (unsigned long) vlen, - (unsigned long) flags); - if (rc >= 0 || ENOSYS != errno) - return rc; - tprintf("sendmmsg(%d, %p, %u, MSG_DONTROUTE|MSG_NOSIGNAL)" - " = -1 ENOSYS (%m)\n", fd, vec, vlen); -#endif -#ifdef HAVE_SENDMMSG - rc = sendmmsg(fd, vec, vlen, flags); -#endif - return rc; -} - -static int -recv_mmsg(int fd, struct mmsghdr *vec, unsigned int vlen, unsigned int flags, - struct timespec *timeout) -{ - int rc; -#ifdef __NR_recvmmsg - rc = syscall(__NR_recvmmsg, (long) fd, vec, (unsigned long) vlen, - (unsigned long) flags, timeout); - if (rc >= 0 || ENOSYS != errno) - return rc; - tprintf("recvmmsg(%d, %p, %u, MSG_DONTWAIT, NULL)" - " = -1 ENOSYS (%m)\n", fd, vec, vlen); -#endif -#ifdef HAVE_RECVMMSG - rc = recvmmsg(fd, vec, vlen, flags, timeout); -#endif - return rc; -} +#include "msghdr.h" int main(void) @@ -135,7 +91,7 @@ main(void) const unsigned int n_w_mmh = ARRAY_SIZE(w_mmh_); int r = send_mmsg(1, w_mmh, n_w_mmh, MSG_DONTROUTE | MSG_NOSIGNAL); - if (r < 0 && errno == ENOSYS) + if (r < 0) perror_msg_and_skip("sendmmsg"); assert(r == (int) n_w_mmh); assert(close(1) == 0); @@ -237,9 +193,3 @@ main(void) tprintf("+++ exited with 0 +++\n"); return 0; } - -#else - -SKIP_MAIN_UNDEFINED("(__NR_sendmmsg || HAVE_SENDMMSG) && (__NR_recvmmsg || HAVE_RECVMMSG)") - -#endif diff --git a/tests/tests.h b/tests/tests.h index c61d0051..e0bf2288 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -111,6 +111,12 @@ int printxval(const struct xlat *, const unsigned long long, const char *); int socketcall(const int nr, const int call, long a1, long a2, long a3, long a4, long a5); +/* Wrappers for recvmmsg and sendmmsg syscalls. */ +struct mmsghdr; +struct timespec; +int recv_mmsg(int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *); +int send_mmsg(int, struct mmsghdr *, unsigned int, unsigned int); + # define ARRAY_SIZE(arg) ((unsigned int) (sizeof(arg) / sizeof((arg)[0]))) # define LENGTH_OF(arg) ((unsigned int) sizeof(arg) - 1) -- 2.40.0