135 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  *
 | |
|  *   Copyright (c) International Business Machines  Corp., 2002
 | |
|  *
 | |
|  *   This program is free software;  you can redistribute it and/or modify
 | |
|  *   it under the terms of the GNU General Public License as published by
 | |
|  *   the Free Software Foundation; either version 2 of the License, or
 | |
|  *   (at your option) any later version.
 | |
|  *
 | |
|  *   This program is distributed in the hope that it will be useful,
 | |
|  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
 | |
|  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 | |
|  *   the GNU General Public License for more details.
 | |
|  *
 | |
|  *   You should have received a copy of the GNU General Public License
 | |
|  *   along with this program;  if not, write to the Free Software
 | |
|  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | |
|  */
 | |
| 
 | |
| /* Ported from SPIE, section2/iosuite/dup6.c, by Airong Zhang */
 | |
| 
 | |
| /*======================================================================
 | |
| 	=================== TESTPLAN SEGMENT ===================
 | |
| >KEYS:  < dup2()
 | |
| >WHAT:  < Does dup return -1 on the 21st file?
 | |
| >HOW:   < Create up to _NFILE files and check for -1 return on the
 | |
| 	< next attempt
 | |
| 	< Should check NOFILE as well as _NFILE.  19-Jun-84 Dale.
 | |
| >BUGS:  <
 | |
| ======================================================================*/
 | |
| 
 | |
| #include <sys/param.h>
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #include <errno.h>
 | |
| #include <fcntl.h>
 | |
| #include <stdio.h>
 | |
| #include <unistd.h>
 | |
| #include "test.h"
 | |
| 
 | |
| char *TCID = "dup205";
 | |
| int TST_TOTAL = 1;
 | |
| int *fildes;
 | |
| int min;
 | |
| int local_flag;
 | |
| 
 | |
| #define PASSED 1
 | |
| #define FAILED 0
 | |
| 
 | |
| static void setup(void);
 | |
| static void cleanup(void);
 | |
| 
 | |
| int main(int ac, char *av[])
 | |
| {
 | |
| 	int ifile;
 | |
| 	char pfilname[40];
 | |
| 	int serrno;
 | |
| 
 | |
| 	int lc;
 | |
| 
 | |
| 	ifile = -1;
 | |
| 
 | |
| 	tst_parse_opts(ac, av, NULL, NULL);
 | |
| 
 | |
| 	local_flag = PASSED;
 | |
| 
 | |
| 	setup();
 | |
| 
 | |
| 	for (lc = 0; TEST_LOOPING(lc); lc++) {
 | |
| 
 | |
| 		sprintf(pfilname, "./dup205.%d\n", getpid());
 | |
| 		unlink(pfilname);
 | |
| 		serrno = 0;
 | |
| 		if ((fildes[0] = creat(pfilname, 0666)) == -1)
 | |
| 			tst_brkm(TBROK | TERRNO, cleanup, "creat failed");
 | |
| 		else {
 | |
| 			fildes[fildes[0]] = fildes[0];
 | |
| 			for (ifile = fildes[0] + 1; ifile < min + 10; ifile++) {
 | |
| 				if ((fildes[ifile] = dup2(fildes[ifile - 1],
 | |
| 							  ifile)) == -1) {
 | |
| 					serrno = errno;
 | |
| 					break;
 | |
| 				} else {
 | |
| 					if (fildes[ifile] != ifile) {
 | |
| 						tst_brkm(TFAIL, cleanup,
 | |
| 							 "got wrong descriptor "
 | |
| 							 "number back (%d != %d)",
 | |
| 							 fildes[ifile], ifile);
 | |
| 					}
 | |
| 				}
 | |
| 			}	/* end for */
 | |
| 			if (ifile < min) {
 | |
| 				tst_resm(TFAIL, "Not enough files duped");
 | |
| 				local_flag = FAILED;
 | |
| 			} else if (ifile > min) {
 | |
| 				tst_resm(TFAIL, "Too many files duped");
 | |
| 				local_flag = FAILED;
 | |
| 			}
 | |
| 			if (serrno != EBADF && serrno != EMFILE &&
 | |
| 			    serrno != EINVAL) {
 | |
| 				tst_resm(TFAIL, "bad errno on dup2 failure");
 | |
| 				local_flag = FAILED;
 | |
| 			}
 | |
| 		}
 | |
| 		unlink(pfilname);
 | |
| 		for (ifile = fildes[0]; ifile < min + 10; ifile++)
 | |
| 			close(fildes[ifile]);
 | |
| 		if (local_flag == PASSED) {
 | |
| 			tst_resm(TPASS, "Test passed.");
 | |
| 		} else {
 | |
| 			tst_resm(TFAIL, "Test failed.");
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 	cleanup();
 | |
| 	tst_exit();
 | |
| }
 | |
| 
 | |
| static void setup(void)
 | |
| {
 | |
| 	tst_tmpdir();
 | |
| 
 | |
| 	min = getdtablesize();	/* get number of files allowed open */
 | |
| 	fildes = malloc((min + 10) * sizeof(int));
 | |
| 	if (fildes == NULL)
 | |
| 		tst_brkm(TBROK | TERRNO, cleanup, "malloc error");
 | |
| }
 | |
| 
 | |
| static void cleanup(void)
 | |
| {
 | |
| 	if (fildes != NULL)
 | |
| 		free(fildes);
 | |
| 	tst_rmdir();
 | |
| }
 |