188 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * NAME
 | |
|  *	fcntl01.c
 | |
|  *
 | |
|  * DESCRIPTION
 | |
|  *	Test F_DUPFD, F_SETFL cmds of fcntl
 | |
|  *
 | |
|  * CALLS
 | |
|  *	fcntl
 | |
|  *
 | |
|  * ALGORITHM
 | |
|  *
 | |
|  *	1. Testing F_DUPFD cmd with arg less than, equal to, and greater
 | |
|  *	   than the next available file descriptor.
 | |
|  *
 | |
|  *	2. Checking F_SETFL cmd with each valid flag (O_NDELAY, O_APPEND).
 | |
|  *
 | |
|  *	3. Checking, setting and reading `close on exec' flag.
 | |
|  *
 | |
|  * USAGE
 | |
|  *	fcntl01
 | |
|  *
 | |
|  * HISTORY
 | |
|  *	07/2001 Ported by Wayne Boyer
 | |
|  *	09/2002 added fd2 array to remove statid fds
 | |
|  *
 | |
|  * RESTRICTIONS
 | |
|  *	None
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #include <fcntl.h>
 | |
| #include <errno.h>
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #include "test.h"
 | |
| 
 | |
| void setup(void);
 | |
| void cleanup(void);
 | |
| 
 | |
| char *TCID = "fcntl01";
 | |
| int TST_TOTAL = 1;
 | |
| 
 | |
| int main(int ac, char **av)
 | |
| {
 | |
| 	int flags;
 | |
| 	char fname[40];
 | |
| 	int fd[10], fd2[10];
 | |
| 	int mypid;
 | |
| 	unsigned int i;
 | |
| 	int lc;
 | |
| 
 | |
| 	tst_parse_opts(ac, av, NULL, NULL);
 | |
| 
 | |
| 	setup();
 | |
| 
 | |
| 	/* check for looping state if -i option is given */
 | |
| 	for (lc = 0; TEST_LOOPING(lc); lc++) {
 | |
| 
 | |
| 		tst_count = 0;
 | |
| 
 | |
| 		mypid = getpid();
 | |
| 		for (i = 0; i < 8; i++) {
 | |
| 			sprintf(fname, "./fcntl%d.%d", i, mypid);
 | |
| 			if ((fd[i] =
 | |
| 			     open(fname, O_WRONLY | O_CREAT, 0666)) == -1)
 | |
| 				tst_resm(TBROK | TERRNO, "open failed");
 | |
| 			fd2[i] = fd[i];
 | |
| 		}
 | |
| 
 | |
| 		close(fd[2]);
 | |
| 		close(fd[3]);
 | |
| 		close(fd[4]);
 | |
| 		close(fd[5]);
 | |
| 
 | |
| 		if ((fd[2] = fcntl(fd[1], F_DUPFD, 1)) == -1)
 | |
| 			tst_resm(TFAIL | TERRNO, "fcntl(.., 1) failed");
 | |
| 
 | |
| 		if (fd[2] < fd2[2])
 | |
| 			tst_resm(TFAIL, "new fd has unexpected value: "
 | |
| 				 "got %d, expected greater than %d", fd[2], 5);
 | |
| 
 | |
| 		if ((fd[4] = fcntl(fd[1], F_DUPFD, fd2[3])) < 0)
 | |
| 			tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[3]) failed");
 | |
| 
 | |
| 		if (fd[4] < fd2[3])
 | |
| 			tst_resm(TFAIL, "new fd has unexpected value, got %d, "
 | |
| 				 "expect greater than %d", fd[4], fd2[3]);
 | |
| 
 | |
| 		if ((fd[8] = fcntl(fd[1], F_DUPFD, fd2[5])) < 0)
 | |
| 			tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[5]) failed");
 | |
| 
 | |
| 		if (fd[8] != fd2[5])
 | |
| 			tst_resm(TFAIL, "new fd has unexpected value: "
 | |
| 				 "got %d, expected %d", fd[8], fd2[5]);
 | |
| /* //block1: */
 | |
| 		flags = fcntl(fd[2], F_GETFL, 0);
 | |
| 		if ((flags & O_WRONLY) == 0)
 | |
| 			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
 | |
| 				 flags, O_WRONLY);
 | |
| 
 | |
| 		/* Check setting of no_delay flag */
 | |
| 		if (fcntl(fd[2], F_SETFL, O_NDELAY) == -1)
 | |
| 			tst_resm(TBROK | TERRNO, "fcntl(.., O_NDELAY) failed");
 | |
| 
 | |
| 		flags = fcntl(fd[2], F_GETFL, 0);
 | |
| 		if ((flags & (O_NDELAY | O_WRONLY)) == 0)
 | |
| 			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
 | |
| 				 flags, O_NDELAY | O_WRONLY);
 | |
| 
 | |
| 		/* Check of setting append flag */
 | |
| 		if (fcntl(fd[2], F_SETFL, O_APPEND) == -1)
 | |
| 			tst_resm(TFAIL | TERRNO, "fcntl(.., O_APPEND) failed");
 | |
| 
 | |
| 		flags = fcntl(fd[2], F_GETFL, 0);
 | |
| 		if ((flags & (O_APPEND | O_WRONLY)) == 0)
 | |
| 			tst_resm(TFAIL, "unexpected flag ox%x, expected 0x%x",
 | |
| 				 flags, O_APPEND | O_WRONLY);
 | |
| 
 | |
| 		/* Check setting flags together */
 | |
| 		if (fcntl(fd[2], F_SETFL, O_NDELAY | O_APPEND) < 0)
 | |
| 			tst_resm(TFAIL, "fcntl(.., O_NDELAY|O_APPEND) failed");
 | |
| 
 | |
| 		flags = fcntl(fd[2], F_GETFL, 0);
 | |
| 		if ((flags & (O_NDELAY | O_APPEND | O_WRONLY)) == 0)
 | |
| 			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
 | |
| 				 flags,
 | |
| 				 O_NDELAY | O_APPEND | O_SYNC | O_WRONLY);
 | |
| 
 | |
| 		/* Check that flags are not cummulative */
 | |
| 		if (fcntl(fd[2], F_SETFL, 0) == -1)
 | |
| 			tst_resm(TFAIL, "fcntl(.., 0) failed");
 | |
| 
 | |
| 		flags = fcntl(fd[2], F_GETFL, 0);
 | |
| 		if ((flags & O_WRONLY) == 0)
 | |
| 			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
 | |
| 				 flags, O_WRONLY);
 | |
| 
 | |
| /* //block2: */
 | |
| 		/*
 | |
| 		 * Check ability to set (F_SETFD) the close on exec flag
 | |
| 		 */
 | |
| 		if ((flags = fcntl(fd[2], F_GETFD, 0)) < 0)
 | |
| 			tst_resm(TFAIL | TERRNO,
 | |
| 				 "fcntl(.., F_GETFD, ..) #1 failed");
 | |
| 		if (flags != 0)
 | |
| 			tst_resm(TFAIL, "unexpected flags got 0x%x expected "
 | |
| 				 "0x%x", flags, 0);
 | |
| 		if ((flags = fcntl(fd[2], F_SETFD, 1)) == -1)
 | |
| 			tst_resm(TFAIL, "fcntl(.., F_SETFD, ..) failed");
 | |
| 		if ((flags = fcntl(fd[2], F_GETFD, 0)) == -1)
 | |
| 			tst_resm(TFAIL | TERRNO,
 | |
| 				 "fcntl(.., F_GETFD, ..) #2 failed");
 | |
| 		if (flags != 1)
 | |
| 			tst_resm(TFAIL, "unexpected flags, got 0x%x, "
 | |
| 				 "expected 0x%x", flags, 1);
 | |
| 
 | |
| 		for (i = 0; i < ARRAY_SIZE(fd); i++)
 | |
| 			close(fd[i]);
 | |
| 		for (i = 0; i < 8; i++) {
 | |
| 			sprintf(fname, "./fcntl%u.%d", i, mypid);
 | |
| 			if ((unlink(fname)) == -1)
 | |
| 				tst_resm(TFAIL | TERRNO,
 | |
| 					 "unlinking %s failed", fname);
 | |
| 		}
 | |
| 	}
 | |
| 	cleanup();
 | |
| 	tst_exit();
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * setup
 | |
|  *	performs all ONE TIME setup for this test
 | |
|  */
 | |
| void setup(void)
 | |
| {
 | |
| 	tst_sig(FORK, DEF_HANDLER, cleanup);
 | |
| 	umask(0);
 | |
| 	TEST_PAUSE;
 | |
| 	tst_tmpdir();
 | |
| }
 | |
| 
 | |
| void cleanup(void)
 | |
| {
 | |
| 	tst_rmdir();
 | |
| 
 | |
| }
 |