. swapped test26 and test40

. renamed sh*.sh to testsh*.sh
. invoked shell tests from run script like the other test commands
  (that was the point of renaming)
This commit is contained in:
Ben Gras 2005-08-08 14:30:50 +00:00
parent 5865124330
commit 1569a60360
5 changed files with 422 additions and 423 deletions

View file

@ -12,15 +12,16 @@ badones= # list of tests that failed
# Print test welcome message # Print test welcome message
clr clr
echo "Running POSIX compliance test suite. There are 40 tests in total." echo "Running POSIX compliance test suite. There are 42 tests in total."
echo "Please note that some tests may take a while, even on fast systems." echo "These tests may take more than 20 minutes, even on fast systems."
echo " " echo " "
# Run all the tests, keeping track of who failed. # Run all the tests, keeping track of who failed.
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
sh1.sh sh2.sh
do total=`expr $total + 1` do total=`expr $total + 1`
if test$i if ./test$i
then passed=`expr $passed + 1` then passed=`expr $passed + 1`
else failed=`expr $failed + 1` else failed=`expr $failed + 1`
badones=`echo $badones " " $i` badones=`echo $badones " " $i`
@ -36,5 +37,3 @@ if test $total = $passed
fi fi
# echo " " # echo " "
# sh1.sh
# sh2.sh

View file

