00001
00002
00003 #include <sys/types.h>
00004 #include <sys/stat.h>
00005 #include <sys/wait.h>
00006 #include <string.h>
00007 #include <stdlib.h>
00008 #include <unistd.h>
00009 #include <limits.h>
00010 #include <fcntl.h>
00011 #include <dirent.h>
00012 #include <errno.h>
00013 #include <time.h>
00014 #include <stdio.h>
00015
00016 _PROTOTYPE(void main, (int argc, char *argv[]));
00017 _PROTOTYPE(void chk_dir, (DIR * dirpntr));
00018 _PROTOTYPE(void test24a, (void));
00019 _PROTOTYPE(void test24b, (void));
00020 _PROTOTYPE(void test24c, (void));
00021 _PROTOTYPE(void makelongnames, (void));
00022 _PROTOTYPE(void e, (int number));
00023 _PROTOTYPE(void quit, (void));
00024
00025 #define OVERFLOW_DIR_NR (OPEN_MAX + 1)
00026 #define MAX_ERROR 4
00027 #define ITERATIONS 5
00028
00029 #define DIRENT0 ((struct dirent *) NULL)
00030 #define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
00031 #define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
00032
00033 int errct = 0;
00034 int subtest = 1;
00035 int superuser;
00036
00037 char MaxName[NAME_MAX + 1];
00038 char MaxPath[PATH_MAX];
00039 char ToLongName[NAME_MAX + 2];
00040 char ToLongPath[PATH_MAX + 1];
00041
00042 void main(argc, argv)
00043 int argc;
00044 char *argv[];
00045 {
00046 int i, m = 0xFFFF;
00047
00048 sync();
00049 if (argc == 2) m = atoi(argv[1]);
00050 printf("Test 24 ");
00051 fflush(stdout);
00052 System("rm -rf DIR_24; mkdir DIR_24");
00053 Chdir("DIR_24");
00054 makelongnames();
00055 superuser = (geteuid() == 0);
00056
00057 for (i = 0; i < ITERATIONS; i++) {
00058 if (m & 0001) test24a();
00059 if (m & 0002) test24b();
00060 if (m & 0004) test24c();
00061 }
00062 quit();
00063 }
00064
00065 void test24a()
00066 {
00067 int fd3, fd4, fd5;
00068 DIR *dirp;
00069 int j, ret, fd, flags;
00070 struct stat st1, st2;
00071 int stat_loc;
00072 time_t time1;
00073
00074 subtest = 1;
00075
00076 System("rm -rf ../DIR_24/*");
00077
00078 if ((fd = dup(0)) != 3) e(1);
00079 close(fd);
00080 dirp = opendir("/");
00081 if (dirp == ((DIR *) NULL)) e(2);
00082 if ((fd = dup(0)) <= 2) e(3);
00083 if (fd > 3) {
00084 flags = fcntl(3, F_GETFD);
00085 if (!(flags & FD_CLOEXEC)) e(4);
00086 }
00087 close(fd);
00088 ret = closedir(dirp);
00089 if (ret == -1) e(5);
00090 if (ret != 0) e(6);
00091 if ((fd = dup(0)) != 3) e(7);
00092 close(fd);
00093
00094 System("rm -rf foo; mkdir foo");
00095 Chdir("foo");
00096 System("touch f1 f2 f3 f4 f5");
00097 System("rm f[24]");
00098 Chdir("..");
00099
00100 if ((dirp = opendir("foo")) == ((DIR *) NULL)) e(8);
00101 chk_dir(dirp);
00102 for (j = 0; j < 10; j++) {
00103 errno = j * 47 % 7;
00104 if (readdir(dirp) != DIRENT0) e(9);
00105 if (errno != j * 47 % 7) e(10);
00106 }
00107 rewinddir(dirp);
00108 chk_dir(dirp);
00109 for (j = 0; j < 10; j++) {
00110 errno = j * 23 % 7;
00111 if (readdir(dirp) != DIRENT0) e(11);
00112 if (errno != j * 23 % 7) e(12);
00113 }
00114 if ((fd4 = creat("foo/f4", 0666)) <= 2) e(13);
00115 System("rm foo/f4");
00116 rewinddir(dirp);
00117 if ((fd3 = open("foo/f3", O_WRONLY)) <= 2) e(14);
00118 if ((fd5 = open("foo/f5", O_WRONLY)) <= 2) e(15);
00119 if (write(fd3, "Hello", 6) != 6) e(16);
00120 if (write(fd4, "Hello", 6) != 6) e(17);
00121 if (close(fd5) != 0) e(18);
00122 chk_dir(dirp);
00123 for (j = 0; j < 10; j++) {
00124 errno = j * 101 % 7;
00125 if (readdir(dirp) != DIRENT0) e(19);
00126 if (errno != j * 101 % 7) e(20);
00127 }
00128 if (close(fd4) != 0) e(21);
00129 if (close(fd3) != 0) e(22);
00130 if (closedir(dirp) != 0) e(23);
00131
00132 Chdir("foo");
00133 if ((dirp = opendir(".//")) == ((DIR *) NULL)) e(24);
00134 Chdir("..");
00135 chk_dir(dirp);
00136 for (j = 0; j < 10; j++) {
00137 errno = (j * 101) % 7;
00138 if (readdir(dirp) != DIRENT0) e(25);
00139 if (errno != (j * 101) % 7) e(26);
00140 }
00141
00142 if (closedir(dirp) != 0) e(27);
00143
00144 stat("foo", &st1);
00145 time(&time1);
00146 while (time1 >= time((time_t *)0))
00147 ;
00148 if ((dirp = opendir("foo")) == ((DIR *) NULL)) e(28);
00149 if (readdir(dirp) == DIRENT0) e(29);
00150 stat("foo", &st2);
00151 if (st1.st_atime > st2.st_atime) e(30);
00152
00153 switch (fork()) {
00154 case -1: printf("Can't fork\n"); break;
00155 case 0:
00156 rewinddir(dirp);
00157 if (readdir(dirp) == DIRENT0) e(31);
00158 if (closedir(dirp) != 0) e(32);
00159 exit(0);
00160 default:
00161 if (wait(&stat_loc) == -1) e(33);
00162 break;
00163 }
00164 if (closedir(dirp) != 0) e(34);
00165 }
00166
00167 void test24b()
00168 {
00169
00170
00171
00172
00173 int i, j;
00174 DIR *dirp[OVERFLOW_DIR_NR], *dp;
00175 struct dirent *dep, *dep1, *dep2;
00176 char name[NAME_MAX + 2];
00177 int dot = 0, dotdot = 0;
00178
00179 subtest = 2;
00180
00181 System("rm -rf ../DIR_24/*");
00182
00183 for (i = 0; i < OVERFLOW_DIR_NR; i++) {
00184 dirp[i] = opendir("/");
00185 if (dirp[i] == ((DIR *) NULL)) {
00186 if (errno != EMFILE) e(1);
00187 break;
00188 }
00189 }
00190 if (i <= 4) e(2);
00191 if (i >= OVERFLOW_DIR_NR) e(3);
00192 for (j = 0; j < i; j++) {
00193 if (closedir(dirp[(j + 5) % i]) != 0) e(4);
00194 }
00195
00196
00197 System("rm -rf foo; mkdir foo");
00198 Chdir("foo");
00199 name[0] = 0;
00200 for (i = 0; i <= NAME_MAX; i++) {
00201 if (strcat(name, "X") != name) e(5);
00202 close(creat(name, 0666));
00203 }
00204 Chdir("..");
00205
00206 if ((dp = opendir("foo")) == ((DIR *) NULL)) e(6);
00207 while ((dep = readdir(dp)) != DIRENT0) {
00208 if (strcmp("..", dep->d_name) == 0)
00209 dotdot++;
00210 else if (strcmp(".", dep->d_name) == 0)
00211 dot++;
00212 else
00213 name[strlen(dep->d_name)] += 1;
00214 }
00215 if (closedir(dp) != 0) e(7);
00216 for (i = 1; i <= NAME_MAX; i++) {
00217 if (name[i] != 'Y') e(8);
00218 }
00219
00220
00221 if (name[0] != 'X') e(9);
00222 if (name[NAME_MAX + 1] != '\0') e(10);
00223
00224
00225 if ((dirp[1] = opendir("foo")) == ((DIR *) NULL)) e(11);
00226 if ((dirp[2] = opendir("foo")) == ((DIR *) NULL)) e(12);
00227 if ((dep1 = readdir(dirp[1])) == DIRENT0) e(13);
00228 if ((dep2 = readdir(dirp[2])) == DIRENT0) e(14);
00229 if (dep1->d_name == dep2->d_name) e(15);
00230 strcpy(name, dep2->d_name);
00231 if (strcmp(dep1->d_name, name) != 0) e(16);
00232 if ((dep1 = readdir(dirp[1])) == DIRENT0) e(17);
00233 if ((dep1 = readdir(dirp[1])) == DIRENT0) e(18);
00234 if ((dep1 = readdir(dirp[1])) == DIRENT0) e(19);
00235 if (dep1->d_name == dep2->d_name) e(20);
00236 if (strcmp(dep2->d_name, name) != 0) e(21);
00237 rewinddir(dirp[1]);
00238 if ((dep2 = readdir(dirp[2])) == DIRENT0) e(22);
00239 if (strcmp(dep2->d_name, name) == 0) e(23);
00240 if (closedir(dirp[1]) != 0) e(24);
00241 if ((dep2 = readdir(dirp[2])) == DIRENT0) e(25);
00242 if (strcmp(dep2->d_name, name) == 0) e(26);
00243 if (closedir(dirp[2]) != 0) e(27);
00244 }
00245
00246 void test24c()
00247 {
00248
00249
00250 DIR *dirp;
00251
00252 subtest = 3;
00253
00254 System("rm -rf ../DIR_24/*");
00255
00256 if (opendir("foo/bar/nono") != ((DIR *) NULL)) e(1);
00257 if (errno != ENOENT) e(2);
00258 System("mkdir foo; chmod 677 foo");
00259 if (opendir("foo/bar/nono") != ((DIR *) NULL)) e(3);
00260 if (superuser) {
00261 if (errno != ENOENT) e(4);
00262 System("chmod 377 foo");
00263 if ((dirp = opendir("foo")) == ((DIR *) NULL)) e(5);
00264 if (closedir(dirp) != 0) e(6);
00265 }
00266 if (!superuser) {
00267 if (errno != EACCES) e(7);
00268 System("chmod 377 foo");
00269 if (opendir("foo") != ((DIR *) NULL)) e(8);
00270 }
00271 System("chmod 777 foo");
00272
00273 if (mkdir(MaxName, 0777) != 0) e(9);
00274 if ((dirp = opendir(MaxName)) == ((DIR *) NULL)) e(10);
00275 if (closedir(dirp) != 0) e(11);
00276 if (rmdir(MaxName) != 0) e(12);
00277 if ((dirp = opendir(MaxPath)) == ((DIR *) NULL)) e(13);
00278 if (closedir(dirp) != 0) e(14);
00279 #if 0
00280 if (closedir(dirp) != -1) e(15);
00281 if (closedir(dirp) != -1) e(16);
00282 #endif
00283 if (opendir(ToLongName) != ((DIR *) NULL)) e(17);
00284 #ifdef _POSIX_NO_TRUNC
00285 # if _POSIX_NO_TRUNC - 0 != -1
00286 if (errno != ENAMETOOLONG) e(18);
00287 # else
00288 if (errno != ENOENT) e(19);
00289 # endif
00290 #else
00291 # include "error, this case requires dynamic checks and is not handled"
00292 #endif
00293 if (opendir(ToLongPath) != ((DIR *) NULL)) e(20);
00294 if (errno != ENAMETOOLONG) e(21);
00295 System("touch foo/abc");
00296 if (opendir("foo/abc") != ((DIR *) NULL)) e(22);
00297 if (errno != ENOTDIR) e(23);
00298 }
00299
00300 void chk_dir(dirp)
00301 DIR *dirp;
00302 {
00303 int f1 = 0, f2 = 0, f3 = 0, f4 = 0, f5 = 0,
00304 other = 0, dot = 0, dotdot = 0;
00305 int i;
00306 struct dirent *dep;
00307 char *fname;
00308 int oldsubtest = subtest;
00309
00310 subtest = 4;
00311
00312 for (i = 0; i < 5; i++) {
00313 dep = readdir(dirp);
00314 if (dep == DIRENT0) {
00315 if (dep == DIRENT0) e(1);
00316 break;
00317 }
00318 fname = dep->d_name;
00319 if (strcmp(fname, ".") == 0)
00320 dot++;
00321 else if (strcmp(fname, "..") == 0)
00322 dotdot++;
00323 else if (strcmp(fname, "f1") == 0)
00324 f1++;
00325 else if (strcmp(fname, "f2") == 0)
00326 f2++;
00327 else if (strcmp(fname, "f3") == 0)
00328 f3++;
00329 else if (strcmp(fname, "f4") == 0)
00330 f4++;
00331 else if (strcmp(fname, "f5") == 0)
00332 f5++;
00333 else
00334 other++;
00335 }
00336
00337 if (dot != 1) e(2);
00338 if (dotdot != 1) e(3);
00339 if (f1 != 1) e(4);
00340 if (f3 != 1) e(5);
00341 if (f5 != 1) e(6);
00342 if (f2 != 0) e(7);
00343 if (f4 != 0) e(8);
00344 if (other != 0) e(9);
00345
00346 subtest = oldsubtest;
00347 }
00348
00349 void makelongnames()
00350 {
00351 register int i;
00352
00353 memset(MaxName, 'a', NAME_MAX);
00354 MaxName[NAME_MAX] = '\0';
00355 for (i = 0; i < PATH_MAX - 1; i++) {
00356 MaxPath[i++] = '.';
00357 MaxPath[i] = '/';
00358 }
00359 MaxPath[PATH_MAX - 1] = '\0';
00360
00361 strcpy(ToLongName, MaxName);
00362 strcpy(ToLongPath, MaxPath);
00363
00364 ToLongName[NAME_MAX] = 'a';
00365 ToLongName[NAME_MAX + 1] = '\0';
00366 ToLongPath[PATH_MAX - 1] = '/';
00367 ToLongPath[PATH_MAX] = '\0';
00368 }
00369
00370 void e(n)
00371 int n;
00372 {
00373 int err_num = errno;
00374
00375 printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
00376 errno = err_num;
00377 perror("");
00378 if (errct++ > MAX_ERROR) {
00379 printf("Too many errors; test aborted\n");
00380 chdir("..");
00381 system("rm -rf DIR*");
00382 exit(1);
00383 }
00384 errno = 0;
00385 }
00386
00387 void quit()
00388 {
00389 Chdir("..");
00390 System("rm -rf DIR_24");
00391
00392 if (errct == 0) {
00393 printf("ok\n");
00394 exit(0);
00395 } else {
00396 printf("%d errors\n", errct);
00397 exit(1);
00398 }
00399 }