blob: 2de03ccba8bb7bc98bc2c09eb375df90ad19bad8 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * NAME
22 * getcwd03
23 *
24 * DESCRIPTION
25 * Testcase to check the basic functionality of the getcwd(2) system call
26 * for symbolically linked directories.
27 *
28 * ALGORITHM
29 * This testcase checks for the functionality of the getcwd(2) system call
30 * on a symbolic link. First create a directory (dir1), and create a
31 * symbolic link (dir2) to it at the same directory level. Then, chdir()
32 * to dir1, and get the working directory (cwd1), and its pathname (pwd1).
33 * Then, chdir() to dir2, and get the working directory (cwd2), its
34 * pathname (pwd2), and its readlink info (link2).
35 * Testcase succeeds if:
36 * i. pwd1 == pwd2
37 * ii. cwd1 == cwd2
38 * iii. link2 == basename(cwd1)
39 *
40 * USAGE: <for command-line>
41 * getcwd03 [-c n] [-i n] [-I x] [-P x] [-t]
42 * where, -c n : Run n copies concurrently.
43 * -i n : Execute test n times.
44 * -I x : Execute test for x seconds.
45 * -P x : Pause for x seconds between iterations.
46 * -t : Turn on syscall timing.
47 *
48 * HISTORY
49 * 07/2001 Ported by Wayne Boyer
50 *
51 * RESTRICTIONS
52 * NONE
53 */
robbiew1d27cce2002-04-03 15:44:30 +000054#define _GNU_SOURCE 1
plars865695b2001-08-27 22:15:12 +000055#include <stdio.h>
56#include <string.h>
57#include <errno.h>
Garrett Coopere8530df2010-12-21 11:37:57 -080058#include "test.h"
robbiew1d27cce2002-04-03 15:44:30 +000059#include <stdlib.h>
robbiew5832f9b2002-08-12 14:57:23 +000060#include <sys/stat.h>
61#include <sys/types.h>
62#include <stdlib.h>
plars865695b2001-08-27 22:15:12 +000063#define FAILED 1
64
65int flag;
66char *TCID = "getcwd03";
67int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000068
69void cleanup(void);
70void setup(void);
Mike Frysinger7f825dd2013-03-11 15:36:25 -040071char *getpwd(void);
plars865695b2001-08-27 22:15:12 +000072
subrata_modak56207ce2009-03-23 13:35:39 +000073int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000074{
75 char dir1[BUFSIZ], dir2[BUFSIZ];
76 char cwd1[BUFSIZ], cwd2[BUFSIZ];
77 char *pwd1, *pwd2;
78 char link2[BUFSIZ];
79 int n;
Cyril Hrubis89af32a2012-10-24 16:39:11 +020080 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020081 const char *msg; /* parse_opts() return message */
plars865695b2001-08-27 22:15:12 +000082
Garrett Cooper45e285d2010-11-22 12:19:25 -080083 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -080084 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +000085 }
86
87 setup();
88
89 /*
90 * The following loop checks looping state if -i option given
91 */
92 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +080093 tst_count = 0;
plars865695b2001-08-27 22:15:12 +000094
95 flag = 0;
96
97 /*
98 * Create dir1, then chdir to dir1, and get the pwd,
99 * and cwd informations
100 */
101 sprintf(dir1, "getcwd1.%d", getpid());
102 if (mkdir(dir1, 00755) < 0) {
103 tst_brkm(TBROK, cleanup, "mkdir(2) failed");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800104 }
plars865695b2001-08-27 22:15:12 +0000105 if (chdir(dir1) != 0) {
106 tst_brkm(TBROK, cleanup, "chdir(2) failed");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800107 }
plars865695b2001-08-27 22:15:12 +0000108
109 pwd1 = getpwd();
110 if (getcwd(cwd1, sizeof cwd1) == NULL) {
Mike Frysingera3127592013-03-20 17:31:05 -0400111 tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly");
plars865695b2001-08-27 22:15:12 +0000112 flag = FAILED;
113 }
114 if ((flag != FAILED) && (strcmp(pwd1, cwd1) != 0)) {
115 tst_brkm(TFAIL, cleanup, "getcwd() returned unexpected "
116 "working directory: expected: %s, got: %s\n",
117 pwd1, cwd1);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800118 }
plars865695b2001-08-27 22:15:12 +0000119
120 tst_resm(TINFO, "getcwd(2) succeeded in returning correct path "
121 "for dir1");
122
123 /*
124 * Now create dir2, then chdir to dir2, and get the pwd,
125 * cwd, and link informations
126 */
127 chdir("..");
128 flag = 0;
129
130 sprintf(dir2, "getcwd2.%d", getpid());
131 if (symlink(dir1, dir2) < 0) {
132 tst_brkm(TBROK, cleanup, "symlink(2) failed: errno: %d",
133 errno);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800134 }
plars865695b2001-08-27 22:15:12 +0000135
136 if (chdir(dir2) != 0) {
137 tst_brkm(TBROK, cleanup, "chdir(2) failed: errno: %d",
138 errno);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800139 }
plars865695b2001-08-27 22:15:12 +0000140
141 pwd2 = getpwd();
142 if (getcwd(cwd2, sizeof cwd2) == NULL) {
Mike Frysingera3127592013-03-20 17:31:05 -0400143 tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly");
plars865695b2001-08-27 22:15:12 +0000144 flag = FAILED;
145 }
146
147 chdir("..");
148 if ((flag != FAILED) &&
149 ((n = readlink(dir2, link2, sizeof(link2))) < 0)) {
150 tst_brkm(TBROK, cleanup, "readlink(2) failed: errno:%d",
151 errno);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800152 }
plars865695b2001-08-27 22:15:12 +0000153
154 /*
155 * Finally compare the pwd, cwd, link informations:
156 * The test should pass iff all the following are true:
subrata_modak56207ce2009-03-23 13:35:39 +0000157 * a. pwd1 == pwd2
158 * b. cwd1 == cwd2
159 * c. link2 == basename(cwd1)
plars865695b2001-08-27 22:15:12 +0000160 */
161 if (flag != FAILED) {
162 if (strcmp(pwd1, pwd2) != 0) {
163 tst_resm(TFAIL, "pwd1: %s, pwd2: %s",
164 pwd1, pwd2);
165 flag = FAILED;
166 }
167 if (strcmp(cwd1, cwd2) != 0) {
168 tst_resm(TFAIL, "cwd1: %s, cwd2: %s",
169 cwd1, cwd2);
170 flag = FAILED;
171 }
172 if (memcmp(link2, (char *)basename(cwd1), n) != 0) {
173 tst_resm(TFAIL, "link2: %s, cwd1: %s",
174 link2, cwd1);
175 flag = FAILED;
176 }
177 if (flag != FAILED) {
178 tst_resm(TINFO, "getcwd(2) succeeded in "
179 "returning correct path for symbolic "
180 "link dir2 -> dir1");
181 }
182 }
183
184 if (flag == FAILED) {
185 tst_resm(TFAIL, "Test FAILED");
186 } else {
187 tst_resm(TPASS, "Test PASSED");
188 }
189
190 /* clean up things in case we are looping */
191 if (unlink(dir2) == -1) {
192 tst_brkm(TBROK, cleanup, "couldnt remove dir2");
193 }
194 if (rmdir(dir1) == -1) {
195 tst_brkm(TBROK, cleanup, "couldnt remove dir1");
196 }
197 }
198 cleanup();
199
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800200 tst_exit();
plars865695b2001-08-27 22:15:12 +0000201}
202
Mike Frysinger7f825dd2013-03-11 15:36:25 -0400203void setup(void)
plars865695b2001-08-27 22:15:12 +0000204{
plars865695b2001-08-27 22:15:12 +0000205 /* FORK is set here because of the popen() call below */
206 tst_sig(FORK, DEF_HANDLER, cleanup);
207
plars865695b2001-08-27 22:15:12 +0000208 TEST_PAUSE;
209
210 /* create a test directory and cd into it */
211 tst_tmpdir();
212}
213
Mike Frysinger7f825dd2013-03-11 15:36:25 -0400214void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000215{
216 /* remove the test directory */
217 tst_rmdir();
plars865695b2001-08-27 22:15:12 +0000218}
219
Mike Frysinger7f825dd2013-03-11 15:36:25 -0400220char *getpwd(void)
plars865695b2001-08-27 22:15:12 +0000221{
robbiew89577252004-01-05 20:15:51 +0000222 FILE *fin;
plars865695b2001-08-27 22:15:12 +0000223 char *pwd = "/bin/pwd";
Mike Frysingera3127592013-03-20 17:31:05 -0400224 char *cp;
plars865695b2001-08-27 22:15:12 +0000225 char *buf;
226
Cyril Hrubisd218f342014-09-23 13:14:56 +0200227 buf = malloc(BUFSIZ);
plars865695b2001-08-27 22:15:12 +0000228 if ((fin = popen(pwd, "r")) == NULL) {
vapiercff4af02006-02-11 04:46:30 +0000229 tst_resm(TINFO, "%s: can't run %s", TCID, pwd);
plars865695b2001-08-27 22:15:12 +0000230 tst_brkm(TBROK, cleanup, "%s FAILED", TCID);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800231 }
plars865695b2001-08-27 22:15:12 +0000232 while (fgets(buf, BUFSIZ, fin) != NULL) {
Garrett Cooper45e285d2010-11-22 12:19:25 -0800233 if ((cp = strchr(buf, '\n')) == NULL) {
plars865695b2001-08-27 22:15:12 +0000234 tst_brkm(TBROK, cleanup, "pwd output too long");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800235 }
plars865695b2001-08-27 22:15:12 +0000236 *cp = 0;
plars865695b2001-08-27 22:15:12 +0000237 }
238 pclose(fin);
239 return buf;
Chris Dearmanec6edca2012-10-17 19:54:01 -0700240}