Home | History | Annotate | Download | only in dup2
      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  * NAME
     22  *	dup202.c
     23  *
     24  * DESCRIPTION
     25  *	Is the access mode the same for both file descriptors?
     26  *		0: read only ?	"0444"
     27  *		1: write only ? "0222"
     28  *		2: read/write ? "0666"
     29  *
     30  * ALGORITHM
     31  *	Creat a file with each access mode; dup each file descriptor;
     32  *	stat each file descriptor and compare modes of each pair
     33  *
     34  * USAGE:  <for command-line>
     35  *  dup202 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
     36  *     where,  -c n : Run n copies concurrently.
     37  *             -f   : Turn off functionality Testing.
     38  *             -i n : Execute test n times.
     39  *             -I x : Execute test for x seconds.
     40  *             -P x : Pause for x seconds between iterations.
     41  *             -t   : Turn on syscall timing.
     42  *
     43  * HISTORY
     44  *	07/2001 Ported by Wayne Boyer
     45  *
     46  * RESTRICTIONS
     47  *	None
     48  */
     49 
     50 #include <sys/types.h>
     51 #include <sys/stat.h>
     52 #include <errno.h>
     53 #include <fcntl.h>
     54 #include <stdio.h>
     55 #include "test.h"
     56 #include "safe_macros.h"
     57 
     58 char *TCID = "dup202";
     59 int TST_TOTAL = 3;
     60 
     61 void setup(void);
     62 void cleanup(void);
     63 
     64 char testfile[40];
     65 int fail;
     66 int newfd;
     67 
     68 /* set these to a known index into our local file descriptor table */
     69 int duprdo = 10, dupwro = 20, duprdwr = 30;
     70 
     71 struct test_case_t {
     72 	int *nfd;
     73 	mode_t mode;
     74 } TC[] = {
     75 	/* The first test creat(es) a file with mode 0444 */
     76 	{
     77 	&duprdo, (S_IRUSR | S_IRGRP | S_IROTH)},
     78 	    /* The second test creat(es) a file with mode 0222 */
     79 	{
     80 	&dupwro, (S_IWUSR | S_IWGRP | S_IWOTH)},
     81 	    /* The third test creat(es) a file with mode 0666 */
     82 	{
     83 	&duprdwr,
     84 		    (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH)}
     85 };
     86 
     87 int main(int ac, char **av)
     88 {
     89 	int lc;
     90 	int i, ofd;
     91 	struct stat oldbuf, newbuf;
     92 
     93 	tst_parse_opts(ac, av, NULL, NULL);
     94 
     95 	setup();
     96 
     97 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     98 
     99 		tst_count = 0;
    100 
    101 		/* loop through the test cases */
    102 		for (i = 0; i < TST_TOTAL; i++) {
    103 
    104 			if ((ofd = creat(testfile, TC[i].mode)) == -1)
    105 				tst_brkm(TBROK | TERRNO, cleanup,
    106 					 "creat failed");
    107 
    108 			TEST(dup2(ofd, *TC[i].nfd));
    109 
    110 			if (TEST_RETURN == -1) {
    111 				tst_resm(TFAIL | TERRNO,
    112 					 "call failed unexpectedly");
    113 				continue;
    114 			}
    115 
    116 			/* stat the original file */
    117 			SAFE_FSTAT(cleanup, ofd, &oldbuf);
    118 
    119 			/* stat the duped file */
    120 			SAFE_FSTAT(cleanup, *TC[i].nfd, &newbuf);
    121 
    122 			if (oldbuf.st_mode != newbuf.st_mode)
    123 				tst_resm(TFAIL, "original and dup "
    124 					 "modes do not match");
    125 			else
    126 				tst_resm(TPASS, "fstat shows new and "
    127 					 "old modes are the same");
    128 
    129 			/* remove the file so that we can use it again */
    130 			if (close(*TC[i].nfd) == -1)
    131 				perror("close failed");
    132 			if (close(ofd) == -1)
    133 				perror("close failed");
    134 			if (unlink(testfile) == -1)
    135 				perror("unlink failed");
    136 		}
    137 	}
    138 
    139 	cleanup();
    140 	tst_exit();
    141 }
    142 
    143 /*
    144  * setup() - performs all ONE TIME setup for this test.
    145  */
    146 void setup(void)
    147 {
    148 
    149 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    150 
    151 	TEST_PAUSE;
    152 
    153 	tst_tmpdir();
    154 
    155 	(void)umask(0);
    156 
    157 	sprintf(testfile, "dup202.%d", getpid());
    158 }
    159 
    160 /*
    161  * cleanup() - performs all ONE TIME cleanup for this test at
    162  *	       completion or premature exit.
    163  */
    164 void cleanup(void)
    165 {
    166 	tst_rmdir();
    167 }
    168