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
73 void setup();
74 void setup2();
75 void cleanup();
76
77 char *TCID = "rename03";
78 int TST_TOTAL = 2;
79
80 char fname[255], mname[255];
81 char fdir[255], mdir[255];
82 struct stat buf1, buf2;
83 dev_t f_olddev, d_olddev;
84 ino_t f_oldino, d_oldino;
85
86 struct 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
main(int ac,char ** av)98 int 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 */
setup(void)185 void 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 */
setup2(void)204 void 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 */
cleanup(void)243 void cleanup(void)
244 {
245
246 /*
247 * Remove the temporary directory.
248 */
249 tst_rmdir();
250 }
251