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
main(int ac,char ** av)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 */
setup(void)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 */
setup2(void)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 */
cleanup(void)223 void cleanup(void)
224 {
225
226 /*
227 * Remove the temporary directory.
228 */
229 tst_rmdir();
230 }
231