xref: /minix3/minix/tests/test23.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1 /* test23: chdir(), getcwd()	Author: Jan-Mark Wams (jms@cs.vu.nl) */
2 
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <limits.h>
6 #include <errno.h>
7 #include <unistd.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <fcntl.h>
11 #include <stdio.h>
12 
13 int max_error = 4;
14 #include "common.h"
15 
16 #define ITERATIONS 3
17 
18 
19 #define System(cmd)	if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
20 #define Chdir(dir)	if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
21 
22 int subtest;
23 int superuser;			/* True if we are root. */
24 
25 char cwd[PATH_MAX];		/* Space for path names. */
26 char cwd2[PATH_MAX];
27 char buf[PATH_MAX];
28 char *MaxName;			/* Name of maximum length */
29 char MaxPath[PATH_MAX];		/* Same for path */
30 char *ToLongName;		/* Name of maximum +1 length */
31 char ToLongPath[PATH_MAX + 1];	/* Same for path, both too long */
32 
33 void test23a(void);
34 void test23b(void);
35 void test23c(void);
36 void makelongnames(void);
37 
main(int argc,char * argv[])38 int main(int argc, char *argv[])
39 {
40   int i, m = 0xFFFF;
41 
42   sync();
43   if (argc == 2) m = atoi(argv[1]);
44   start(23);
45   makelongnames();
46   superuser = (geteuid() == 0);
47 
48   for (i = 0; i < ITERATIONS; i++) {
49 	if (m & 0001) test23a();	/* Test normal operation */
50 	if (m & 0002) test23b();	/* Test critical operation */
51 	if (m & 0004) test23c();	/* Test error operation */
52   }
53 
54   quit();
55   return 1;
56 }
57 
test23a()58 void test23a()
59 {				/* Test normal operation. */
60   register int i;
61 
62   subtest = 1;
63 
64   System("rm -rf ../DIR_23/*");
65 
66   /* Let's do some fiddeling with path names. */
67   if (getcwd(cwd, PATH_MAX) != cwd) e(1);
68   if (chdir(cwd) != 0) e(2);
69   if (getcwd(buf, PATH_MAX) != buf) e(3);
70   if (strcmp(buf, cwd) != 0) e(4);
71   if (chdir(".") != 0) e(5);
72   if (getcwd(buf, PATH_MAX) != buf) e(6);
73   if (strcmp(buf, cwd) != 0) e(7);
74   if (chdir("./././.") != 0) e(8);
75   if (getcwd(buf, PATH_MAX) != buf) e(9);
76   if (strcmp(buf, cwd) != 0) e(10);
77 
78   /* Creat a working dir named "foo", remove any previous residues. */
79   System("rm -rf foo");
80   if (mkdir("foo", 0777) != 0) e(11);
81 
82   /* Do some more fiddeling with path names. */
83   if (chdir("foo/.././foo/..") != 0) e(12);	/* change to cwd */
84   if (getcwd(buf, PATH_MAX) != buf) e(13);
85   if (strcmp(buf, cwd) != 0) e(13);
86   if (chdir("foo") != 0) e(14);	/* change to foo */
87   if (chdir("..") != 0) e(15);	/* and back again */
88   if (getcwd(buf, PATH_MAX) != buf) e(16);
89   if (strcmp(buf, cwd) != 0) e(17);
90 
91   /* Make 30 sub dirs, eg. ./bar/bar/bar/bar/bar...... */
92   System("rm -rf bar");		/* get ridd of bar */
93   for (i = 0; i < 30; i++) {
94 	if (mkdir("bar", 0777) != 0) e(18);
95 	if (chdir("bar") != 0) e(19);	/* change to bar */
96   }
97   for (i = 0; i < 30; i++) {
98 	if (chdir("..") != 0) e(20);	/* and back again */
99 	if (rmdir("bar") != 0) e(21);
100   }
101 
102   /* Make sure we are back where we started. */
103   if (getcwd(buf, PATH_MAX) != buf) e(22);
104   if (strcmp(buf, cwd) != 0) e(23);
105   System("rm -rf bar");		/* just incase */
106 
107   /* Do some normal checks on `Chdir()' and `getcwd()' */
108   if (chdir("/") != 0) e(24);
109   if (getcwd(buf, PATH_MAX) != buf) e(25);
110   if (strcmp(buf, "/") != 0) e(26);
111   if (chdir("..") != 0) e(27);	/* go to parent of / */
112   if (getcwd(buf, PATH_MAX) != buf) e(28);
113   if (strcmp(buf, "/") != 0) e(29);
114   if (chdir(cwd) != 0) e(30);
115   if (getcwd(buf, PATH_MAX) != buf) e(31);
116   if (strcmp(buf, cwd) != 0) e(32);
117   if (chdir("/etc") != 0) e(33);	/* /etc might be on RAM */
118   if (getcwd(buf, PATH_MAX) != buf) e(34);	/* might make a difference */
119   if (strcmp(buf, "/etc") != 0) e(35);
120   if (chdir(cwd) != 0) e(36);
121   if (getcwd(buf, PATH_MAX) != buf) e(37);
122   if (strcmp(buf, cwd) != 0) e(38);
123   if (chdir(".//.//") != 0) e(39);	/* .//.// == current dir */
124   if (getcwd(buf, PATH_MAX) != buf) e(40);
125   if (strcmp(buf, cwd) != 0) e(41);	/* we might be at '/' */
126   System("rm -rf foo");
127 }
128 
test23b()129 void test23b()
130 {				/* Test critical values. */
131   int does_truncate;
132   subtest = 2;
133 
134   System("rm -rf ../DIR_23/*");
135 
136   /* Fiddle with the size (2nd) parameter of `getcwd ()'. */
137   if (getcwd(cwd, PATH_MAX) != cwd) e(1);	/* get cwd */
138   if (getcwd(buf, strlen(cwd)) != (char *) 0) e(2);   /* size 1 to small */
139   if (errno != ERANGE) e(3);
140   if (getcwd(buf, PATH_MAX) != buf) e(4);
141   if (strcmp(buf, cwd) != 0) e(5);
142   Chdir(cwd);			/* getcwd might cd / */
143   if (getcwd(buf, strlen(cwd) + 1) != buf) e(6);	/* size just ok */
144   if (getcwd(buf, PATH_MAX) != buf) e(7);
145   if (strcmp(buf, cwd) != 0) e(8);
146 
147   /* Let's see how "MaxName" and "ToLongName" are handled. */
148   if (mkdir(MaxName, 0777) != 0) e(9);
149   if (chdir(MaxName) != 0) e(10);
150   if (chdir("..") != 0) e(11);
151   if (rmdir(MaxName) != 0) e(12);
152   if (getcwd(buf, PATH_MAX) != buf) e(13);
153   if (strcmp(buf, cwd) != 0) e(14);
154   if (chdir(MaxPath) != 0) e(15);
155   if (getcwd(buf, PATH_MAX) != buf) e(16);
156   if (strcmp(buf, cwd) != 0) e(17);
157 
158   does_truncate = does_fs_truncate();
159   if (chdir(ToLongName) != -1) e(18);
160   if (does_truncate) {
161 	if (errno != ENOENT) e(19);
162   } else {
163   	if (errno != ENAMETOOLONG) e(20);
164   }
165 
166   if (getcwd(buf, PATH_MAX) != buf) e(21);
167   if (strcmp(buf, cwd) != 0) e(22);
168   if (chdir(ToLongPath) != -1) e(23);
169   if (errno != ENAMETOOLONG) e(24);
170   if (getcwd(buf, PATH_MAX) != buf) e(25);
171   if (strcmp(buf, cwd) != 0) e(26);
172 }
173 
test23c()174 void test23c()
175 {				/* Check reaction to errors */
176   subtest = 3;
177 
178   System("rm -rf ../DIR_23/*");
179 
180   if (getcwd(cwd, PATH_MAX) != cwd) e(1);	/* get cwd */
181 
182   /* Creat a working dir named "foo", remove any previous residues. */
183   System("rm -rf foo; mkdir foo");
184 
185   /* Check some obviouse errors. */
186   if (chdir("") != -1) e(2);
187   if (errno != ENOENT) e(3);
188   if (getcwd(buf, PATH_MAX) != buf) e(4);
189   if (strcmp(buf, cwd) != 0) e(5);
190   if (getcwd(buf, 0) != (char *) 0) e(6);
191   if (errno != EINVAL) e(7);
192   if (getcwd(buf, PATH_MAX) != buf) e(8);
193   if (strcmp(buf, cwd) != 0) e(9);
194   if (getcwd(buf, 0) != (char *) 0) e(10);
195   if (errno != EINVAL) e(11);
196   if (getcwd(buf, PATH_MAX) != buf) e(12);
197   if (strcmp(buf, cwd) != 0) e(13);
198   if (chdir(cwd) != 0) e(14);	/* getcwd might be buggy. */
199 
200   /* Change the mode of foo, and check the effect. */
201   if (chdir("foo") != 0) e(15);	/* change to foo */
202   if (mkdir("bar", 0777) != 0) e(16);	/* make a new dir bar */
203   if (getcwd(cwd2, PATH_MAX) != cwd2) e(17);	/* get the new cwd */
204   if (getcwd(buf, 3) != (char *) 0) e(18);	/* size is too small */
205   if (errno != ERANGE) e(19);
206   if (getcwd(buf, PATH_MAX) != buf) e(20);
207   if (strcmp(buf, cwd2) != 0) e(21);
208   Chdir(cwd2);			/* getcwd() might cd / */
209   System("chmod 377 .");	/* make foo unreadable */
210   if (getcwd(buf, PATH_MAX) != buf) e(22);	/* dir not readable */
211   if (getcwd(buf, PATH_MAX) != buf) e(23);
212   if (strcmp(buf, cwd2) != 0) e(24);
213   if (chdir("bar") != 0) e(25);	/* at .../foo/bar */
214   if (!superuser) {
215 	if (getcwd(buf, PATH_MAX) != (char *) 0) e(26);
216 	if (errno != EACCES) e(27);
217   }
218   if (superuser) {
219 	if (getcwd(buf, PATH_MAX) != buf) e(28);
220   }
221   if (chdir(cwd2) != 0) e(29);
222   if (getcwd(buf, PATH_MAX) != buf) e(30);
223   if (strcmp(buf, cwd2) != 0) e(31);
224   System("chmod 677 .");	/* make foo inaccessable */
225   if (!superuser) {
226 	if (getcwd(buf, PATH_MAX) != (char *) 0) e(32);	/* try to get cwd */
227 	if (errno != EACCES) e(33);	/* but no access */
228 	if (chdir("..") != -1) e(34);	/* try to get back */
229 	if (errno != EACCES) e(35);	/* again no access */
230 	if (chdir(cwd) != 0) e(36);	/* get back to cwd */
231 	/* `Chdir()' might do path optimizing, it shouldn't. */
232 	if (chdir("foo/..") != -1) e(37);	/* no op */
233 	if (chdir("foo") != -1) e(38);	/* try to cd to foo */
234 	if (errno != EACCES) e(39);	/* no have access */
235 	if (getcwd(buf, PATH_MAX) != buf) e(40);
236 	if (strcmp(buf, cwd) != 0) e(41);
237   }
238   if (superuser) {
239 	if (getcwd(buf, PATH_MAX) != buf) e(42);
240 	if (strcmp(buf, cwd2) != 0) e(43);
241 	if (chdir("..") != 0) e(44);	/* get back to cwd */
242 	if (chdir("foo") != 0) e(45);	/* get back to foo */
243 	if (chdir(cwd) != 0) e(46);	/* get back to cwd */
244   }
245   if (getcwd(buf, PATH_MAX) != buf) e(47);	/* check we are */
246   if (strcmp(buf, cwd) != 0) e(48);	/* back at cwd. */
247   Chdir(cwd);			/* just in case... */
248 
249   if (chdir("/etc/passwd") != -1) e(49);	/* try to change to a file */
250   if (errno != ENOTDIR) e(50);
251   if (getcwd(buf, PATH_MAX) != buf) e(51);
252   if (strcmp(buf, cwd) != 0) e(52);
253   if (chdir("/notexist") != -1) e(53);
254   if (errno != ENOENT) e(54);
255   if (getcwd(buf, PATH_MAX) != buf) e(55);
256   if (strcmp(buf, cwd) != 0) e(56);
257   System("chmod 777 foo");
258   if (chdir("foo") != 0) e(57);
259 
260   /* XXX - this comment was botched by 'pretty'. */
261   /* * Since `foo' is the cwd, it should not be removeable but * if it
262    * were, this code would be found here; *
263    *
264    *  System ("cd .. ; rm -rf foo");	remove foo *  if (chdir (".")
265    * != -1) e();		try go to. *  if (errno != ENOENT) e();
266    * hould not be an entry *  if (chdir ("..") != -1) e();	try
267    * to get back *  if (errno != ENOENT) e();		should not be
268    * an entry *  if (getcwd (buf, PATH_MAX) != (char *)0) e(); don't
269    * know where we are *
270    *
271    * What should errno be now ? The cwd might be gone if te superuser *
272    * removed the cwd. (Might even have linked it first.) But this *
273    * testing should be done by the test program for `rmdir()'. */
274   if (chdir(cwd) != 0) e(58);
275 }
276 
makelongnames()277 void makelongnames()
278 {
279   register int i;
280   int max_name_length;
281 
282   max_name_length = name_max("."); /* Aka NAME_MAX, but not every FS supports
283 				    * the same length, hence runtime check */
284   MaxName = malloc(max_name_length + 1);
285   ToLongName = malloc(max_name_length + 1 + 1); /* Name of maximum +1 length */
286   memset(MaxName, 'a', max_name_length);
287   MaxName[max_name_length] = '\0';
288 
289   for (i = 0; i < PATH_MAX - 1; i++) {	/* idem path */
290 	MaxPath[i++] = '.';
291 	MaxPath[i] = '/';
292   }
293   MaxPath[PATH_MAX - 1] = '\0';
294 
295   strcpy(ToLongName, MaxName);	/* copy them Max to ToLong */
296   strcpy(ToLongPath, MaxPath);
297 
298   ToLongName[max_name_length] = 'a';
299   ToLongName[max_name_length+1] = '\0';/* extend ToLongName by one too many */
300   ToLongPath[PATH_MAX - 1] = '/';
301   ToLongPath[PATH_MAX] = '\0';	/* inc ToLongPath by one */
302 }
303 
304