• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2001
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /*
21  * DESCRIPTION
22  *	Testcase to check that open(2) sets EMFILE if a process opens files
23  *	more than its descriptor size
24  *
25  * ALGORITHM
26  *	First get the file descriptor table size which is set for a process.
27  *	Use open(2) for creating files till the descriptor table becomes full.
28  *	These open(2)s should succeed. Finally use open(2) to open another
29  *	file. This attempt should fail with EMFILE.
30  */
31 
32 #include <stdio.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include "test.h"
37 
38 char *TCID = "open04";
39 int TST_TOTAL = 1;
40 
41 static int fd, ifile, mypid, first;
42 static int nfile;
43 static int *buf;
44 static char fname[40];
45 
46 static void setup(void);
47 static void cleanup(void);
48 
main(int ac,char ** av)49 int main(int ac, char **av)
50 {
51 	int lc;
52 
53 	tst_parse_opts(ac, av, NULL, NULL);
54 
55 	setup();
56 
57 	for (lc = 0; TEST_LOOPING(lc); lc++) {
58 		tst_count = 0;
59 
60 		TEST(open(fname, O_RDWR | O_CREAT, 0777));
61 
62 		if (TEST_RETURN != -1) {
63 			tst_resm(TFAIL, "call succeeded unexpectedly");
64 			continue;
65 		}
66 
67 		if (TEST_ERRNO != EMFILE)
68 			tst_resm(TFAIL, "Expected EMFILE, got %d", TEST_ERRNO);
69 		else
70 			tst_resm(TPASS, "call returned expected EMFILE error");
71 	}
72 
73 	close(first);
74 	close(fd);
75 	cleanup();
76 	tst_exit();
77 }
78 
setup(void)79 static void setup(void)
80 {
81 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
82 
83 	TEST_PAUSE;
84 
85 	/* make a temporary directory and cd to it */
86 	tst_tmpdir();
87 
88 	mypid = getpid();
89 	nfile = getdtablesize();
90 	sprintf(fname, "open04.%d", mypid);
91 
92 	first = fd = open(fname, O_RDWR | O_CREAT, 0777);
93 	if (first == -1)
94 		tst_brkm(TBROK, cleanup, "Cannot open first file");
95 
96 	close(fd);
97 	close(first);
98 	unlink(fname);
99 
100 	/* Allocate memory for stat and ustat structure variables */
101 	buf = malloc(sizeof(int) * nfile - first);
102 	if (buf == NULL)
103 		tst_brkm(TBROK, NULL, "Failed to allocate Memory");
104 
105 	for (ifile = first; ifile <= nfile; ifile++) {
106 		sprintf(fname, "open04.%d.%d", ifile, mypid);
107 		fd = open(fname, O_RDWR | O_CREAT, 0777);
108 		if (fd == -1) {
109 			if (errno != EMFILE) {
110 				tst_brkm(TBROK, cleanup, "Expected EMFILE got "
111 					 "%d", errno);
112 			}
113 			break;
114 		}
115 		buf[ifile - first] = fd;
116 	}
117 }
118 
cleanup(void)119 static void cleanup(void)
120 {
121 	close(first);
122 
123 	for (ifile = first; ifile < nfile; ifile++) {
124 		sprintf(fname, "open04.%d.%d", ifile, mypid);
125 		close(buf[ifile - first]);
126 		unlink(fname);
127 	}
128 
129 	free(buf);
130 
131 	/* delete the test directory created in setup() */
132 	tst_rmdir();
133 }
134