Home | History | Annotate | Download | only in dup2
      1 /*
      2  *
      3  *   Copyright (c) International Business Machines  Corp., 2002
      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 /* Ported from SPIE, section2/iosuite/dup6.c, by Airong Zhang */
     21 
     22 /*======================================================================
     23 	=================== TESTPLAN SEGMENT ===================
     24 >KEYS:  < dup2()
     25 >WHAT:  < Does dup return -1 on the 21st file?
     26 >HOW:   < Create up to _NFILE files and check for -1 return on the
     27 	< next attempt
     28 	< Should check NOFILE as well as _NFILE.  19-Jun-84 Dale.
     29 >BUGS:  <
     30 ======================================================================*/
     31 
     32 #include <sys/param.h>
     33 #include <sys/types.h>
     34 #include <sys/stat.h>
     35 #include <errno.h>
     36 #include <fcntl.h>
     37 #include <stdio.h>
     38 #include <unistd.h>
     39 #include "test.h"
     40 
     41 char *TCID = "dup205";
     42 int TST_TOTAL = 1;
     43 int *fildes;
     44 int min;
     45 int local_flag;
     46 
     47 #define PASSED 1
     48 #define FAILED 0
     49 
     50 static void setup(void);
     51 static void cleanup(void);
     52 
     53 int main(int ac, char *av[])
     54 {
     55 	int ifile;
     56 	char pfilname[40];
     57 	int serrno;
     58 
     59 	int lc;
     60 
     61 	ifile = -1;
     62 
     63 	tst_parse_opts(ac, av, NULL, NULL);
     64 
     65 	local_flag = PASSED;
     66 
     67 	setup();
     68 
     69 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     70 
     71 		sprintf(pfilname, "./dup205.%d\n", getpid());
     72 		unlink(pfilname);
     73 		serrno = 0;
     74 		if ((fildes[0] = creat(pfilname, 0666)) == -1)
     75 			tst_brkm(TBROK | TERRNO, cleanup, "creat failed");
     76 		else {
     77 			fildes[fildes[0]] = fildes[0];
     78 			for (ifile = fildes[0] + 1; ifile < min + 10; ifile++) {
     79 				if ((fildes[ifile] = dup2(fildes[ifile - 1],
     80 							  ifile)) == -1) {
     81 					serrno = errno;
     82 					break;
     83 				} else {
     84 					if (fildes[ifile] != ifile) {
     85 						tst_brkm(TFAIL, cleanup,
     86 							 "got wrong descriptor "
     87 							 "number back (%d != %d)",
     88 							 fildes[ifile], ifile);
     89 					}
     90 				}
     91 			}	/* end for */
     92 			if (ifile < min) {
     93 				tst_resm(TFAIL, "Not enough files duped");
     94 				local_flag = FAILED;
     95 			} else if (ifile > min) {
     96 				tst_resm(TFAIL, "Too many files duped");
     97 				local_flag = FAILED;
     98 			}
     99 			if (serrno != EBADF && serrno != EMFILE &&
    100 			    serrno != EINVAL) {
    101 				tst_resm(TFAIL, "bad errno on dup2 failure");
    102 				local_flag = FAILED;
    103 			}
    104 		}
    105 		unlink(pfilname);
    106 		for (ifile = fildes[0]; ifile < min + 10; ifile++)
    107 			close(fildes[ifile]);
    108 		if (local_flag == PASSED) {
    109 			tst_resm(TPASS, "Test passed.");
    110 		} else {
    111 			tst_resm(TFAIL, "Test failed.");
    112 		}
    113 
    114 	}
    115 	cleanup();
    116 	tst_exit();
    117 }
    118 
    119 static void setup(void)
    120 {
    121 	tst_tmpdir();
    122 
    123 	min = getdtablesize();	/* get number of files allowed open */
    124 	fildes = malloc((min + 10) * sizeof(int));
    125 	if (fildes == NULL)
    126 		tst_brkm(TBROK | TERRNO, cleanup, "malloc error");
    127 }
    128 
    129 static void cleanup(void)
    130 {
    131 	if (fildes != NULL)
    132 		free(fildes);
    133 	tst_rmdir();
    134 }
    135