Home | History | Annotate | Download | only in open
      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 
     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 
     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 
    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