Home | History | Annotate | Download | only in rename
      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  *	rename03
     23  *
     24  * DESCRIPTION
     25  *	This test will verify that rename(2) functions correctly
     26  *	when the "new" file or directory exists
     27  *
     28  * ALGORITHM
     29  *	Setup:
     30  *		Setup signal handling.
     31  *		Create temporary directory.
     32  *		Pause for SIGUSR1 if option specified.
     33  *
     34  *	Test:
     35  *		Loop if the proper options are given.
     36  *              1.  both old and new file exist
     37  *                  create the "old" file and the "new" file
     38  *                  rename the "old" to the "new" file
     39  *                  verify the "new" file points to the "old" file
     40  *                  verify the "old" file does not exists
     41  *              2.  both old file and new directory exist
     42  *                  create the "old" and the "new" directory
     43  *                  rename the "old" to the "new" directory
     44  *                  verify the "new" points to the "old" directory
     45  *                  verify the "old" does not exists
     46  *	Cleanup:
     47  *		Print errno log and/or timing stats if options given
     48  *		Delete the temporary directory created.
     49  *
     50  * USAGE
     51  *	rename03 [-c n] [-f] [-i n] [-I x] [-p x] [-t]
     52  *	where,  -c n : Run n copies concurrently.
     53  *		-f   : Turn off functionality Testing.
     54  *		-i n : Execute test n times.
     55  *		-I x : Execute test for x seconds.
     56  *		-P x : Pause for x seconds between iterations.
     57  *		-t   : Turn on syscall timing.
     58  *
     59  * HISTORY
     60  *	07/2001 Ported by Wayne Boyer
     61  *
     62  * RESTRICTIONS
     63  *	None.
     64  */
     65 #include <sys/types.h>
     66 #include <fcntl.h>
     67 #include <sys/stat.h>
     68 #include <unistd.h>
     69 #include <errno.h>
     70 
     71 #include "test.h"
     72 #include "safe_macros.h"
     73 
     74 void setup();
     75 void setup2();
     76 void cleanup();
     77 
     78 char *TCID = "rename03";
     79 int TST_TOTAL = 2;
     80 
     81 char fname[255], mname[255];
     82 char fdir[255], mdir[255];
     83 struct stat buf1, buf2;
     84 dev_t f_olddev, d_olddev;
     85 ino_t f_oldino, d_oldino;
     86 
     87 struct test_case_t {
     88 	char *name1;
     89 	char *name2;
     90 	char *desc;
     91 	dev_t *olddev;
     92 	ino_t *oldino;
     93 } TC[] = {
     94 	{
     95 	fname, mname, "file", &f_olddev, &f_oldino}, {
     96 	fdir, mdir, "directory", &d_olddev, &d_oldino}
     97 };
     98 
     99 int main(int ac, char **av)
    100 {
    101 	int lc;
    102 	int i;
    103 
    104 	/*
    105 	 * parse standard options
    106 	 */
    107 	tst_parse_opts(ac, av, NULL, NULL);
    108 	/*
    109 	 * perform global setup for test
    110 	 */
    111 	setup();
    112 
    113 	/*
    114 	 * check looping state if -i option given
    115 	 */
    116 	for (lc = 0; TEST_LOOPING(lc); lc++) {
    117 
    118 		tst_count = 0;
    119 
    120 		/* set up the files and directories for the tests */
    121 		setup2();
    122 
    123 		/* loop through the test cases */
    124 		for (i = 0; i < TST_TOTAL; i++) {
    125 
    126 			TEST(rename(TC[i].name1, TC[i].name2));
    127 
    128 			if (TEST_RETURN == -1) {
    129 				tst_resm(TFAIL, "call failed unexpectedly");
    130 				continue;
    131 			}
    132 
    133 			SAFE_STAT(cleanup, TC[i].name2, &buf2);
    134 
    135 			/*
    136 			 * verify the new file or directory is the
    137 			 * same as the old one
    138 			 */
    139 			if (buf2.st_dev != *TC[i].olddev ||
    140 			    buf2.st_ino != *TC[i].oldino) {
    141 				tst_resm(TFAIL, "rename() failed: the "
    142 					 "new %s points to a different "
    143 					 "inode/location", TC[i].desc);
    144 				continue;
    145 			}
    146 			/*
    147 			 * verify that the old file or directory
    148 			 * does not exist
    149 			 */
    150 			if (stat(fname, &buf2) != -1) {
    151 				tst_resm(TFAIL, "the old %s still "
    152 					 "exists", TC[i].desc);
    153 				continue;
    154 			}
    155 
    156 			tst_resm(TPASS, "functionality is correct "
    157 				 "for renaming a %s", TC[i].desc);
    158 		}
    159 
    160 		/* reset things in case we are looping */
    161 
    162 		/* unlink the new file */
    163 		SAFE_UNLINK(cleanup, mname);
    164 
    165 		/* remove the new directory */
    166 		SAFE_RMDIR(cleanup, mdir);
    167 	}
    168 
    169 	cleanup();
    170 	tst_exit();
    171 
    172 }
    173 
    174 /*
    175  * setup() - performs all ONE TIME setup for this test.
    176  */
    177 void setup(void)
    178 {
    179 
    180 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    181 
    182 	TEST_PAUSE;
    183 
    184 	/* Create a temporary directory and make it current. */
    185 	tst_tmpdir();
    186 
    187 	sprintf(fname, "./tfile_%d", getpid());
    188 	sprintf(mname, "./rnfile_%d", getpid());
    189 	sprintf(fdir, "./tdir_%d", getpid());
    190 	sprintf(mdir, "./rndir_%d", getpid());
    191 }
    192 
    193 /*
    194  * setup2() - set up the files and directories for the tests
    195  */
    196 void setup2(void)
    197 {
    198 	SAFE_TOUCH(cleanup, fname, 0700, NULL);
    199 
    200 	SAFE_STAT(cleanup, fname, &buf1);
    201 
    202 	/* save original file's dev and ino */
    203 	f_olddev = buf1.st_dev;
    204 	f_oldino = buf1.st_ino;
    205 
    206 	SAFE_TOUCH(cleanup, mname, 0700, NULL);
    207 
    208 	/* create "old" directory */
    209 	SAFE_MKDIR(cleanup, fdir, 00770);
    210 	SAFE_STAT(cleanup, fdir, &buf1);
    211 
    212 	d_olddev = buf1.st_dev;
    213 	d_oldino = buf1.st_ino;
    214 
    215 	/* create another directory */
    216 	SAFE_MKDIR(cleanup, mdir, 00770);
    217 }
    218 
    219 /*
    220  * cleanup() - performs all ONE TIME cleanup for this test at
    221  *             completion or premature exit.
    222  */
    223 void cleanup(void)
    224 {
    225 
    226 	/*
    227 	 * Remove the temporary directory.
    228 	 */
    229 	tst_rmdir();
    230 }
    231