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 
     57 char *TCID = "dup202";
     58 int TST_TOTAL = 3;
     59 
     60 void setup(void);
     61 void cleanup(void);
     62 
     63 char testfile[40];
     64 int fail;
     65 int newfd;
     66 
     67 /* set these to a known index into our local file descriptor table */
     68 int duprdo = 10, dupwro = 20, duprdwr = 30;
     69 
     70 struct test_case_t {
     71 	int *nfd;
     72 	mode_t mode;
     73 } TC[] = {
     74 	/* The first test creat(es) a file with mode 0444 */
     75 	{
     76 	&duprdo, (S_IRUSR | S_IRGRP | S_IROTH)},
     77 	    /* The second test creat(es) a file with mode 0222 */
     78 	{
     79 	&dupwro, (S_IWUSR | S_IWGRP | S_IWOTH)},
     80 	    /* The third test creat(es) a file with mode 0666 */
     81 	{
     82 	&duprdwr,
     83 		    (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH)}
     84 };
     85 
     86 int main(int ac, char **av)
     87 {
     88 	int lc;
     89 	int i, ofd;
     90 	struct stat oldbuf, newbuf;
     91 
     92 	tst_parse_opts(ac, av, NULL, NULL);
     93 
     94 	setup();
     95 
     96 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     97 
     98 		tst_count = 0;
     99 
    100 		/* loop through the test cases */
    101 		for (i = 0; i < TST_TOTAL; i++) {
    102 
    103 			if ((ofd = creat(testfile, TC[i].mode)) == -1)
    104 				tst_brkm(TBROK | TERRNO, cleanup,
    105 					 "creat failed");
    106 
    107 			TEST(dup2(ofd, *TC[i].nfd));
    108 
    109 			if (TEST_RETURN == -1) {
    110 				tst_resm(TFAIL | TERRNO,
    111 					 "call failed unexpectedly");
    112 				continue;
    113 			}
    114 
    115 			/* stat the original file */
    116 			if (fstat(ofd, &oldbuf) == -1)
    117 				tst_brkm(TBROK | TERRNO, cleanup,
    118 					 "fstat #1 failed");
    119 
    120 			/* stat the duped file */
    121 			if (fstat(*TC[i].nfd, &newbuf) == -1)
    122 				tst_brkm(TBROK | TERRNO, cleanup,
    123 					 "fstat #2 failed");
    124 
    125 			if (oldbuf.st_mode != newbuf.st_mode)
    126 				tst_resm(TFAIL, "original and dup "
    127 					 "modes do not match");
    128 			else
    129 				tst_resm(TPASS, "fstat shows new and "
    130 					 "old modes are the same");
    131 
    132 			/* remove the file so that we can use it again */
    133 			if (close(*TC[i].nfd) == -1)
    134 				perror("close failed");
    135 			if (close(ofd) == -1)
    136 				perror("close failed");
    137 			if (unlink(testfile) == -1)
    138 				perror("unlink failed");
    139 		}
    140 	}
    141 
    142 	cleanup();
    143 	tst_exit();
    144 }
    145 
    146 /*
    147  * setup() - performs all ONE TIME setup for this test.
    148  */
    149 void setup(void)
    150 {
    151 
    152 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    153 
    154 	TEST_PAUSE;
    155 
    156 	tst_tmpdir();
    157 
    158 	(void)umask(0);
    159 
    160 	sprintf(testfile, "dup202.%d", getpid());
    161 }
    162 
    163 /*
    164  * cleanup() - performs all ONE TIME cleanup for this test at
    165  *	       completion or premature exit.
    166  */
    167 void cleanup(void)
    168 {
    169 	tst_rmdir();
    170 }
    171