]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
tests: (test_mkfds) add poll multiplexer
authorMasatake YAMATO <yamato@redhat.com>
Sun, 30 Jul 2023 08:56:54 +0000 (17:56 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Mon, 11 Sep 2023 11:19:42 +0000 (20:19 +0900)
meson.build
tests/helpers/Makemodule.am
tests/helpers/test_mkfds.c
tests/helpers/test_mkfds.h [new file with mode: 0644]

index 8e3d6bb1d93dfc42afc4e1514bbd5b2a9fdeb630..d077fef06e1817de7a9ed14ca5a68f03d84bc8cd 100644 (file)
@@ -3384,6 +3384,7 @@ if LINUX
   exe = executable(
     'test_mkfds',
     'tests/helpers/test_mkfds.c',
+    'tests/helpers/test_mkfds.h',
     include_directories : includes,
     dependencies : mq_libs,
     build_by_default: program_tests)
index 6f0075f8388457979a8fb525ac85ed35ed62e681..00a32c8159127a656576bd6b93ffd12c30d9b332 100644 (file)
@@ -33,7 +33,7 @@ test_uuid_namespace_SOURCES = tests/helpers/test_uuid_namespace.c \
 
 if LINUX
 check_PROGRAMS += test_mkfds
-test_mkfds_SOURCES = tests/helpers/test_mkfds.c
+test_mkfds_SOURCES = tests/helpers/test_mkfds.c tests/helpers/test_mkfds.h
 test_mkfds_LDADD = $(LDADD) $(MQ_LIBS)
 
 check_PROGRAMS += test_enosys
index 7c6060b887751fae577d1a68c3146d167b3ecf08..930768e29537a707ce26326cd753e95705efb610 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "c.h"
 #include "xalloc.h"
+#include "test_mkfds.h"
 
 #include <arpa/inet.h>
 #include <ctype.h>
@@ -37,6 +38,7 @@
 #include <net/if.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
+#include <poll.h>
 #include <sched.h>
 #include <signal.h>
 #include <stdbool.h>
@@ -314,19 +316,6 @@ static void free_arg(struct arg *arg)
        arg->free(arg->v);
 }
 
-enum multiplexing_mode {
-   MX_READ   = 1 << 0,
-   MX_WRITE  = 1 << 1,
-   MX_EXCEPT = 1 << 2,
-};
-
-struct fdesc {
-       int fd;
-       void (*close)(int, void *);
-       unsigned int mx_modes;
-       void *data;
-};
-
 struct factory {
        const char *name;       /* [-a-zA-Z0-9_]+ */
        const char *desc;
@@ -3817,7 +3806,7 @@ struct multiplexer {
        void (*fn)(bool, struct fdesc *fdescs, size_t n_fdescs);
 };
 
-#if defined(__NR_select)
+#if defined(__NR_select) || defined(__NR_poll)
 static void sighandler_nop(int si _U_)
 {
    /* Do nothing */
@@ -3887,6 +3876,14 @@ DEFUN_WAIT_EVENT_SELECT(select,
                        syscall(__NR_select, n, &readfds, &writefds, &exceptfds, NULL))
 #endif
 
+#ifdef __NR_poll
+static DEFUN_WAIT_EVENT_POLL(poll,
+                     "poll",
+                     ,
+                     signal(SIGCONT,sighandler_nop);,
+                     syscall(__NR_poll, pfds, n, -1))
+#endif
+
 #define DEFAULT_MULTIPLEXER 0
 static struct multiplexer multiplexers [] = {
        {
@@ -3905,6 +3902,12 @@ static struct multiplexer multiplexers [] = {
                .fn = wait_event_select,
        },
 #endif
+#ifdef __NR_poll
+       {
+               .name = "poll",
+               .fn = wait_event_poll,
+       },
+#endif
 };
 
 static struct multiplexer *lookup_multiplexer(const char *name)
diff --git a/tests/helpers/test_mkfds.h b/tests/helpers/test_mkfds.h
new file mode 100644 (file)
index 0000000..068dd72
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * test_mkfds - make various file descriptors
+ *
+ * Written by Masatake YAMATO <yamato@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef TEST_MKFDS_H
+#define TEST_MKFDS_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+enum multiplexing_mode {
+   MX_READ   = 1 << 0,
+   MX_WRITE  = 1 << 1,
+   MX_EXCEPT = 1 << 2,
+};
+
+struct fdesc {
+       int fd;
+       void (*close)(int, void *);
+       unsigned int mx_modes;
+       void *data;
+};
+
+#define DEFUN_WAIT_EVENT_POLL(NAME,SYSCALL,XDECLS,SETUP_SIG_HANDLER,SYSCALL_INVOCATION) \
+       void wait_event_##NAME(bool add_stdin, struct fdesc *fdescs, size_t n_fdescs) \
+       {                                                               \
+               int n = add_stdin? 1: 0;                                \
+               int n0 = 0;                                             \
+               struct pollfd *pfds = NULL;                             \
+                                                                       \
+               XDECLS                                                  \
+                                                                       \
+               for (size_t i = 0; i < n_fdescs; i++)                   \
+                       if (fdescs[i].mx_modes)                         \
+                               n++;                                    \
+                                                                       \
+               pfds = xcalloc(n, sizeof(pfds[0]));                     \
+                                                                       \
+               for (size_t i = 0; i < n_fdescs; i++) {                 \
+                       if (!fdescs[i].mx_modes)                        \
+                               continue;                               \
+                       pfds[n0].fd = fdescs[i].fd;                     \
+                       if (fdescs[i].mx_modes & MX_READ)               \
+                               pfds[n0].events |= POLLIN;              \
+                       if (fdescs[i].mx_modes & MX_WRITE)              \
+                               pfds[n0].events |= POLLOUT;             \
+                       if (fdescs[i].mx_modes & MX_EXCEPT)             \
+                               pfds[n0].events |= POLLHUP;             \
+                       n0++;                                           \
+               }                                                       \
+                                                                       \
+               if (add_stdin) {                                        \
+                       pfds[n0].fd = 0;                                \
+                       pfds[n0].events |= POLLIN;                      \
+               }                                                       \
+                                                                       \
+               SETUP_SIG_HANDLER                                       \
+                                                                       \
+               if (SYSCALL_INVOCATION < 0                              \
+                   && errno != EINTR)                                  \
+                       err(EXIT_FAILURE, "failed in " SYSCALL);        \
+               free(pfds);                                             \
+       }
+
+#endif /* TEST_MKFDS_H */