diff options
Diffstat (limited to 'testcases/kernel/syscalls/pipe/pipe07.c')
-rw-r--r-- | testcases/kernel/syscalls/pipe/pipe07.c | 203 |
1 files changed, 65 insertions, 138 deletions
diff --git a/testcases/kernel/syscalls/pipe/pipe07.c b/testcases/kernel/syscalls/pipe/pipe07.c index 55bb9f419..8098007c2 100644 --- a/testcases/kernel/syscalls/pipe/pipe07.c +++ b/testcases/kernel/syscalls/pipe/pipe07.c @@ -1,176 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) International Business Machines Corp., 2002 - * Ported by Paul Larson + * Ported by Paul Larson * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz> - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will 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 + * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com> */ -/* - * Test the ability of pipe to open the maximum even number of file - * descriptors permitted (or (maxfds - 3)/2 pipes) +/*\ + * [Description] * - * ALGORITHM - * 1. record file descriptors open prior to test run - * 2. open pipes until EMFILE is returned - * 3. check to see that the number of pipes opened is (maxfds - 3) / 2 - * 4. close all fds in range 0, maximal fd that were not open prior to - * the test execution + * Verify that, pipe(2) syscall can open the maximum number of + * file descriptors permitted. */ -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <dirent.h> -#include "test.h" -#include "safe_macros.h" - -char *TCID = "pipe07"; -int TST_TOTAL = 1; - -/* used to record file descriptors open at the test start */ -static int rec_fds[128]; -static int rec_fds_max; -static void record_open_fds(void); -static void close_test_fds(int max_fd); +#include "tst_test.h" +#include <stdlib.h> -static void setup(void); -static void cleanup(void); +static int *opened_fds, *pipe_fds; +static int num_pipe_fds, exp_num_pipes; -int main(int ac, char **av) +static int record_open_fds(void) { - int lc; - int min, ret; - int npipes; - int pipes[2], max_fd = 0; - - tst_parse_opts(ac, av, NULL, NULL); + DIR *dir; + struct dirent *ent; + int fd; + int num_opened_fds = 0; + int arr_size = 0; - setup(); + dir = SAFE_OPENDIR("/proc/self/fd"); - min = getdtablesize() - rec_fds_max; - - for (lc = 0; TEST_LOOPING(lc); lc++) { - tst_count = 0; + while ((ent = SAFE_READDIR(dir))) { + if (!strcmp(ent->d_name, ".") || + !strcmp(ent->d_name, "..")) + continue; + fd = atoi(ent->d_name); - for (npipes = 0;; npipes++) { - ret = pipe(pipes); - if (ret < 0) { - if (errno != EMFILE) { - tst_brkm(TFAIL, cleanup, - "got unexpected error - %d", - errno); - } - break; - } + if (fd == dirfd(dir)) + continue; - max_fd = MAX(pipes[0], max_fd); - max_fd = MAX(pipes[1], max_fd); + if (num_opened_fds >= arr_size) { + arr_size = MAX(1, arr_size * 2); + opened_fds = SAFE_REALLOC(opened_fds, arr_size * sizeof(int)); } - - if (npipes == (min / 2)) - tst_resm(TPASS, "Opened %d pipes", npipes); - else - tst_resm(TFAIL, "Unable to open maxfds/2 pipes"); - - close_test_fds(max_fd); - max_fd = 0; + opened_fds[num_opened_fds++] = fd; } - cleanup(); - tst_exit(); + SAFE_CLOSEDIR(dir); + + return num_opened_fds; } static void setup(void) { - tst_sig(FORK, DEF_HANDLER, cleanup); - TEST_PAUSE; + int max_fds; + + max_fds = getdtablesize(); + tst_res(TINFO, "getdtablesize() = %d", max_fds); + pipe_fds = SAFE_MALLOC(max_fds * sizeof(int)); - record_open_fds(); + exp_num_pipes = (max_fds - record_open_fds()) / 2 * 2; + tst_res(TINFO, "expected max fds to be opened by pipe(): %d", exp_num_pipes); } -static void record_open_fds(void) +static void run(void) { - DIR *dir = opendir("/proc/self/fd"); - int dir_fd, fd; - struct dirent *file; - - if (dir == NULL) - tst_brkm(TBROK | TERRNO, cleanup, "opendir()"); - - dir_fd = dirfd(dir); + int fds[2]; - if (dir_fd == -1) - tst_brkm(TBROK | TERRNO, cleanup, "dirfd()"); - - errno = 0; - - while ((file = readdir(dir))) { - if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) - continue; - - fd = atoi(file->d_name); - - if (fd == dir_fd) - continue; - - if (rec_fds_max >= (int)ARRAY_SIZE(rec_fds)) { - tst_brkm(TBROK, cleanup, - "Too much file descriptors open"); + do { + TEST(pipe(fds)); + if (!TST_RET) { + pipe_fds[num_pipe_fds++] = fds[0]; + pipe_fds[num_pipe_fds++] = fds[1]; } + } while (!TST_RET); - rec_fds[rec_fds_max++] = fd; - } - - if (errno) - tst_brkm(TBROK | TERRNO, cleanup, "readdir()"); + TST_EXP_EQ_LI(errno, EMFILE); + TST_EXP_EQ_LI(exp_num_pipes, num_pipe_fds); - closedir(dir); + for (int i = 0; i < num_pipe_fds; i++) + SAFE_CLOSE(pipe_fds[i]); - tst_resm(TINFO, "Found %u files open", rec_fds_max); + num_pipe_fds = 0; } -static int not_recorded(int fd) +static void cleanup(void) { - int i; + for (int i = 0; i < num_pipe_fds; i++) + if (pipe_fds[i] > 0) + SAFE_CLOSE(pipe_fds[i]); - for (i = 0; i < rec_fds_max; i++) - if (fd == rec_fds[i]) - return 0; + if (pipe_fds) + free(pipe_fds); - return 1; + if (opened_fds) + free(opened_fds); } -static void close_test_fds(int max_fd) -{ - int i; - - for (i = 0; i <= max_fd; i++) { - if (not_recorded(i)) { - if (close(i)) { - if (errno == EBADF) - continue; - tst_resm(TWARN | TERRNO, "close(%i)", i); - } - } - } -} - -static void cleanup(void) -{ -} +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test_all = run +}; |