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 <sys/fcntl.h> 67#include <sys/stat.h> 68#include <unistd.h> 69#include <errno.h> 70 71#include "test.h" 72 73void setup(); 74void setup2(); 75void cleanup(); 76 77char *TCID = "rename03"; 78int TST_TOTAL = 2; 79 80char fname[255], mname[255]; 81char fdir[255], mdir[255]; 82struct stat buf1, buf2; 83dev_t f_olddev, d_olddev; 84ino_t f_oldino, d_oldino; 85 86struct test_case_t { 87 char *name1; 88 char *name2; 89 char *desc; 90 dev_t *olddev; 91 ino_t *oldino; 92} TC[] = { 93 { 94 fname, mname, "file", &f_olddev, &f_oldino}, { 95 fdir, mdir, "directory", &d_olddev, &d_oldino} 96}; 97 98int main(int ac, char **av) 99{ 100 int lc; 101 int i; 102 103 /* 104 * parse standard options 105 */ 106 tst_parse_opts(ac, av, NULL, NULL); 107 /* 108 * perform global setup for test 109 */ 110 setup(); 111 112 /* 113 * check looping state if -i option given 114 */ 115 for (lc = 0; TEST_LOOPING(lc); lc++) { 116 117 tst_count = 0; 118 119 /* set up the files and directories for the tests */ 120 setup2(); 121 122 /* loop through the test cases */ 123 for (i = 0; i < TST_TOTAL; i++) { 124 125 TEST(rename(TC[i].name1, TC[i].name2)); 126 127 if (TEST_RETURN == -1) { 128 tst_resm(TFAIL, "call failed unexpectedly"); 129 continue; 130 } 131 132 if (stat(TC[i].name2, &buf2) == -1) { 133 tst_brkm(TBROK, cleanup, "stat of %s " 134 "failed", TC[i].desc); 135 136 } 137 138 /* 139 * verify the new file or directory is the 140 * same as the old one 141 */ 142 if (buf2.st_dev != *TC[i].olddev || 143 buf2.st_ino != *TC[i].oldino) { 144 tst_resm(TFAIL, "rename() failed: the " 145 "new %s points to a different " 146 "inode/location", TC[i].desc); 147 continue; 148 } 149 /* 150 * verify that the old file or directory 151 * does not exist 152 */ 153 if (stat(fname, &buf2) != -1) { 154 tst_resm(TFAIL, "the old %s still " 155 "exists", TC[i].desc); 156 continue; 157 } 158 159 tst_resm(TPASS, "functionality is correct " 160 "for renaming a %s", TC[i].desc); 161 } 162 163 /* reset things in case we are looping */ 164 165 /* unlink the new file */ 166 if (unlink(mname) == -1) { 167 tst_brkm(TBROK, cleanup, "unlink() failed"); 168 } 169 170 /* remove the new directory */ 171 if (rmdir(mdir) == -1) { 172 tst_brkm(TBROK, cleanup, "Couldn't remove directory %s", 173 mdir); 174 } 175 } 176 177 cleanup(); 178 tst_exit(); 179 180} 181 182/* 183 * setup() - performs all ONE TIME setup for this test. 184 */ 185void setup(void) 186{ 187 188 tst_sig(NOFORK, DEF_HANDLER, cleanup); 189 190 TEST_PAUSE; 191 192 /* Create a temporary directory and make it current. */ 193 tst_tmpdir(); 194 195 sprintf(fname, "./tfile_%d", getpid()); 196 sprintf(mname, "./rnfile_%d", getpid()); 197 sprintf(fdir, "./tdir_%d", getpid()); 198 sprintf(mdir, "./rndir_%d", getpid()); 199} 200 201/* 202 * setup2() - set up the files and directories for the tests 203 */ 204void setup2(void) 205{ 206 SAFE_TOUCH(cleanup, fname, 0700, NULL); 207 208 if (stat(fname, &buf1) == -1) { 209 tst_brkm(TBROK, cleanup, "failed to stat file %s" 210 "in rename()", fname); 211 212 } 213 214 /* save original file's dev and ino */ 215 f_olddev = buf1.st_dev; 216 f_oldino = buf1.st_ino; 217 218 SAFE_TOUCH(cleanup, mname, 0700, NULL); 219 220 /* create "old" directory */ 221 if (mkdir(fdir, 00770) == -1) { 222 tst_brkm(TBROK, cleanup, "Could not create directory %s", fdir); 223 } 224 if (stat(fdir, &buf1) == -1) { 225 tst_brkm(TBROK, cleanup, "failed to stat directory %s" 226 "in rename()", fdir); 227 228 } 229 230 d_olddev = buf1.st_dev; 231 d_oldino = buf1.st_ino; 232 233 /* create another directory */ 234 if (mkdir(mdir, 00770) == -1) { 235 tst_brkm(TBROK, cleanup, "Could not create directory %s", mdir); 236 } 237} 238 239/* 240 * cleanup() - performs all ONE TIME cleanup for this test at 241 * completion or premature exit. 242 */ 243void cleanup(void) 244{ 245 246 /* 247 * Remove the temporary directory. 248 */ 249 tst_rmdir(); 250} 251