blob: bf2a7adc8f3da43df7bffc67ab804202dc246f45 [file] [log] [blame]
robbiew906d4682003-01-06 17:23:07 +00001/*
Cyril Hrubis2aabae12013-06-25 19:15:40 +02002 * Copyright (c) International Business Machines Corp., 2002
3 * Ported by Paul Larson
4 * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
robbiew906d4682003-01-06 17:23:07 +00005 *
Cyril Hrubis2aabae12013-06-25 19:15:40 +02006 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
robbiew906d4682003-01-06 17:23:07 +000010 *
Cyril Hrubis2aabae12013-06-25 19:15:40 +020011 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 * the GNU General Public License for more details.
robbiew906d4682003-01-06 17:23:07 +000015 *
Cyril Hrubis2aabae12013-06-25 19:15:40 +020016 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
robbiew906d4682003-01-06 17:23:07 +000019 */
20
21/*
Cyril Hrubis2aabae12013-06-25 19:15:40 +020022 * Test the ability of pipe to open the maximum even number of file
23 * descriptors permitted (or (maxfds - 3)/2 pipes)
robbiew906d4682003-01-06 17:23:07 +000024 *
25 * ALGORITHM
Cyril Hrubis2aabae12013-06-25 19:15:40 +020026 * 1. record file descriptors open prior to test run
27 * 2. open pipes until EMFILE is returned
28 * 3. check to see that the number of pipes opened is (maxfds - 3) / 2
29 * 4. close all fds in range 0, maximal fd that were not open prior to
30 * the test execution
robbiew906d4682003-01-06 17:23:07 +000031 */
robbiew6617b472003-12-15 17:08:10 +000032#include <unistd.h>
robbiew906d4682003-01-06 17:23:07 +000033#include <fcntl.h>
34#include <errno.h>
robbiew86389102003-12-08 20:39:34 +000035#include <stdlib.h>
36#include <stdio.h>
Cyril Hrubis2aabae12013-06-25 19:15:40 +020037#include <string.h>
38#include <dirent.h>
39
robbiew906d4682003-01-06 17:23:07 +000040#include "test.h"
Cyril Hrubis2aabae12013-06-25 19:15:40 +020041#include "safe_macros.h"
robbiew906d4682003-01-06 17:23:07 +000042
43char *TCID = "pipe07";
44int TST_TOTAL = 1;
robbiew906d4682003-01-06 17:23:07 +000045
Cyril Hrubis2aabae12013-06-25 19:15:40 +020046/* used to record file descriptors open at the test start */
47static int rec_fds[128];
48static int rec_fds_max;
49static void record_open_fds(void);
50static void close_test_fds(int max_fd);
51
52static void setup(void);
53static void cleanup(void);
robbiew906d4682003-01-06 17:23:07 +000054
55int main(int ac, char **av)
56{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020057 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020058 const char *msg;
Cyril Hrubis2aabae12013-06-25 19:15:40 +020059 int min, ret;
60 int npipes;
61 int pipes[2], max_fd = 0;
robbiew906d4682003-01-06 17:23:07 +000062
Garrett Cooper53740502010-12-16 00:04:01 -080063 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080064 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiew86389102003-12-08 20:39:34 +000065
Cyril Hrubis2aabae12013-06-25 19:15:40 +020066 setup();
67
68 min = getdtablesize() - rec_fds_max;
robbiew906d4682003-01-06 17:23:07 +000069
70 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +080071 tst_count = 0;
robbiew906d4682003-01-06 17:23:07 +000072
subrata_modak56207ce2009-03-23 13:35:39 +000073 for (npipes = 0;; npipes++) {
Cyril Hrubis2aabae12013-06-25 19:15:40 +020074 ret = pipe(pipes);
75 if (ret < 0) {
robbiew906d4682003-01-06 17:23:07 +000076 if (errno != EMFILE) {
vapier5ef7d2f2006-05-26 05:58:39 +000077 tst_brkm(TFAIL, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +000078 "got unexpected error - %d",
79 errno);
robbiew906d4682003-01-06 17:23:07 +000080 }
81 break;
82 }
Cyril Hrubis2aabae12013-06-25 19:15:40 +020083
84 max_fd = MAX(pipes[0], max_fd);
85 max_fd = MAX(pipes[1], max_fd);
robbiew906d4682003-01-06 17:23:07 +000086 }
Cyril Hrubis2aabae12013-06-25 19:15:40 +020087
robbiew906d4682003-01-06 17:23:07 +000088 if (npipes == (min / 2))
subrata_modak56207ce2009-03-23 13:35:39 +000089 tst_resm(TPASS, "Opened %d pipes", npipes);
robbiew906d4682003-01-06 17:23:07 +000090 else
91 tst_resm(TFAIL, "Unable to open maxfds/2 pipes");
92
Cyril Hrubis2aabae12013-06-25 19:15:40 +020093 close_test_fds(max_fd);
94 max_fd = 0;
robbiew906d4682003-01-06 17:23:07 +000095 }
Cyril Hrubis2aabae12013-06-25 19:15:40 +020096
robbiew906d4682003-01-06 17:23:07 +000097 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -080098 tst_exit();
robbiew906d4682003-01-06 17:23:07 +000099}
100
Cyril Hrubis2aabae12013-06-25 19:15:40 +0200101static void setup(void)
robbiew906d4682003-01-06 17:23:07 +0000102{
robbiew86389102003-12-08 20:39:34 +0000103 tst_sig(FORK, DEF_HANDLER, cleanup);
robbiew906d4682003-01-06 17:23:07 +0000104 TEST_PAUSE;
105
Cyril Hrubis2aabae12013-06-25 19:15:40 +0200106 record_open_fds();
robbiew906d4682003-01-06 17:23:07 +0000107}
108
Cyril Hrubis2aabae12013-06-25 19:15:40 +0200109static void record_open_fds(void)
robbiew906d4682003-01-06 17:23:07 +0000110{
Cyril Hrubis2aabae12013-06-25 19:15:40 +0200111 DIR *dir = opendir("/proc/self/fd");
112 int dir_fd, fd;
113 struct dirent *file;
114
115 if (dir == NULL)
116 tst_brkm(TBROK | TERRNO, cleanup, "opendir()");
117
118 dir_fd = dirfd(dir);
119
120 if (dir_fd == -1)
121 tst_brkm(TBROK | TERRNO, cleanup, "dirfd()");
122
123 errno = 0;
124
125 while ((file = readdir(dir))) {
126 if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, ".."))
127 continue;
128
129 fd = atoi(file->d_name);
130
131 if (fd == dir_fd)
132 continue;
133
134 if (rec_fds_max >= ARRAY_SIZE(rec_fds)) {
135 tst_brkm(TBROK, cleanup,
136 "Too much file descriptors open");
137 }
138
139 rec_fds[rec_fds_max++] = fd;
140 }
141
142 if (errno)
143 tst_brkm(TBROK | TERRNO, cleanup, "readdir()");
144
145 closedir(dir);
146
147 tst_resm(TINFO, "Found %u files open", rec_fds_max);
148}
149
150static int not_recorded(int fd)
151{
152 int i;
153
154 for (i = 0; i < rec_fds_max; i++)
155 if (fd == rec_fds[i])
156 return 0;
157
158 return 1;
159}
160
161static void close_test_fds(int max_fd)
162{
163 int i;
164
165 for (i = 0; i <= max_fd; i++) {
166 if (not_recorded(i)) {
167 if (close(i)) {
168 if (errno == EBADF)
169 continue;
170 tst_resm(TWARN | TERRNO, "close(%i)", i);
171 }
172 }
173 }
174}
175
176static void cleanup(void)
177{
Chris Dearmanec6edca2012-10-17 19:54:01 -0700178}