@ -1,44 +1,37 @@
/* test26: link() unlink() Aithor: Jan-Mark Wams (jms@cs.vu.nl) */ /* test26: lseek() Author: Jan-Mark Wams (jms@cs.vu.nl) */
/*
* Not tested readonly file systems
* Not tested fs full
* Not tested unlinking bussy files
*/
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <string.h> #include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 10
#define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
#define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
#define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
#define Mkfifo(f) if (mkfifo(f,0777)!=0) printf("Can't make fifo %s\n", f)
int errct = 0; int errct = 0;
int subtest = 1; int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */ char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */ char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */ char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */ char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
#define MAX_ERROR 4
#define ITERATIONS 2 /* LINK_MAX is high, so time consuming. */
#define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
#define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
#define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
_PROTOTYPE(void main, (int argc, char *argv[])); _PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test26a, (void)); _PROTOTYPE(void test26a, (void));
_PROTOTYPE(void test26b, (void)); _PROTOTYPE(void test26b, (void));
_PROTOTYPE(void test26c, (void)); _PROTOTYPE(void test26c, (void));
_PROTOTYPE(int stateq, (struct stat *stp1, struct stat *stp2)); _PROTOTYPE(void e, (int number));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int __n));
_PROTOTYPE(void quit, (void)); _PROTOTYPE(void quit, (void));
void main(argc, argv) void main(argc, argv)
@ -53,10 +46,8 @@ char *argv[];
fflush(stdout); fflush(stdout);
System("rm -rf DIR_26; mkdir DIR_26"); System("rm -rf DIR_26; mkdir DIR_26");
Chdir("DIR_26"); Chdir("DIR_26");
superuser = (getuid() == 0);
makelongnames();
for (i = 0; i < ITERATIONS; i++) { for (i = 0; i < 10; i++) {
if (m & 0001) test26a(); if (m & 0001) test26a();
if (m & 0002) test26b(); if (m & 0002) test26b();
if (m & 0004) test26c(); if (m & 0004) test26c();
@ -66,248 +57,194 @@ char *argv[];
void test26a() void test26a()
{ /* Test normal operation. */ { /* Test normal operation. */
struct stat st1, st2, st3; int fd;
time_t time1; char buf[20];
int i, j;
struct stat st;
subtest = 1; subtest = 1;
/* Clean up any residu. */
System("rm -rf ../DIR_26/*"); System("rm -rf ../DIR_26/*");
System("touch foo"); /* make source file */
Stat("foo", &st1); /* get info of foo */ System("echo -n hihaho > hihaho");
Stat(".", &st2); /* and the cwd */ if ((fd = open("hihaho", O_RDONLY)) != 3) e(1);
time(&time1); if (lseek(fd, (off_t) 3, SEEK_SET) != (off_t) 3) e(2);
while (time1 >= time((time_t *)0)) if (read(fd, buf, 1) != 1) e(3);
; /* wait a sec */ if (buf[0] != 'a') e(4);
if (link("foo", "bar") != 0) e(1); /* link foo to bar */ if (lseek(fd, (off_t) - 1, SEEK_END) != 5) e(5);
Stat("foo", &st3); /* get new status */ if (read(fd, buf, 1) != 1) e(6);
if (st1.st_nlink + 1 != st3.st_nlink) e(2); /* link count foo up 1 */ if (buf[0] != 'o') e(7);
#ifndef V1_FILESYSTEM
if (st1.st_ctime >= st3.st_ctime) e(3); /* check stattime changed */ /* Seek past end of file. */
#endif if (lseek(fd, (off_t) 1000, SEEK_END) != 1006) e(8);
Stat(".", &st1); /* get parend dir info */ if (read(fd, buf, 1) != 0) e(9);
if (st2.st_ctime >= st1.st_ctime) e(4); /* ctime and mtime */
if (st2.st_mtime >= st1.st_mtime) e(5); /* should be updated */ /* Lseek() should not extend the file. */
Stat("bar", &st2); /* get info of bar */ if (fstat(fd, &st) != 0) e(10);
if (st2.st_nlink != st3.st_nlink) e(6); /* link count foo == bar */ if (st.st_size != (off_t) 6) e(11);
if (st2.st_ino != st3.st_ino) e(7); /* ino should be same */ if (close(fd) != 0) e(12);
if (st2.st_mode != st3.st_mode) e(8); /* check mode same */
if (st2.st_uid != st3.st_uid) e(9); /* check uid same */ /* Probeer lseek met write. */
if (st2.st_gid != st3.st_gid) e(10); /* check gid same */ if ((fd = open("hihaho", O_WRONLY)) != 3) e(13);
if (st2.st_size != st3.st_size) e(11); /* check size */ if (lseek(fd, (off_t) 3, SEEK_SET) != (off_t) 3) e(14);
if (st2.st_ctime != st3.st_ctime) e(12); /* check ctime */ if (write(fd, "e", 1) != 1) e(15);
if (st2.st_atime != st3.st_atime) e(13); /* check atime */ if (lseek(fd, (off_t) 1000, SEEK_END) != 1006) e(16);
if (st2.st_mtime != st3.st_mtime) e(14); /* check mtime */
Stat("foo", &st1); /* get fooinfo */ /* Lseek() should not extend the file. */
Stat(".", &st2); /* get dir info */ if (fstat(fd, &st) != 0) e(17);
time(&time1); if (st.st_size != (off_t) 6) e(18);
while (time1 >= time((time_t *)0)) if (write(fd, "e", 1) != 1) e(19);
; /* wait a sec */
if (unlink("bar") != 0) e(15);/* rm bar */ /* Lseek() and a subsequent write should! */
if (stat("bar", &st2) != -1) e(16); /* it's gone */ if (fstat(fd, &st) != 0) e(20);
Stat("foo", &st3); /* get foo again */ if (st.st_size != (off_t) 1007) e(21);
if (st1.st_nlink != st3.st_nlink + 1) e(17); /* link count back to normal */
#ifndef V1_FILESYSTEM if (close(fd) != 0) e(22);
if (st1.st_ctime >= st3.st_ctime) e(18); /* check ctime */
#endif /* Check the file, it should start with hiheho. */
Stat(".", &st3); /* get parend dir info */ if ((fd = open("hihaho", O_RDONLY)) != 3) e(23);
if (st2.st_ctime >= st3.st_ctime) e(19); /* ctime and mtime */ if (read(fd, buf, 6) != 6) e(24);
if (st2.st_mtime >= st3.st_mtime) e(20); /* should be updated */ if (strncmp(buf, "hiheho", 6) != 0) e(25);
/* The should be zero bytes and a trailing ``e''. */
if (sizeof(buf) < 10) e(26);
for (i = 1; i <= 20; i++) {
if (read(fd, buf, 10) != 10) e(27);
for (j = 0; j < 10; j++)
if (buf[j] != '\0') break;
if (j != 10) e(28);
if (lseek(fd, (off_t) 15, SEEK_CUR) != (off_t) i * 25 + 6) e(29);
}
if (lseek(fd, (off_t) 1006, SEEK_SET) != (off_t) 1006) e(30);
if (read(fd, buf, sizeof(buf)) != 1) e(31);
if (buf[0] != 'e') e(32);
if (lseek(fd, (off_t) - 1, SEEK_END) != (off_t) 1006) e(33);
if (read(fd, buf, sizeof(buf)) != 1) e(34);
if (buf[0] != 'e') e(35);
/* Closing time. */
if (close(fd) != 0) e(36);
} }
void test26b() void test26b()
{ {
register int nlink; int fd1, fd2, fd3;
char bar[30]; int stat_loc;
struct stat st, st2;
subtest = 2; subtest = 2;
/* Clean up any residu. */
System("rm -rf ../DIR_26/*"); System("rm -rf ../DIR_26/*");
/* Test what happens if we make LINK_MAX number of links. */ /* See if childs lseek() is effecting the parent. * See also if
System("touch foo"); * lseeking() on same file messes things up. */
for (nlink = 2; nlink <= LINK_MAX; nlink++) {
sprintf(bar, "bar.%d", nlink); /* Creat a file of 11 bytes. */
if (link("foo", bar) != 0) e(2); if ((fd1 = open("santa", O_WRONLY | O_CREAT, 0777)) != 3) e(1);
Stat(bar, &st); if (write(fd1, "ho ho ho ho", 11) != 11) e(2);
if (st.st_nlink != nlink) e(3); if (close(fd1) != 0) e(3);
Stat("foo", &st);
if (st.st_nlink != nlink) e(4); /* Open it multiple times. */
if ((fd1 = open("santa", O_RDONLY)) != 3) e(4);
if ((fd2 = open("santa", O_WRONLY)) != 4) e(5);
if ((fd3 = open("santa", O_RDWR)) != 5) e(6);
/* Set all offsets different. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(7);
if (lseek(fd2, (off_t) 4, SEEK_SET) != 4) e(8);
if (lseek(fd3, (off_t) 7, SEEK_SET) != 7) e(9);
/* Have a child process do additional offset changes. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (lseek(fd1, (off_t) 1, SEEK_CUR) != 3) e(10);
if (lseek(fd2, (off_t) 5, SEEK_SET) != 5) e(11);
if (lseek(fd3, (off_t) - 4, SEEK_END) != 7) e(12);
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(13); /* Alarm? */
} }
/* Check if we have LINK_MAX links that are all the same. */ /* Check if the new offsets are correct. */
Stat("foo", &st); if (lseek(fd1, (off_t) 0, SEEK_CUR) != 3) e(14);
if (st.st_nlink != LINK_MAX) e(5); if (lseek(fd2, (off_t) 0, SEEK_CUR) != 5) e(15);
for (nlink = 2; nlink <= LINK_MAX; nlink++) { if (lseek(fd3, (off_t) 0, SEEK_CUR) != 7) e(16);
sprintf(bar, "bar.%d", nlink);
Stat(bar, &st2);
if (!stateq(&st, &st2)) e(6);
}
/* Test no more links are possible. */ /* Close the file. */
if (link("foo", "nono") != -1) e(7); if (close(fd1) != 0) e(17);
if (stat("nono", &st) != -1) e(8); if (close(fd2) != 0) e(18);
Stat("foo", &st); if (close(fd3) != 0) e(19);
if (st.st_nlink != LINK_MAX) e(9); /* recheck the number of links */
/* Now unlink() the bar.### files */
for (nlink = LINK_MAX; nlink >= 2; nlink--) {
sprintf(bar, "bar.%d", nlink);
Stat(bar, &st);
if (st.st_nlink != nlink) e(10);
Stat("foo", &st2);
if (!stateq(&st, &st2)) e(11);
if (unlink(bar) != 0) e(12);
}
Stat("foo", &st);
if (st.st_nlink != 1) e(13); /* number of links back to 1 */
/* Test max path ed. */
if (link("foo", MaxName) != 0) e(14); /* link to MaxName */
if (unlink(MaxName) != 0) e(15); /* and remove it */
MaxPath[strlen(MaxPath) - 2] = '/';
MaxPath[strlen(MaxPath) - 1] = 'a'; /* make ././.../a */
if (link("foo", MaxPath) != 0) e(16); /* it should be */
if (unlink(MaxPath) != 0) e(17); /* (un)linkable */
System("rm -f ../DIR_26/*"); /* clean cwd */
} }
void test26c() void test26c()
{ { /* Test error returns. */
subtest = 3; int fd;
int tube[2];
int i, stat_loc;
/* Clean up any residu. */ subtest = 3;
System("rm -rf ../DIR_26/*"); System("rm -rf ../DIR_26/*");
/* Check some simple things. */ /* Fifo's can't be lseeked(). */
if (link("bar/nono", "nono") != -1) e(1); /* nonexistent */ Mkfifo("fifo");
if (errno != ENOENT) e(2); switch (fork()) {
Chdir(".."); case -1: printf("Can't fork\n"); break;
System("touch DIR_26/foo"); case 0:
System("chmod 677 DIR_26"); /* make inaccesable */ alarm(3); /* Try for max 3 secs. */
if (!superuser) { if ((fd = open("fifo", O_RDONLY)) != 3) e(1);
if (unlink("DIR_26/foo") != -1) e(3); if (lseek(fd, (off_t) 0, SEEK_SET) != (off_t) - 1) e(2);
if (errno != EACCES) e(4); if (errno != ESPIPE) e(3);
if (close(fd) != 0) e(4);
exit(0);
default:
if ((fd = open("fifo", O_WRONLY)) != 3) e(5);
wait(&stat_loc);
if (stat_loc != 0) e(6);/* Alarm? */
if (close(fd) != 0) e(7);
} }
if (link("DIR_26/bar/nono", "DIR_26/nono") != -1) e(5); /* nono no be */
if (superuser) {
if (errno != ENOENT) e(6); /* su has access */
}
if (!superuser) {
if (errno != EACCES) e(7); /* we don't ;-) */
}
System("chmod 577 DIR_26"); /* make unwritable */
if (superuser) {
if (link("DIR_26/foo", "DIR_26/nono") != 0) e(8);
if (unlink("DIR_26/nono") != 0) e(9);
}
if (!superuser) {
if (link("DIR_26/foo", "DIR_26/nono") != -1) e(10);
if (errno != EACCES) e(11);
if (unlink("DIR_26/foo") != -1) e(12); /* try to rm foo/foo */
if (errno != EACCES) e(13);
}
System("chmod 755 DIR_26"); /* back to normal */
Chdir("DIR_26");
/* Too-long path and name test */ /* Pipes can't be lseeked() eigther. */
ToLongPath[strlen(ToLongPath) - 2] = '/'; if (pipe(tube) != 0) e(8);
ToLongPath[strlen(ToLongPath) - 1] = 'a'; /* make ././.../a */ switch (fork()) {
if (link("foo", ToLongPath) != -1) e(18); /* path is too long */ case -1: printf("Can't fork\n"); break;
if (errno != ENAMETOOLONG) e(19); case 0:
if (unlink(ToLongPath) != -1) e(20); /* path is too long */ alarm(3); /* Max 3 sconds wait. */
if (errno != ENAMETOOLONG) e(21); if (lseek(tube[0], (off_t) 0, SEEK_SET) != (off_t) - 1) e(9);
if (link("foo", "foo") != -1) e(22); /* try linking foo to foo */ if (errno != ESPIPE) e(10);
if (errno != EEXIST) e(23); if (lseek(tube[1], (off_t) 0, SEEK_SET) != (off_t) - 1) e(11);
if (link("foo", "bar") != 0) e(24); /* make a link to bar */ if (errno != ESPIPE) e(12);
if (link("foo", "bar") != -1) e(25); /* try linking to bar again */ exit(0);
if (errno != EEXIST) e(26); default:
if (link("foo", "bar") != -1) e(27); /* try linking to bar again */ wait(&stat_loc);
if (errno != EEXIST) e(28); if (stat_loc != 0) e(14); /* Alarm? */
if (unlink("nono") != -1) e(29); /* try rm <not exist> */
if (errno != ENOENT) e(30);
if (unlink("") != -1) e(31); /* try unlinking empty */
if (errno != ENOENT) e(32);
if (link("foo", "") != -1) e(33); /* try linking to "" */
if (errno != ENOENT) e(34);
if (link("", "foo") != -1) e(35); /* try linking "" */
if (errno != ENOENT) e(36);
if (link("", "") != -1) e(37);/* try linking "" to "" */
if (errno != ENOENT) e(38);
if (link("/foo/bar/foo", "a") != -1) e(39); /* try no existing path */
if (errno != ENOENT) e(40);
if (link("foo", "/foo/bar/foo") != -1) e(41); /* try no existing path */
if (errno != ENOENT) e(42);
if (link("/a/b/c", "/d/e/f") != -1) e(43); /* try no existing path */
if (errno != ENOENT) e(44);
if (link("abc", "a") != -1) e(45); /* try no existing file */
if (errno != ENOENT) e(46);
if (link("foo/bar", "bar") != -1) e(47); /* foo is a file */
if (errno != ENOTDIR) e(48);
if (link("foo", "foo/bar") != -1) e(49); /* foo is not a dir */
if (errno != ENOTDIR) e(50);
if (unlink("foo/bar") != -1) e(51); /* foo still no dir */
if (errno != ENOTDIR) e(52);
if (!superuser) {
if (link(".", "root") != -1) e(55);
if (errno != EPERM) e(56); /* noroot can't */
if (unlink("root") != -1) e(57);
if (errno != ENOENT) e(58);
} }
if (mkdir("dir", 0777) != 0) e(59);
if (superuser) { /* Close the pipe. */
if (rmdir("dir") != 0) e(63); if (close(tube[0]) != 0) e(15);
if (close(tube[1]) != 0) e(16);
/* Whence arument invalid. */
System("echo -n contact > file");
if ((fd = open("file", O_RDWR)) != 3) e(17);
for (i = -1000; i < 1000; i++) {
if (i == SEEK_SET || i == SEEK_END || i == SEEK_CUR) continue;
if (lseek(fd, (off_t) 0, i) != (off_t) -1) e(18);
if (errno != EINVAL) e(19);
} }
if (!superuser) { if (close(fd) != 0) e(20);
if (unlink("dir") != -1) e(64);
if (errno != EPERM) e(65); /* that ain't w'rkn */ /* EBADF for bad fides. */
if (rmdir("dir") != 0) e(66); /* that's the way to do it */ for (i = -1000; i < 1000; i++) {
if (i >= 0 && i < OPEN_MAX) continue;
if (lseek(i, (off_t) 0, SEEK_SET) != (off_t) - 1) e(21);
if (lseek(i, (off_t) 0, SEEK_END) != (off_t) - 1) e(22);
if (lseek(i, (off_t) 0, SEEK_CUR) != (off_t) - 1) e(23);
} }
} }
int stateq(stp1, stp2)
struct stat *stp1, *stp2;
{
if (stp1->st_dev != stp2->st_dev) return 0;
if (stp1->st_ino != stp2->st_ino) return 0;
if (stp1->st_mode != stp2->st_mode) return 0;
if (stp1->st_nlink != stp2->st_nlink) return 0;
if (stp1->st_uid != stp2->st_uid) return 0;
if (stp1->st_gid != stp2->st_gid) return 0;
if (stp1->st_rdev != stp2->st_rdev) return 0;
if (stp1->st_size != stp2->st_size) return 0;
if (stp1->st_atime != stp2->st_atime) return 0;
if (stp1->st_mtime != stp2->st_mtime) return 0;
if (stp1->st_ctime != stp2->st_ctime) return 0;
return 1;
}
void makelongnames()
{
register int i;
memset(MaxName, 'a', NAME_MAX);
MaxName[NAME_MAX] = '\0';
for (i = 0; i < PATH_MAX - 1; i++) { /* idem path */
MaxPath[i++] = '.';
MaxPath[i] = '/';
}
MaxPath[PATH_MAX - 1] = '\0';
strcpy(ToLongName, MaxName); /* copy them Max to ToLong */
strcpy(ToLongPath, MaxPath);
ToLongName[NAME_MAX] = 'a';
ToLongName[NAME_MAX + 1] = '\0'; /* extend ToLongName by one
* too many */
ToLongPath[PATH_MAX - 1] = '/';
ToLongPath[PATH_MAX] = '\0'; /* inc ToLongPath by one */
}
void e(n) void e(n)
int n; int n;
@ -329,8 +266,8 @@ int n;
void quit() void quit()
{ {
chdir(".."); Chdir("..");
system("rm -rf DIR_26"); System("rm -rf DIR_26");
if (errct == 0) { if (errct == 0) {
printf("ok\n"); printf("ok\n");

View file

@ -1,37 +1,44 @@
/* test40: lseek() Author: Jan-Mark Wams (jms@cs.vu.nl) */ /* test40: link() unlink() Aithor: Jan-Mark Wams (jms@cs.vu.nl) */
/*
* Not tested readonly file systems
* Not tested fs full
* Not tested unlinking bussy files
*/
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h>
#include <errno.h> #include <errno.h>
#include <limits.h>
#include <string.h>
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 10
#define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
#define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
#define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
#define Mkfifo(f) if (mkfifo(f,0777)!=0) printf("Can't make fifo %s\n", f)
int errct = 0; int errct = 0;
int subtest = 1; int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */ char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */ char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */ char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */ char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
#define MAX_ERROR 4
#define ITERATIONS 2 /* LINK_MAX is high, so time consuming. */
#define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
#define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
#define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
_PROTOTYPE(void main, (int argc, char *argv[])); _PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test40a, (void)); _PROTOTYPE(void test40a, (void));
_PROTOTYPE(void test40b, (void)); _PROTOTYPE(void test40b, (void));
_PROTOTYPE(void test40c, (void)); _PROTOTYPE(void test40c, (void));
_PROTOTYPE(void e, (int number)); _PROTOTYPE(int stateq, (struct stat *stp1, struct stat *stp2));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int __n));
_PROTOTYPE(void quit, (void)); _PROTOTYPE(void quit, (void));
void main(argc, argv) void main(argc, argv)
@ -46,8 +53,10 @@ char *argv[];
fflush(stdout); fflush(stdout);
System("rm -rf DIR_40; mkdir DIR_40"); System("rm -rf DIR_40; mkdir DIR_40");
Chdir("DIR_40"); Chdir("DIR_40");
superuser = (getuid() == 0);
makelongnames();
for (i = 0; i < 10; i++) { for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test40a(); if (m & 0001) test40a();
if (m & 0002) test40b(); if (m & 0002) test40b();
if (m & 0004) test40c(); if (m & 0004) test40c();
@ -57,192 +66,246 @@ char *argv[];
void test40a() void test40a()
{ /* Test normal operation. */ { /* Test normal operation. */
int fd; struct stat st1, st2, st3;
char buf[20]; time_t time1;
int i, j;
struct stat st;
subtest = 1; subtest = 1;
/* Clean up any residu. */
System("rm -rf ../DIR_40/*"); System("rm -rf ../DIR_40/*");
System("touch foo"); /* make source file */
System("echo -n hihaho > hihaho"); Stat("foo", &st1); /* get info of foo */
if ((fd = open("hihaho", O_RDONLY)) != 3) e(1); Stat(".", &st2); /* and the cwd */
if (lseek(fd, (off_t) 3, SEEK_SET) != (off_t) 3) e(2); time(&time1);
if (read(fd, buf, 1) != 1) e(3); while (time1 >= time((time_t *)0))
if (buf[0] != 'a') e(4); ; /* wait a sec */
if (lseek(fd, (off_t) - 1, SEEK_END) != 5) e(5); if (link("foo", "bar") != 0) e(1); /* link foo to bar */
if (read(fd, buf, 1) != 1) e(6); Stat("foo", &st3); /* get new status */
if (buf[0] != 'o') e(7); if (st1.st_nlink + 1 != st3.st_nlink) e(2); /* link count foo up 1 */
#ifndef V1_FILESYSTEM
/* Seek past end of file. */ if (st1.st_ctime >= st3.st_ctime) e(3); /* check stattime changed */
if (lseek(fd, (off_t) 1000, SEEK_END) != 1006) e(8); #endif
if (read(fd, buf, 1) != 0) e(9); Stat(".", &st1); /* get parend dir info */
if (st2.st_ctime >= st1.st_ctime) e(4); /* ctime and mtime */
/* Lseek() should not extend the file. */ if (st2.st_mtime >= st1.st_mtime) e(5); /* should be updated */
if (fstat(fd, &st) != 0) e(10); Stat("bar", &st2); /* get info of bar */
if (st.st_size != (off_t) 6) e(11); if (st2.st_nlink != st3.st_nlink) e(6); /* link count foo == bar */
if (close(fd) != 0) e(12); if (st2.st_ino != st3.st_ino) e(7); /* ino should be same */
if (st2.st_mode != st3.st_mode) e(8); /* check mode same */
/* Probeer lseek met write. */ if (st2.st_uid != st3.st_uid) e(9); /* check uid same */
if ((fd = open("hihaho", O_WRONLY)) != 3) e(13); if (st2.st_gid != st3.st_gid) e(10); /* check gid same */
if (lseek(fd, (off_t) 3, SEEK_SET) != (off_t) 3) e(14); if (st2.st_size != st3.st_size) e(11); /* check size */
if (write(fd, "e", 1) != 1) e(15); if (st2.st_ctime != st3.st_ctime) e(12); /* check ctime */
if (lseek(fd, (off_t) 1000, SEEK_END) != 1006) e(16); if (st2.st_atime != st3.st_atime) e(13); /* check atime */
if (st2.st_mtime != st3.st_mtime) e(14); /* check mtime */
/* Lseek() should not extend the file. */ Stat("foo", &st1); /* get fooinfo */
if (fstat(fd, &st) != 0) e(17); Stat(".", &st2); /* get dir info */
if (st.st_size != (off_t) 6) e(18); time(&time1);
if (write(fd, "e", 1) != 1) e(19); while (time1 >= time((time_t *)0))
; /* wait a sec */
/* Lseek() and a subsequent write should! */ if (unlink("bar") != 0) e(15);/* rm bar */
if (fstat(fd, &st) != 0) e(20); if (stat("bar", &st2) != -1) e(16); /* it's gone */
if (st.st_size != (off_t) 1007) e(21); Stat("foo", &st3); /* get foo again */
if (st1.st_nlink != st3.st_nlink + 1) e(17); /* link count back to normal */
if (close(fd) != 0) e(22); #ifndef V1_FILESYSTEM
if (st1.st_ctime >= st3.st_ctime) e(18); /* check ctime */
/* Check the file, it should start with hiheho. */ #endif
if ((fd = open("hihaho", O_RDONLY)) != 3) e(23); Stat(".", &st3); /* get parend dir info */
if (read(fd, buf, 6) != 6) e(24); if (st2.st_ctime >= st3.st_ctime) e(19); /* ctime and mtime */
if (strncmp(buf, "hiheho", 6) != 0) e(25); if (st2.st_mtime >= st3.st_mtime) e(20); /* should be updated */
/* The should be zero bytes and a trailing ``e''. */
if (sizeof(buf) < 10) e(26);
for (i = 1; i <= 20; i++) {
if (read(fd, buf, 10) != 10) e(27);
for (j = 0; j < 10; j++)
if (buf[j] != '\0') break;
if (j != 10) e(28);
if (lseek(fd, (off_t) 15, SEEK_CUR) != (off_t) i * 25 + 6) e(29);
}
if (lseek(fd, (off_t) 1006, SEEK_SET) != (off_t) 1006) e(30);
if (read(fd, buf, sizeof(buf)) != 1) e(31);
if (buf[0] != 'e') e(32);
if (lseek(fd, (off_t) - 1, SEEK_END) != (off_t) 1006) e(33);
if (read(fd, buf, sizeof(buf)) != 1) e(34);
if (buf[0] != 'e') e(35);
/* Closing time. */
if (close(fd) != 0) e(36);
} }
void test40b() void test40b()
{ {
int fd1, fd2, fd3; register int nlink;
int stat_loc; char bar[30];
struct stat st, st2;
subtest = 2; subtest = 2;
/* Clean up any residu. */
System("rm -rf ../DIR_40/*"); System("rm -rf ../DIR_40/*");
/* See if childs lseek() is effecting the parent. * See also if /* Test what happens if we make LINK_MAX number of links. */
* lseeking() on same file messes things up. */ System("touch foo");
for (nlink = 2; nlink <= LINK_MAX; nlink++) {
/* Creat a file of 11 bytes. */ sprintf(bar, "bar.%d", nlink);
if ((fd1 = open("santa", O_WRONLY | O_CREAT, 0777)) != 3) e(1); if (link("foo", bar) != 0) e(2);
if (write(fd1, "ho ho ho ho", 11) != 11) e(2); Stat(bar, &st);
if (close(fd1) != 0) e(3); if (st.st_nlink != nlink) e(3);
Stat("foo", &st);
/* Open it multiple times. */ if (st.st_nlink != nlink) e(4);
if ((fd1 = open("santa", O_RDONLY)) != 3) e(4);
if ((fd2 = open("santa", O_WRONLY)) != 4) e(5);
if ((fd3 = open("santa", O_RDWR)) != 5) e(6);
/* Set all offsets different. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(7);
if (lseek(fd2, (off_t) 4, SEEK_SET) != 4) e(8);
if (lseek(fd3, (off_t) 7, SEEK_SET) != 7) e(9);
/* Have a child process do additional offset changes. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (lseek(fd1, (off_t) 1, SEEK_CUR) != 3) e(10);
if (lseek(fd2, (off_t) 5, SEEK_SET) != 5) e(11);
if (lseek(fd3, (off_t) - 4, SEEK_END) != 7) e(12);
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(13); /* Alarm? */
} }
/* Check if the new offsets are correct. */ /* Check if we have LINK_MAX links that are all the same. */
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 3) e(14); Stat("foo", &st);
if (lseek(fd2, (off_t) 0, SEEK_CUR) != 5) e(15); if (st.st_nlink != LINK_MAX) e(5);
if (lseek(fd3, (off_t) 0, SEEK_CUR) != 7) e(16); for (nlink = 2; nlink <= LINK_MAX; nlink++) {
sprintf(bar, "bar.%d", nlink);
Stat(bar, &st2);
if (!stateq(&st, &st2)) e(6);
}
/* Close the file. */ /* Test no more links are possible. */
if (close(fd1) != 0) e(17); if (link("foo", "nono") != -1) e(7);
if (close(fd2) != 0) e(18); if (stat("nono", &st) != -1) e(8);
if (close(fd3) != 0) e(19); Stat("foo", &st);
if (st.st_nlink != LINK_MAX) e(9); /* recheck the number of links */
/* Now unlink() the bar.### files */
for (nlink = LINK_MAX; nlink >= 2; nlink--) {
sprintf(bar, "bar.%d", nlink);
Stat(bar, &st);
if (st.st_nlink != nlink) e(10);
Stat("foo", &st2);
if (!stateq(&st, &st2)) e(11);
if (unlink(bar) != 0) e(12);
}
Stat("foo", &st);
if (st.st_nlink != 1) e(13); /* number of links back to 1 */
/* Test max path ed. */
if (link("foo", MaxName) != 0) e(14); /* link to MaxName */
if (unlink(MaxName) != 0) e(15); /* and remove it */
MaxPath[strlen(MaxPath) - 2] = '/';
MaxPath[strlen(MaxPath) - 1] = 'a'; /* make ././.../a */
if (link("foo", MaxPath) != 0) e(16); /* it should be */
if (unlink(MaxPath) != 0) e(17); /* (un)linkable */
System("rm -f ../DIR_40/*"); /* clean cwd */
} }
void test40c() void test40c()
{ /* Test error returns. */ {
int fd;
int tube[2];
int i, stat_loc;
subtest = 3; subtest = 3;
/* Clean up any residu. */
System("rm -rf ../DIR_40/*"); System("rm -rf ../DIR_40/*");
/* Fifo's can't be lseeked(). */ /* Check some simple things. */
Mkfifo("fifo"); if (link("bar/nono", "nono") != -1) e(1); /* nonexistent */
switch (fork()) { if (errno != ENOENT) e(2);
case -1: printf("Can't fork\n"); break; Chdir("..");
case 0: System("touch DIR_40/foo");
alarm(3); /* Try for max 3 secs. */ System("chmod 677 DIR_40"); /* make inaccesable */
if ((fd = open("fifo", O_RDONLY)) != 3) e(1); if (!superuser) {
if (lseek(fd, (off_t) 0, SEEK_SET) != (off_t) - 1) e(2); if (unlink("DIR_40/foo") != -1) e(3);
if (errno != ESPIPE) e(3); if (errno != EACCES) e(4);
if (close(fd) != 0) e(4);
exit(0);
default:
if ((fd = open("fifo", O_WRONLY)) != 3) e(5);
wait(&stat_loc);
if (stat_loc != 0) e(6);/* Alarm? */
if (close(fd) != 0) e(7);
} }
if (link("DIR_40/bar/nono", "DIR_40/nono") != -1) e(5); /* nono no be */
/* Pipes can't be lseeked() eigther. */ if (superuser) {
if (pipe(tube) != 0) e(8); if (errno != ENOENT) e(6); /* su has access */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(3); /* Max 3 sconds wait. */
if (lseek(tube[0], (off_t) 0, SEEK_SET) != (off_t) - 1) e(9);
if (errno != ESPIPE) e(10);
if (lseek(tube[1], (off_t) 0, SEEK_SET) != (off_t) - 1) e(11);
if (errno != ESPIPE) e(12);
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(14); /* Alarm? */
} }
if (!superuser) {
/* Close the pipe. */ if (errno != EACCES) e(7); /* we don't ;-) */
if (close(tube[0]) != 0) e(15);
if (close(tube[1]) != 0) e(16);
/* Whence arument invalid. */
System("echo -n contact > file");
if ((fd = open("file", O_RDWR)) != 3) e(17);
for (i = -1000; i < 1000; i++) {
if (i == SEEK_SET || i == SEEK_END || i == SEEK_CUR) continue;
if (lseek(fd, (off_t) 0, i) != (off_t) -1) e(18);
if (errno != EINVAL) e(19);
} }
if (close(fd) != 0) e(20); System("chmod 577 DIR_40"); /* make unwritable */
if (superuser) {
/* EBADF for bad fides. */ if (link("DIR_40/foo", "DIR_40/nono") != 0) e(8);
for (i = -1000; i < 1000; i++) { if (unlink("DIR_40/nono") != 0) e(9);
if (i >= 0 && i < OPEN_MAX) continue;
if (lseek(i, (off_t) 0, SEEK_SET) != (off_t) - 1) e(21);
if (lseek(i, (off_t) 0, SEEK_END) != (off_t) - 1) e(22);
if (lseek(i, (off_t) 0, SEEK_CUR) != (off_t) - 1) e(23);
} }
if (!superuser) {
if (link("DIR_40/foo", "DIR_40/nono") != -1) e(10);
if (errno != EACCES) e(11);
if (unlink("DIR_40/foo") != -1) e(12); /* try to rm foo/foo */
if (errno != EACCES) e(13);
}
System("chmod 755 DIR_40"); /* back to normal */
Chdir("DIR_40");
/* Too-long path and name test */
ToLongPath[strlen(ToLongPath) - 2] = '/';
ToLongPath[strlen(ToLongPath) - 1] = 'a'; /* make ././.../a */
if (link("foo", ToLongPath) != -1) e(18); /* path is too long */
if (errno != ENAMETOOLONG) e(19);
if (unlink(ToLongPath) != -1) e(20); /* path is too long */
if (errno != ENAMETOOLONG) e(21);
if (link("foo", "foo") != -1) e(22); /* try linking foo to foo */
if (errno != EEXIST) e(23);
if (link("foo", "bar") != 0) e(24); /* make a link to bar */
if (link("foo", "bar") != -1) e(25); /* try linking to bar again */
if (errno != EEXIST) e(26);
if (link("foo", "bar") != -1) e(27); /* try linking to bar again */
if (errno != EEXIST) e(28);
if (unlink("nono") != -1) e(29); /* try rm <not exist> */
if (errno != ENOENT) e(30);
if (unlink("") != -1) e(31); /* try unlinking empty */
if (errno != ENOENT) e(32);
if (link("foo", "") != -1) e(33); /* try linking to "" */
if (errno != ENOENT) e(34);
if (link("", "foo") != -1) e(35); /* try linking "" */
if (errno != ENOENT) e(36);
if (link("", "") != -1) e(37);/* try linking "" to "" */
if (errno != ENOENT) e(38);
if (link("/foo/bar/foo", "a") != -1) e(39); /* try no existing path */
if (errno != ENOENT) e(40);
if (link("foo", "/foo/bar/foo") != -1) e(41); /* try no existing path */
if (errno != ENOENT) e(42);
if (link("/a/b/c", "/d/e/f") != -1) e(43); /* try no existing path */
if (errno != ENOENT) e(44);
if (link("abc", "a") != -1) e(45); /* try no existing file */
if (errno != ENOENT) e(46);
if (link("foo/bar", "bar") != -1) e(47); /* foo is a file */
if (errno != ENOTDIR) e(48);
if (link("foo", "foo/bar") != -1) e(49); /* foo is not a dir */
if (errno != ENOTDIR) e(50);
if (unlink("foo/bar") != -1) e(51); /* foo still no dir */
if (errno != ENOTDIR) e(52);
if (!superuser) {
if (link(".", "root") != -1) e(55);
if (errno != EPERM) e(56); /* noroot can't */
if (unlink("root") != -1) e(57);
if (errno != ENOENT) e(58);
}
if (mkdir("dir", 0777) != 0) e(59);
if (superuser) {
if (rmdir("dir") != 0) e(63);
}
if (!superuser) {
if (unlink("dir") != -1) e(64);
if (errno != EPERM) e(65); /* that ain't w'rkn */
if (rmdir("dir") != 0) e(66); /* that's the way to do it */
}
}
int stateq(stp1, stp2)
struct stat *stp1, *stp2;
{
if (stp1->st_dev != stp2->st_dev) return 0;
if (stp1->st_ino != stp2->st_ino) return 0;
if (stp1->st_mode != stp2->st_mode) return 0;
if (stp1->st_nlink != stp2->st_nlink) return 0;
if (stp1->st_uid != stp2->st_uid) return 0;
if (stp1->st_gid != stp2->st_gid) return 0;
if (stp1->st_rdev != stp2->st_rdev) return 0;
if (stp1->st_size != stp2->st_size) return 0;
if (stp1->st_atime != stp2->st_atime) return 0;
if (stp1->st_mtime != stp2->st_mtime) return 0;
if (stp1->st_ctime != stp2->st_ctime) return 0;
return 1;
}
void makelongnames()
{
register int i;
memset(MaxName, 'a', NAME_MAX);
MaxName[NAME_MAX] = '\0';
for (i = 0; i < PATH_MAX - 1; i++) { /* idem path */
MaxPath[i++] = '.';
MaxPath[i] = '/';
}
MaxPath[PATH_MAX - 1] = '\0';
strcpy(ToLongName, MaxName); /* copy them Max to ToLong */
strcpy(ToLongPath, MaxPath);
ToLongName[NAME_MAX] = 'a';
ToLongName[NAME_MAX + 1] = '\0'; /* extend ToLongName by one
* too many */
ToLongPath[PATH_MAX - 1] = '/';
ToLongPath[PATH_MAX] = '\0'; /* inc ToLongPath by one */
} }
@ -266,8 +329,8 @@ int n;
void quit() void quit()
{ {
Chdir(".."); chdir("..");
System("rm -rf DIR_40"); system("rm -rf DIR_40");
if (errct == 0) { if (errct == 0) {
printf("ok\n"); printf("ok\n");