test27.c

Go to the documentation of this file.
00001 /* test27: stat() fstat()       Author: Jan-Mark Wams (jms@cs.vu.nl) */
00002 
00003 #include <sys/types.h>
00004 #include <sys/stat.h>
00005 #include <fcntl.h>
00006 #include <unistd.h>
00007 #include <stdlib.h>
00008 #include <errno.h>
00009 #include <limits.h>
00010 #include <string.h>
00011 #include <limits.h>
00012 #include <time.h>
00013 #include <stdio.h>
00014 
00015 #define MODE_MASK       (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID)
00016 #define MAX_ERROR       4
00017 #define ITERATIONS      2
00018 
00019 #define System(cmd)     if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
00020 #define Chdir(dir)      if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
00021 
00022 int errct = 0;
00023 int subtest = 1;
00024 int superuser;
00025 char MaxName[NAME_MAX + 1];     /* Name of maximum length */
00026 char MaxPath[PATH_MAX];
00027 char ToLongName[NAME_MAX + 2];  /* Name of maximum +1 length */
00028 char ToLongPath[PATH_MAX + 1];
00029 
00030 _PROTOTYPE(void main, (int argc, char *argv[]));
00031 _PROTOTYPE(void test27a, (void));
00032 _PROTOTYPE(void test27b, (void));
00033 _PROTOTYPE(void test27c, (void));
00034 _PROTOTYPE(void makelongnames, (void));
00035 _PROTOTYPE(void e, (int __n));
00036 _PROTOTYPE(void quit, (void));
00037 
00038 void main(argc, argv)
00039 int argc;
00040 char *argv[];
00041 {
00042   int i, m = 0xFFFF;
00043 
00044   sync();
00045   if (argc == 2) m = atoi(argv[1]);
00046   printf("Test 27 ");
00047   fflush(stdout);
00048   System("rm -rf DIR_27; mkdir DIR_27");
00049   Chdir("DIR_27");
00050   superuser = (getuid() == 0);
00051   makelongnames();
00052 
00053   for (i = 0; i < ITERATIONS; i++) {
00054         if (m & 0001) test27a();
00055         if (m & 0002) test27b();
00056         if (m & 0004) test27c();
00057   }
00058   quit();
00059 }
00060 
00061 void test27a()
00062 {                               /* Test Normal operation. */
00063   struct stat st1, st2;
00064   time_t time1, time2;
00065   int fd, pfd[2];
00066 
00067   subtest = 1;
00068 
00069   time(&time1);                 /* get time before */
00070   while (time1 >= time((time_t *)0))
00071         ;                       /* Wait for time to change. */
00072   System("echo 7bytes > foo; chmod 4750 foo");
00073   if (stat("foo", &st1) != 0) e(1);     /* get foo's info */
00074   time(&time2);
00075   while (time2 >= time((time_t *)0))
00076         ;                       /* Wait for next second. */
00077   time(&time2);                 /* get time after */
00078   if ((st1.st_mode & MODE_MASK) != 04750) e(2);
00079   if (st1.st_nlink != 1) e(3);  /* check stat */
00080   if (st1.st_uid != geteuid()) e(4);
00081 #if defined(NGROUPS_MAX) && NGROUPS_MAX == 0
00082   if (st1.st_gid != getegid()) e(5);
00083 #endif /* defined(NGROUPS_MAX) && NGROUPS_MAX == 0 */
00084   if (st1.st_size != (size_t) 7) e(6);
00085   if (st1.st_atime <= time1) e(7);
00086   if (st1.st_atime >= time2) e(8);
00087   if (st1.st_ctime <= time1) e(9);
00088   if (st1.st_ctime >= time2) e(10);
00089   if (st1.st_mtime <= time1) e(11);
00090   if (st1.st_mtime >= time2) e(12);
00091 
00092   /* Compair stat and fstat. */
00093   System("echo 7bytes > bar");
00094   fd = open("bar", O_RDWR | O_APPEND);  /* the bar is open! */
00095   if (fd != 3) e(13);           /* should be stderr + 1 */
00096   if (stat("bar", &st1) != 0) e(14);    /* get bar's info */
00097   if (fstat(fd, &st2) != 0) e(15);      /* get bar's info */
00098 
00099   /* St1 en st2 should be the same. */
00100   if (st1.st_dev != st2.st_dev) e(16);
00101   if (st1.st_ino != st2.st_ino) e(17);
00102   if (st1.st_mode != st2.st_mode) e(18);
00103   if (st1.st_nlink != st2.st_nlink) e(19);
00104   if (st1.st_uid != st2.st_uid) e(20);
00105   if (st1.st_gid != st2.st_gid) e(21);
00106   if (st1.st_size != st2.st_size) e(22);
00107   if (st1.st_atime != st2.st_atime) e(23);
00108   if (st1.st_ctime != st2.st_ctime) e(24);
00109   if (st1.st_mtime != st2.st_mtime) e(25);
00110   time(&time1);                 /* wait a sec. */
00111   while (time1 >= time((time_t *)0))
00112         ;
00113   System("chmod 755 bar");      /* chainge mode */
00114   System("rm -f foobar; ln bar foobar");        /* chainge # links */
00115   if (write(fd, "foo", 4) != 4) e(26);  /* write a bit (or two) */
00116   if (stat("bar", &st2) != 0) e(27);    /* get new info */
00117   if (st2.st_dev != st1.st_dev) e(28);
00118   if (st2.st_ino != st1.st_ino) e(29);  /* compair the fealds */
00119   if ((st2.st_mode & MODE_MASK) != 0755) e(30);
00120   if (!S_ISREG(st2.st_mode)) e(31);
00121   if (st2.st_nlink != st1.st_nlink + 1) e(32);
00122   if (st2.st_uid != st1.st_uid) e(33);
00123   if (st2.st_gid != st1.st_gid) e(34);
00124   if (st2.st_size != (size_t) 11) e(35);
00125   if (st2.st_atime != st1.st_atime) e(36);
00126   if (st2.st_ctime <= st1.st_ctime) e(37);
00127   if (st2.st_mtime <= st1.st_mtime) e(38);
00128   if (close(fd) != 0) e(39);    /* sorry the bar is closed */
00129 
00130   /* Check special file. */
00131   if (stat("/dev/tty", &st1) != 0) e(40);
00132   if (!S_ISCHR(st1.st_mode)) e(41);
00133 #ifdef _MINIX
00134   if (stat("/dev/ram", &st1) != 0) e(42);
00135   if (!S_ISBLK(st1.st_mode)) e(43);
00136 #endif
00137 
00138   /* Check fifos. */
00139   time(&time1);
00140   while (time1 >= time((time_t *)0))
00141         ;
00142   if (mkfifo("fifo", 0640) != 0) e(44);
00143   if (stat("fifo", &st1) != 0) e(45);   /* get fifo's info */
00144   time(&time2);
00145   while (time2 >= time((time_t *)0))
00146         ;
00147   time(&time2);
00148   if (!S_ISFIFO(st1.st_mode)) e(46);
00149   if (st1.st_nlink != 1) e(47); /* check the stat info */
00150   if (st1.st_uid != geteuid()) e(48);
00151 #if defined(NGROUPS_MAX) && NGROUPS_MAX == 0
00152   if (st1.st_gid != getegid()) e(49);
00153 #endif /* defined(NGROUPS_MAX) && NGROUPS_MAX == 0 */
00154   if (st1.st_size != (size_t) 0) e(50);
00155   if (st1.st_atime <= time1) e(51);
00156   if (st1.st_atime >= time2) e(52);
00157   if (st1.st_ctime <= time1) e(53);
00158   if (st1.st_ctime >= time2) e(54);
00159   if (st1.st_mtime <= time1) e(55);
00160   if (st1.st_mtime >= time2) e(56);
00161 
00162   /* Note: the st_mode of a fstat on a pipe should contain a isfifo bit. */
00163   /* Check pipes. */
00164   time(&time1);
00165   while (time1 >= time((time_t *)0))
00166         ;
00167   if (pipe(pfd) != 0) e(57);
00168   if (fstat(pfd[0], &st1) != 0) e(58);  /* get pipe input info */
00169   time(&time2);
00170   while (time2 >= time((time_t *)0))
00171         ;
00172   time(&time2);
00173   if (!(S_ISFIFO(st1.st_mode))) e(59);  /* check stat struct */
00174   if (st1.st_uid != geteuid()) e(60);
00175   if (st1.st_gid != getegid()) e(61);
00176   if (st1.st_size != (size_t) 0) e(62);
00177   if (st1.st_atime <= time1) e(63);
00178   if (st1.st_atime >= time2) e(64);
00179   if (st1.st_ctime <= time1) e(65);
00180   if (st1.st_ctime >= time2) e(66);
00181   if (st1.st_mtime <= time1) e(67);
00182   if (st1.st_mtime >= time2) e(68);
00183   if (fstat(pfd[1], &st1) != 0) e(69);  /* get pipe output info */
00184   if (!(S_ISFIFO(st1.st_mode))) e(70);
00185   if (st1.st_uid != geteuid()) e(71);
00186   if (st1.st_gid != getegid()) e(72);
00187   if (st1.st_size != (size_t) 0) e(73);
00188   if (st1.st_atime < time1) e(74);
00189   if (st1.st_atime > time2) e(75);
00190   if (st1.st_ctime < time1) e(76);
00191   if (st1.st_ctime > time2) e(77);
00192   if (st1.st_mtime < time1) e(78);
00193   if (st1.st_mtime > time2) e(79);
00194   if (close(pfd[0]) != 0) e(80);
00195   if (close(pfd[1]) != 0) e(81);/* close pipe */
00196 
00197   /* Check dirs. */
00198   time(&time1);
00199   while (time1 >= time((time_t *)0))
00200         ;
00201   System("mkdir dir");
00202   if (stat("dir", &st1) != 0) e(82);    /* get dir info */
00203   time(&time2);
00204   while (time2 >= time((time_t *)0))
00205         ;
00206   time(&time2);
00207   if (!(S_ISDIR(st1.st_mode))) e(83);   /* check stat struct */
00208   if (st1.st_uid != geteuid()) e(84);
00209 #if defined(NGROUPS_MAX) && NGROUPS_MAX == 0
00210   if (st1.st_gid != getegid()) e(85);
00211 #endif /* defined(NGROUPS_MAX) && NGROUPS_MAX == 0 */
00212   if (st1.st_atime < time1) e(86);
00213   if (st1.st_atime > time2) e(87);
00214   if (st1.st_ctime < time1) e(88);
00215   if (st1.st_ctime > time2) e(89);
00216   if (st1.st_mtime < time1) e(90);
00217   if (st1.st_mtime > time2) e(91);
00218   System("rm -rf ../DIR_27/*");
00219 }
00220 
00221 void test27b()
00222 {                               /* Test maxima. */
00223   struct stat st;
00224   int fd;
00225 
00226   subtest = 2;
00227 
00228   /* Check stats on maximum length files names. */
00229   if (mkdir(MaxName, 0777) != 0) e(1);
00230   if (stat(MaxName, &st) != 0) e(2);
00231   if ((fd = open(MaxName, O_RDONLY)) != 3) e(3);
00232   if (fstat(fd, &st) != 0) e(4);
00233   if (close(fd) != 0) e(5);
00234   if (rmdir(MaxName) != 0) e(6);
00235   if (stat(MaxPath, &st) != 0) e(7);
00236   if ((fd = open(MaxPath, O_RDONLY)) != 3) e(8);
00237   if (fstat(fd, &st) != 0) e(9);
00238   if (close(fd) != 0) e(10);
00239   System("rm -rf ../DIR_27/*");
00240 }
00241 
00242 void test27c()
00243 {                               /* Test error response. */
00244   struct stat st;
00245   int fd, i;
00246 
00247   subtest = 3;
00248 
00249   System("echo Hi > foo");      /* Make a file called foo. */
00250   /* Check if a un searchable dir is handled ok. */
00251   Chdir("..");                  /* cd .. */
00252   System("chmod 677 DIR_27");   /* no search permission */
00253   if (stat("DIR_27/nono", &st) != -1) e(1);
00254   if (superuser) {
00255         if (errno != ENOENT) e(2);      /* su has access */
00256   }
00257   if (!superuser) {
00258         if (errno != EACCES) e(3);      /* we don't ;-) */
00259   }
00260   System("chmod 777 DIR_27");
00261   Chdir("DIR_27");              /* back to test dir */
00262 
00263   /* Check on ToLongName etc. */
00264 #ifdef _POSIX_NO_TRUNC
00265 # if _POSIX_NO_TRUNC - 0 != -1
00266   if (stat(ToLongName, &st) != -1) e(4);        /* name is too long */
00267   if (errno != ENAMETOOLONG) e(5);
00268 # endif
00269 #else
00270 # include "error, this case requires dynamic checks and is not handled"
00271 #endif
00272   if (stat(ToLongPath, &st) != -1) e(6);        /* path is too long */
00273   if (errno != ENAMETOOLONG) e(7);
00274 
00275   /* Test some common errors. */
00276   if (stat("nono", &st) != -1) e(8);    /* nono nonexistent */
00277   if (errno != ENOENT) e(9);
00278   if (stat("", &st) != -1) e(10);       /* try empty */
00279   if (errno != ENOENT) e(11);
00280   if (stat("foo/bar", &st) != -1) e(12);        /* foo is a file */
00281   if (errno != ENOTDIR) e(13);
00282 
00283   /* Test fstat on file descriptors that are not open. */
00284   for (i = 3; i < 6; i++) {
00285         if (fstat(i, &st) != -1) e(14);
00286         if (errno != EBADF) e(15);
00287   }
00288 
00289   /* Test if a just closed file is `fstat()'-able. */
00290   if ((fd = open("foo", O_RDONLY)) != 3) e(16); /* open foo */
00291   if (fstat(fd, &st) != 0) e(17);       /* get stat */
00292   if (close(fd) != 0) e(18);    /* close it */
00293   if (fstat(fd, &st) != -1) e(19);      /* get stat */
00294   if (errno != EBADF) e(20);
00295   System("rm -rf ../DIR_27/*");
00296 }
00297 
00298 void makelongnames()
00299 {
00300   register int i;
00301 
00302   memset(MaxName, 'a', NAME_MAX);
00303   MaxName[NAME_MAX] = '\0';
00304   for (i = 0; i < PATH_MAX - 1; i++) {  /* idem path */
00305         MaxPath[i++] = '.';
00306         MaxPath[i] = '/';
00307   }
00308   MaxPath[PATH_MAX - 1] = '\0';
00309 
00310   strcpy(ToLongName, MaxName);  /* copy them Max to ToLong */
00311   strcpy(ToLongPath, MaxPath);
00312 
00313   ToLongName[NAME_MAX] = 'a';
00314   ToLongName[NAME_MAX + 1] = '\0';      /* extend ToLongName by one too many */
00315   ToLongPath[PATH_MAX - 1] = '/';
00316   ToLongPath[PATH_MAX] = '\0';  /* inc ToLongPath by one */
00317 }
00318 
00319 void e(n)
00320 int n;
00321 {
00322   int err_num = errno;          /* Save in case printf clobbers it. */
00323 
00324   printf("Subtest %d,  error %d  errno=%d: ", subtest, n, errno);
00325   errno = err_num;
00326   perror("");
00327   if (errct++ > MAX_ERROR) {
00328         printf("Too many errors; test aborted\n");
00329         chdir("..");
00330         system("rm -rf DIR*");
00331         exit(1);
00332   }
00333   errno = 0;
00334 }
00335 
00336 void quit()
00337 {
00338   Chdir("..");
00339   System("rm -rf DIR_27");
00340 
00341   if (errct == 0) {
00342         printf("ok\n");
00343         exit(0);
00344   } else {
00345         printf("%d errors\n", errct);
00346         exit(1);
00347   }
00348 }

Generated on Fri Apr 14 22:57:34 2006 for minix by  doxygen 1.4.6