1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21b85337dSArnaldo Carvalho de Melo #include <api/fd/array.h>
316b91d5eSArnaldo Carvalho de Melo #include <poll.h>
41b85337dSArnaldo Carvalho de Melo #include "util/debug.h"
51b85337dSArnaldo Carvalho de Melo #include "tests/tests.h"
61b85337dSArnaldo Carvalho de Melo
fdarray__init_revents(struct fdarray * fda,short revents)71b85337dSArnaldo Carvalho de Melo static void fdarray__init_revents(struct fdarray *fda, short revents)
81b85337dSArnaldo Carvalho de Melo {
91b85337dSArnaldo Carvalho de Melo int fd;
101b85337dSArnaldo Carvalho de Melo
111b85337dSArnaldo Carvalho de Melo fda->nr = fda->nr_alloc;
121b85337dSArnaldo Carvalho de Melo
131b85337dSArnaldo Carvalho de Melo for (fd = 0; fd < fda->nr; ++fd) {
141b85337dSArnaldo Carvalho de Melo fda->entries[fd].fd = fda->nr - fd;
1559b4412fSAlexey Budankov fda->entries[fd].events = revents;
161b85337dSArnaldo Carvalho de Melo fda->entries[fd].revents = revents;
171b85337dSArnaldo Carvalho de Melo }
181b85337dSArnaldo Carvalho de Melo }
191b85337dSArnaldo Carvalho de Melo
fdarray__fprintf_prefix(struct fdarray * fda,const char * prefix,FILE * fp)201b85337dSArnaldo Carvalho de Melo static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE *fp)
211b85337dSArnaldo Carvalho de Melo {
221b85337dSArnaldo Carvalho de Melo int printed = 0;
231b85337dSArnaldo Carvalho de Melo
24bb963e16SNamhyung Kim if (verbose <= 0)
251b85337dSArnaldo Carvalho de Melo return 0;
261b85337dSArnaldo Carvalho de Melo
271b85337dSArnaldo Carvalho de Melo printed += fprintf(fp, "\n%s: ", prefix);
281b85337dSArnaldo Carvalho de Melo return printed + fdarray__fprintf(fda, fp);
291b85337dSArnaldo Carvalho de Melo }
301b85337dSArnaldo Carvalho de Melo
test__fdarray__filter(struct test_suite * test __maybe_unused,int subtest __maybe_unused)31*33f44bfdSIan Rogers static int test__fdarray__filter(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
321b85337dSArnaldo Carvalho de Melo {
3359b4412fSAlexey Budankov int nr_fds, err = TEST_FAIL;
341b85337dSArnaldo Carvalho de Melo struct fdarray *fda = fdarray__new(5, 5);
351b85337dSArnaldo Carvalho de Melo
361b85337dSArnaldo Carvalho de Melo if (fda == NULL) {
371b85337dSArnaldo Carvalho de Melo pr_debug("\nfdarray__new() failed!");
381b85337dSArnaldo Carvalho de Melo goto out;
391b85337dSArnaldo Carvalho de Melo }
401b85337dSArnaldo Carvalho de Melo
411b85337dSArnaldo Carvalho de Melo fdarray__init_revents(fda, POLLIN);
42258e4bfcSWang Nan nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
431b85337dSArnaldo Carvalho de Melo if (nr_fds != fda->nr_alloc) {
441b85337dSArnaldo Carvalho de Melo pr_debug("\nfdarray__filter()=%d != %d shouldn't have filtered anything",
451b85337dSArnaldo Carvalho de Melo nr_fds, fda->nr_alloc);
461b85337dSArnaldo Carvalho de Melo goto out_delete;
471b85337dSArnaldo Carvalho de Melo }
481b85337dSArnaldo Carvalho de Melo
491b85337dSArnaldo Carvalho de Melo fdarray__init_revents(fda, POLLHUP);
50258e4bfcSWang Nan nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
511b85337dSArnaldo Carvalho de Melo if (nr_fds != 0) {
521b85337dSArnaldo Carvalho de Melo pr_debug("\nfdarray__filter()=%d != %d, should have filtered all fds",
531b85337dSArnaldo Carvalho de Melo nr_fds, fda->nr_alloc);
541b85337dSArnaldo Carvalho de Melo goto out_delete;
551b85337dSArnaldo Carvalho de Melo }
561b85337dSArnaldo Carvalho de Melo
571b85337dSArnaldo Carvalho de Melo fdarray__init_revents(fda, POLLHUP);
581b85337dSArnaldo Carvalho de Melo fda->entries[2].revents = POLLIN;
591b85337dSArnaldo Carvalho de Melo
601b85337dSArnaldo Carvalho de Melo pr_debug("\nfiltering all but fda->entries[2]:");
611b85337dSArnaldo Carvalho de Melo fdarray__fprintf_prefix(fda, "before", stderr);
62258e4bfcSWang Nan nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
631b85337dSArnaldo Carvalho de Melo fdarray__fprintf_prefix(fda, " after", stderr);
641b85337dSArnaldo Carvalho de Melo if (nr_fds != 1) {
651b85337dSArnaldo Carvalho de Melo pr_debug("\nfdarray__filter()=%d != 1, should have left just one event", nr_fds);
661b85337dSArnaldo Carvalho de Melo goto out_delete;
671b85337dSArnaldo Carvalho de Melo }
681b85337dSArnaldo Carvalho de Melo
691b85337dSArnaldo Carvalho de Melo fdarray__init_revents(fda, POLLHUP);
701b85337dSArnaldo Carvalho de Melo fda->entries[0].revents = POLLIN;
711b85337dSArnaldo Carvalho de Melo fda->entries[3].revents = POLLIN;
721b85337dSArnaldo Carvalho de Melo
731b85337dSArnaldo Carvalho de Melo pr_debug("\nfiltering all but (fda->entries[0], fda->entries[3]):");
741b85337dSArnaldo Carvalho de Melo fdarray__fprintf_prefix(fda, "before", stderr);
75258e4bfcSWang Nan nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
761b85337dSArnaldo Carvalho de Melo fdarray__fprintf_prefix(fda, " after", stderr);
771b85337dSArnaldo Carvalho de Melo if (nr_fds != 2) {
781b85337dSArnaldo Carvalho de Melo pr_debug("\nfdarray__filter()=%d != 2, should have left just two events",
791b85337dSArnaldo Carvalho de Melo nr_fds);
801b85337dSArnaldo Carvalho de Melo goto out_delete;
811b85337dSArnaldo Carvalho de Melo }
821b85337dSArnaldo Carvalho de Melo
831b85337dSArnaldo Carvalho de Melo pr_debug("\n");
841b85337dSArnaldo Carvalho de Melo
851b85337dSArnaldo Carvalho de Melo err = 0;
861b85337dSArnaldo Carvalho de Melo out_delete:
871b85337dSArnaldo Carvalho de Melo fdarray__delete(fda);
881b85337dSArnaldo Carvalho de Melo out:
891b85337dSArnaldo Carvalho de Melo return err;
901b85337dSArnaldo Carvalho de Melo }
911b85337dSArnaldo Carvalho de Melo
test__fdarray__add(struct test_suite * test __maybe_unused,int subtest __maybe_unused)92*33f44bfdSIan Rogers static int test__fdarray__add(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
931b85337dSArnaldo Carvalho de Melo {
941b85337dSArnaldo Carvalho de Melo int err = TEST_FAIL;
951b85337dSArnaldo Carvalho de Melo struct fdarray *fda = fdarray__new(2, 2);
961b85337dSArnaldo Carvalho de Melo
971b85337dSArnaldo Carvalho de Melo if (fda == NULL) {
981b85337dSArnaldo Carvalho de Melo pr_debug("\nfdarray__new() failed!");
991b85337dSArnaldo Carvalho de Melo goto out;
1001b85337dSArnaldo Carvalho de Melo }
1011b85337dSArnaldo Carvalho de Melo
1021b85337dSArnaldo Carvalho de Melo #define FDA_CHECK(_idx, _fd, _revents) \
1031b85337dSArnaldo Carvalho de Melo if (fda->entries[_idx].fd != _fd) { \
1041b85337dSArnaldo Carvalho de Melo pr_debug("\n%d: fda->entries[%d](%d) != %d!", \
1051b85337dSArnaldo Carvalho de Melo __LINE__, _idx, fda->entries[1].fd, _fd); \
1061b85337dSArnaldo Carvalho de Melo goto out_delete; \
1071b85337dSArnaldo Carvalho de Melo } \
1081b85337dSArnaldo Carvalho de Melo if (fda->entries[_idx].events != (_revents)) { \
1091b85337dSArnaldo Carvalho de Melo pr_debug("\n%d: fda->entries[%d].revents(%d) != %d!", \
1101b85337dSArnaldo Carvalho de Melo __LINE__, _idx, fda->entries[_idx].fd, _revents); \
1111b85337dSArnaldo Carvalho de Melo goto out_delete; \
1121b85337dSArnaldo Carvalho de Melo }
1131b85337dSArnaldo Carvalho de Melo
1141b85337dSArnaldo Carvalho de Melo #define FDA_ADD(_idx, _fd, _revents, _nr) \
115ab4c1f9fSAlexey Budankov if (fdarray__add(fda, _fd, _revents, fdarray_flag__default) < 0) { \
1161b85337dSArnaldo Carvalho de Melo pr_debug("\n%d: fdarray__add(fda, %d, %d) failed!", \
1171b85337dSArnaldo Carvalho de Melo __LINE__,_fd, _revents); \
1181b85337dSArnaldo Carvalho de Melo goto out_delete; \
1191b85337dSArnaldo Carvalho de Melo } \
1201b85337dSArnaldo Carvalho de Melo if (fda->nr != _nr) { \
1211b85337dSArnaldo Carvalho de Melo pr_debug("\n%d: fdarray__add(fda, %d, %d)=%d != %d", \
1221b85337dSArnaldo Carvalho de Melo __LINE__,_fd, _revents, fda->nr, _nr); \
1231b85337dSArnaldo Carvalho de Melo goto out_delete; \
1241b85337dSArnaldo Carvalho de Melo } \
1251b85337dSArnaldo Carvalho de Melo FDA_CHECK(_idx, _fd, _revents)
1261b85337dSArnaldo Carvalho de Melo
1271b85337dSArnaldo Carvalho de Melo FDA_ADD(0, 1, POLLIN, 1);
1281b85337dSArnaldo Carvalho de Melo FDA_ADD(1, 2, POLLERR, 2);
1291b85337dSArnaldo Carvalho de Melo
1301b85337dSArnaldo Carvalho de Melo fdarray__fprintf_prefix(fda, "before growing array", stderr);
1311b85337dSArnaldo Carvalho de Melo
1321b85337dSArnaldo Carvalho de Melo FDA_ADD(2, 35, POLLHUP, 3);
1331b85337dSArnaldo Carvalho de Melo
1341b85337dSArnaldo Carvalho de Melo if (fda->entries == NULL) {
1351b85337dSArnaldo Carvalho de Melo pr_debug("\nfdarray__add(fda, 35, POLLHUP) should have allocated fda->pollfd!");
1361b85337dSArnaldo Carvalho de Melo goto out_delete;
1371b85337dSArnaldo Carvalho de Melo }
1381b85337dSArnaldo Carvalho de Melo
1391b85337dSArnaldo Carvalho de Melo fdarray__fprintf_prefix(fda, "after 3rd add", stderr);
1401b85337dSArnaldo Carvalho de Melo
1411b85337dSArnaldo Carvalho de Melo FDA_ADD(3, 88, POLLIN | POLLOUT, 4);
1421b85337dSArnaldo Carvalho de Melo
1431b85337dSArnaldo Carvalho de Melo fdarray__fprintf_prefix(fda, "after 4th add", stderr);
1441b85337dSArnaldo Carvalho de Melo
1451b85337dSArnaldo Carvalho de Melo FDA_CHECK(0, 1, POLLIN);
1461b85337dSArnaldo Carvalho de Melo FDA_CHECK(1, 2, POLLERR);
1471b85337dSArnaldo Carvalho de Melo FDA_CHECK(2, 35, POLLHUP);
1481b85337dSArnaldo Carvalho de Melo FDA_CHECK(3, 88, POLLIN | POLLOUT);
1491b85337dSArnaldo Carvalho de Melo
1501b85337dSArnaldo Carvalho de Melo #undef FDA_ADD
1511b85337dSArnaldo Carvalho de Melo #undef FDA_CHECK
1521b85337dSArnaldo Carvalho de Melo
1531b85337dSArnaldo Carvalho de Melo pr_debug("\n");
1541b85337dSArnaldo Carvalho de Melo
1551b85337dSArnaldo Carvalho de Melo err = 0;
1561b85337dSArnaldo Carvalho de Melo out_delete:
1571b85337dSArnaldo Carvalho de Melo fdarray__delete(fda);
1581b85337dSArnaldo Carvalho de Melo out:
1591b85337dSArnaldo Carvalho de Melo return err;
1601b85337dSArnaldo Carvalho de Melo }
161d68f0365SIan Rogers
162d68f0365SIan Rogers DEFINE_SUITE("Filter fds with revents mask in a fdarray", fdarray__filter);
163d68f0365SIan Rogers DEFINE_SUITE("Add fd to a fdarray, making it autogrow", fdarray__add);
164