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