1906d4687089fa0f40436d453de38449cb1dd459brobbiew/* 22aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * Copyright (c) International Business Machines Corp., 2002 32aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * Ported by Paul Larson 42aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz> 5906d4687089fa0f40436d453de38449cb1dd459brobbiew * 62aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * This program is free software; you can redistribute it and/or modify 72aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * it under the terms of the GNU General Public License as published by 82aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * the Free Software Foundation; either version 2 of the License, or 92aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * (at your option) any later version. 10906d4687089fa0f40436d453de38449cb1dd459brobbiew * 112aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * This program is distributed in the hope that it will be useful, 122aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * but WITHOUT ANY WARRANTY; without even the implied warranty of 132aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 142aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * the GNU General Public License for more details. 15906d4687089fa0f40436d453de38449cb1dd459brobbiew * 162aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * You should have received a copy of the GNU General Public License 172aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * along with this program; if not, write to the Free Software 182aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19906d4687089fa0f40436d453de38449cb1dd459brobbiew */ 20906d4687089fa0f40436d453de38449cb1dd459brobbiew 21906d4687089fa0f40436d453de38449cb1dd459brobbiew/* 222aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * Test the ability of pipe to open the maximum even number of file 232aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * descriptors permitted (or (maxfds - 3)/2 pipes) 24906d4687089fa0f40436d453de38449cb1dd459brobbiew * 25906d4687089fa0f40436d453de38449cb1dd459brobbiew * ALGORITHM 262aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * 1. record file descriptors open prior to test run 272aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * 2. open pipes until EMFILE is returned 282aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * 3. check to see that the number of pipes opened is (maxfds - 3) / 2 292aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * 4. close all fds in range 0, maximal fd that were not open prior to 302aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis * the test execution 31906d4687089fa0f40436d453de38449cb1dd459brobbiew */ 326617b477babb4933ac65c2db08a94ced22c4b2f1robbiew#include <unistd.h> 33906d4687089fa0f40436d453de38449cb1dd459brobbiew#include <fcntl.h> 34906d4687089fa0f40436d453de38449cb1dd459brobbiew#include <errno.h> 358638910f6ed981998527594ecf8af9879247636frobbiew#include <stdlib.h> 368638910f6ed981998527594ecf8af9879247636frobbiew#include <stdio.h> 372aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis#include <string.h> 382aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis#include <dirent.h> 392aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 40906d4687089fa0f40436d453de38449cb1dd459brobbiew#include "test.h" 412aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis#include "safe_macros.h" 42906d4687089fa0f40436d453de38449cb1dd459brobbiew 43906d4687089fa0f40436d453de38449cb1dd459brobbiewchar *TCID = "pipe07"; 44906d4687089fa0f40436d453de38449cb1dd459brobbiewint TST_TOTAL = 1; 45906d4687089fa0f40436d453de38449cb1dd459brobbiew 462aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis/* used to record file descriptors open at the test start */ 472aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic int rec_fds[128]; 482aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic int rec_fds_max; 492aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic void record_open_fds(void); 502aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic void close_test_fds(int max_fd); 512aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 522aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic void setup(void); 532aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic void cleanup(void); 54906d4687089fa0f40436d453de38449cb1dd459brobbiew 55906d4687089fa0f40436d453de38449cb1dd459brobbiewint main(int ac, char **av) 56906d4687089fa0f40436d453de38449cb1dd459brobbiew{ 5789af32a63ce8a780ea39337339e14caae244b5a4Cyril Hrubis int lc; 582aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis int min, ret; 592aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis int npipes; 602aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis int pipes[2], max_fd = 0; 61906d4687089fa0f40436d453de38449cb1dd459brobbiew 62d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis tst_parse_opts(ac, av, NULL, NULL); 632aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 64906d4687089fa0f40436d453de38449cb1dd459brobbiew setup(); 658638910f6ed981998527594ecf8af9879247636frobbiew 662aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis min = getdtablesize() - rec_fds_max; 67906d4687089fa0f40436d453de38449cb1dd459brobbiew 68906d4687089fa0f40436d453de38449cb1dd459brobbiew for (lc = 0; TEST_LOOPING(lc); lc++) { 69d59a659cd639ca2780b00049d102acd2a783d585Caspar Zhang tst_count = 0; 70906d4687089fa0f40436d453de38449cb1dd459brobbiew 7156207cec7732e09c216c751c0b5f88a242bacae6subrata_modak for (npipes = 0;; npipes++) { 722aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis ret = pipe(pipes); 732aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (ret < 0) { 74906d4687089fa0f40436d453de38449cb1dd459brobbiew if (errno != EMFILE) { 755ef7d2fdd1c7cd6c77c8f17cf74ef243d512cb93vapier tst_brkm(TFAIL, cleanup, 7656207cec7732e09c216c751c0b5f88a242bacae6subrata_modak "got unexpected error - %d", 7756207cec7732e09c216c751c0b5f88a242bacae6subrata_modak errno); 78906d4687089fa0f40436d453de38449cb1dd459brobbiew } 79906d4687089fa0f40436d453de38449cb1dd459brobbiew break; 80906d4687089fa0f40436d453de38449cb1dd459brobbiew } 812aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 822aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis max_fd = MAX(pipes[0], max_fd); 832aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis max_fd = MAX(pipes[1], max_fd); 84906d4687089fa0f40436d453de38449cb1dd459brobbiew } 852aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 86906d4687089fa0f40436d453de38449cb1dd459brobbiew if (npipes == (min / 2)) 8756207cec7732e09c216c751c0b5f88a242bacae6subrata_modak tst_resm(TPASS, "Opened %d pipes", npipes); 88906d4687089fa0f40436d453de38449cb1dd459brobbiew else 89906d4687089fa0f40436d453de38449cb1dd459brobbiew tst_resm(TFAIL, "Unable to open maxfds/2 pipes"); 90906d4687089fa0f40436d453de38449cb1dd459brobbiew 912aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis close_test_fds(max_fd); 922aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis max_fd = 0; 93906d4687089fa0f40436d453de38449cb1dd459brobbiew } 942aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 95906d4687089fa0f40436d453de38449cb1dd459brobbiew cleanup(); 961e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper tst_exit(); 972aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis} 98906d4687089fa0f40436d453de38449cb1dd459brobbiew 992aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic void setup(void) 1002aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis{ 1012aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis tst_sig(FORK, DEF_HANDLER, cleanup); 1022aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis TEST_PAUSE; 1032aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 1042aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis record_open_fds(); 105906d4687089fa0f40436d453de38449cb1dd459brobbiew} 106906d4687089fa0f40436d453de38449cb1dd459brobbiew 1072aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic void record_open_fds(void) 108906d4687089fa0f40436d453de38449cb1dd459brobbiew{ 1092aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis DIR *dir = opendir("/proc/self/fd"); 1102aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis int dir_fd, fd; 1112aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis struct dirent *file; 1126617b477babb4933ac65c2db08a94ced22c4b2f1robbiew 1132aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (dir == NULL) 1142aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis tst_brkm(TBROK | TERRNO, cleanup, "opendir()"); 1156617b477babb4933ac65c2db08a94ced22c4b2f1robbiew 1162aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis dir_fd = dirfd(dir); 1176617b477babb4933ac65c2db08a94ced22c4b2f1robbiew 1182aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (dir_fd == -1) 1192aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis tst_brkm(TBROK | TERRNO, cleanup, "dirfd()"); 1208638910f6ed981998527594ecf8af9879247636frobbiew 1212aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis errno = 0; 122906d4687089fa0f40436d453de38449cb1dd459brobbiew 1232aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis while ((file = readdir(dir))) { 1242aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) 1252aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis continue; 1262aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 1272aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis fd = atoi(file->d_name); 1282aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 1292aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (fd == dir_fd) 1302aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis continue; 1312aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 1322aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (rec_fds_max >= ARRAY_SIZE(rec_fds)) { 1332aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis tst_brkm(TBROK, cleanup, 1342aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis "Too much file descriptors open"); 1352aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis } 136906d4687089fa0f40436d453de38449cb1dd459brobbiew 1372aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis rec_fds[rec_fds_max++] = fd; 1382aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis } 1392aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 1402aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (errno) 1412aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis tst_brkm(TBROK | TERRNO, cleanup, "readdir()"); 1422aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 1432aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis closedir(dir); 1442aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 1452aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis tst_resm(TINFO, "Found %u files open", rec_fds_max); 146906d4687089fa0f40436d453de38449cb1dd459brobbiew} 147906d4687089fa0f40436d453de38449cb1dd459brobbiew 1482aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic int not_recorded(int fd) 149906d4687089fa0f40436d453de38449cb1dd459brobbiew{ 1502aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis int i; 151906d4687089fa0f40436d453de38449cb1dd459brobbiew 1522aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis for (i = 0; i < rec_fds_max; i++) 1532aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (fd == rec_fds[i]) 1542aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis return 0; 1556617b477babb4933ac65c2db08a94ced22c4b2f1robbiew 1562aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis return 1; 1572aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis} 1586617b477babb4933ac65c2db08a94ced22c4b2f1robbiew 1592aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic void close_test_fds(int max_fd) 1602aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis{ 1612aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis int i; 1622aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 1632aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis for (i = 0; i <= max_fd; i++) { 1642aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (not_recorded(i)) { 1652aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (close(i)) { 1662aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis if (errno == EBADF) 1672aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis continue; 1682aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis tst_resm(TWARN | TERRNO, "close(%i)", i); 1692aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis } 1702aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis } 1712aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis } 1722aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis} 1732aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis 1742aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubisstatic void cleanup(void) 1752aabae101f562a9de0483518b9e0a00cf5a923a7Cyril Hrubis{ 176ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 177