Initial revision

This commit is contained in:
Ben Gras
2005-04-21 14:53:53 +00:00
commit 9865aeaa79
2264 changed files with 411685 additions and 0 deletions

75
test/Makefile Normal file
View File

@@ -0,0 +1,75 @@
# Makefile for the tests.
CC = exec cc
CFLAGS= -O -D_MINIX -D_POSIX_SOURCE
OBJ= test1 test2 test3 test4 test5 test6 test7 test8 test9 \
test10 test12 test13 test14 test15 test16 test17 test18 test19 \
test21 test22 test23 test25 test26 test27 test28 test29 \
test30 test31 test32 test34 test35 test36 test37 test38 test39 \
test40 t10a t11a t11b
BIGOBJ= test20 test24
ROOTOBJ= test11 test33
all: $(OBJ) $(BIGOBJ) $(ROOTOBJ)
$(OBJ):
$(CC) $(CFLAGS) -o $@ $@.c
install -S 10kw $@
$(BIGOBJ):
$(CC) $(CFLAGS) -o $@ $@.c
install -S 32kw $@
$(ROOTOBJ):
$(CC) $(CFLAGS) $@.c
install -c -S 10kw -o root -m 4755 a.out $@
rm a.out
clean:
@rm -f *.o *.s *.bak test? test?? t10a t11a t11b DIR*
test1: test1.c
test2: test2.c
test3: test3.c
test4: test4.c
test5: test5.c
test6: test6.c
test7: test7.c
test8: test8.c
test9: test9.c
test10: test10.c
t10a: t10a.c
test11: test11.c
t11a: t11a.c
t11b: t11b.c
test12: test12.c
test13: test13.c
test14: test14.c
test15: test15.c
test16: test16.c
test17: test17.c
test18: test18.c
test19: test19.c
test20: test20.c
test21: test21.c
test22: test22.c
test23: test23.c
test24: test24.c
test25: test25.c
test26: test26.c
test27: test27.c
test28: test28.c
test29: test29.c
test30: test30.c
test31: test31.c
test32: test32.c
test33: test33.c
test34: test34.c
test35: test35.c
test36: test36.c
test37: test37.c
test38: test38.c
test39: test39.c
test40: test40.c

103
test/common.c Normal file
View File

@@ -0,0 +1,103 @@
/* Utility routines for Minix tests.
* This is designed to be #includ'ed near the top of test programs. It is
* self-contained except for MAX_ERRORS.
*/
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
int common_test_nr = -1, errct = 0, subtest;
_PROTOTYPE(void cleanup, (void));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
_PROTOTYPE(void rm_rf_dir, (int test_nr));
_PROTOTYPE(void rm_rf_ppdir, (int test_nr));
_PROTOTYPE(void start, (int test_nr));
void start(test_nr)
int test_nr;
{
char buf[64];
common_test_nr = test_nr;
printf("Test %2d ", test_nr);
fflush(stdout); /* since stdout is probably line buffered */
sync();
rm_rf_dir(test_nr);
sprintf(buf, "mkdir DIR_%02d", test_nr);
if (system(buf) != 0) {
e(666);
quit();
}
sprintf(buf, "DIR_%02d", test_nr);
if (chdir(buf) != 0) {
e(6666);
quit();
}
}
void rm_rf_dir(test_nr)
int test_nr;
{
char buf[128];
/* "rm -rf dir" will not work unless all the subdirectories have suitable
* permissions. Minix chmod is not recursive so it is not easy to change
* all the permissions. I had to fix opendir() to stop the bash shell
* from hanging when it opendir()s fifos.
*/
sprintf(buf, "chmod 777 DIR_%02d DIR_%02d/* DIR_%02d/*/* >/dev/null 2>&1",
test_nr, test_nr, test_nr);
(void) system(buf); /* usually fails */
sprintf(buf, "rm -rf DIR_%02d >/dev/null 2>&1", test_nr);
if (system(buf) != 0) printf("Warning: system(\"%s\") failed\n", buf);
}
void rm_rf_ppdir(test_nr)
int test_nr;
{
/* Attempt to remove everything in the test directory (== the current dir). */
char buf[128];
sprintf(buf, "chmod 777 ../DIR_%02d/* ../DIR_%02d/*/* >/dev/null 2>&1",
test_nr, test_nr);
(void) system(buf);
sprintf(buf, "rm -rf ../DIR_%02d >/dev/null 2>&1", test_nr);
if (system(buf) != 0) printf("Warning: system(\"%s\") failed\n", buf);
}
void e(n)
int n;
{
if (errct == 0) printf("\n"); /* finish header */
printf("Subtest %d, error %d, errno %d: %s\n",
subtest, n, errno, strerror(errno));
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
cleanup();
exit(1);
}
errno = 0; /* don't leave it around to confuse next e() */
}
void cleanup()
{
if (chdir("..") == 0 && common_test_nr != -1) rm_rf_dir(common_test_nr);
}
void quit()
{
cleanup();
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

35
test/run.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/sh
# Initialization
PATH=:/bin:/usr/bin
export PATH
rm -rf DIR* # remove any old junk lying around
passed=`expr 0` # count number of tests run correctly
failed=`expr 0` # count number of tests that failed
total=`expr 0` # total number of tests tried
badones= # list of tests that failed
# Run all the tests, keeping track of who failed.
clr
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
do total=`expr $total + 1`
if test$i
then passed=`expr $passed + 1`
else failed=`expr $failed + 1`
badones=`echo $badones " " $i`
fi
done
# Print results of the tests.
echo " "
if test $total = $passed
then echo All $passed tests completed without error.
else echo Testing completed. Score: $passed passed, $failed failed
echo The following tests failed: $badones
fi
# echo " "
# sh1.sh
# sh2.sh

310
test/sh1.sh Executable file
View File

@@ -0,0 +1,310 @@
#!/bin/sh
# Shell script used to test MINIX.
PATH=:/bin:/usr/bin
export PATH
echo -n "Shell test 1 "
rm -rf DIR_SH1
mkdir DIR_SH1
cd DIR_SH1
f=../test1.c
if test -r $f; then : ; else echo sh1 cannot read $f; exit 1; fi
#Initial setup
echo "abcdefghijklmnopqrstuvwxyz" >alpha
echo "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >ALPHA
echo "0123456789" >num
echo "!@#$%^&*()_+=-{}[]:;<>?/.," >special
cp /etc/rc rc
cp /etc/passwd passwd
cat alpha ALPHA num rc passwd special >tmp
cat tmp tmp tmp >f1
#Test cp
mkdir foo
cp /etc/rc /etc/passwd foo
if cmp -s foo/rc /etc/rc ; then : ; else echo Error on cp test 1; fi
if cmp -s foo/passwd /etc/passwd ; then : ; else echo Error on cp test 2; fi
rm -rf foo
#Test cat
cat num num num num num >y
wc -c y >x1
echo " 55 y" >x2
if cmp -s x1 x2; then : ; else echo Error on cat test 1; fi
cat <y >z
if cmp -s y z; then : ; else echo Error on cat test 2; fi
#Test ar
cat passwd >p
cp passwd q
if cmp -s p q; then : ; else echo Error on ar test 1; fi
date >r
ar r x.a p q r 2>/dev/null
ar r x.a /usr/bin/cp
ar r x.a /usr/bin/cat
rm p q
mv r R
ar x x.a
if cmp -s p /etc/passwd; then : ; else Error on ar test 2; fi
if cmp -s q /etc/passwd; then : ; else Error on ar test 3; fi
if cmp -s r R; then : ; else Error on ar test 4; fi
if cmp -s cp /usr/bin/cp; then : ; else Error on ar test 5; fi
if cmp -s cat /usr/bin/cat; then : ; else Error on ar test 6; fi
rm cp cat p q r
ar d x.a r >/dev/null
ar x x.a
if test -r r; then echo Error on ar test 7; fi
rm -rf p q r R
#Test basename
if test `basename /usr/ast/foo.c .c` != 'foo'
then echo Error on basename test 1
fi
if test `basename a/b/c/d` != 'd'; then Error on basename test 2; fi
#Test cdiff, sed, and patch
cp $f x.c # x.c is a copy $f
echo "/a/s//#####/g" >s # create sed script
sed -f s <x.c >y.c # y.c is new version of x.c
cdiff x.c y.c >y # y is cdiff listing
patch x.c y 2>/dev/null # z should be y.c
if cmp -s x.c y.c; then : ; else echo Error in cdiff test; fi
rm x.c* y.c s y
#Test comm, grep -v
ls /etc >x # x = list of /etc
grep -v "passwd" x >y # y = x except for /etc/passwd
comm -3 x y >z # should only be 1 line, /etc/passwd
echo "passwd" >w
if cmp -s w z; then : else echo Error on comm test 1; fi
comm -13 x y >z # should be empty
if test -s z; then echo Error on comm test 2; fi
rm -rf w x y z
#Test compress
compress -fc $f >x.c.Z # compress the test file
compress -cd x.c.Z >y # uncompress it
if cmp -s $f y; then : else echo Error in compress test 1; fi
rm -rf x.c.Z y
#Test ed
cp $f x # copy $f to x
cat >y <<END
g/a/s//#####/g
g/b/s//@@@@@/g
g/c/s//!!!!!/g
w
q
END
ed x <y >/dev/null
cat >y <<END
g/#####/s//a/g
g/@@@@@/s//b/g
g/!!!!!/s//c/g
w
q
END
ed x <y >/dev/null
if cmp -s x $f; then : ; else echo Error in ed test 1; fi
rm x y
#Test expr
if test `expr 1 + 1` != 2; then echo Error on expr test 1; fi
if test `expr 10000 - 1` != 9999; then echo Error on expr test 2; fi
if test `expr 100 '*' 50` != 5000; then echo Error on expr test 3; fi
if test `expr 120 / 5` != 24; then echo Error on expr test 4; fi
if test `expr 143 % 7` != 3; then echo Error on expr test 5; fi
a=100
a=`expr $a + 1`
if test $a != '101'; then echo Error on expr test 6; fi
#Test fgrep
fgrep "abc" alpha >z
if cmp -s alpha z ; then : else echo Error on fgrep test 1; fi
fgrep "abc" num >z
if test -s z; then echo Error on fgrep test 2; fi
cat alpha num >z
fgrep "012" z >w
if cmp -s w num; then : ; else echo Error fgrep test 3; fi
#Test find
date >Rabbit
echo "Rabbit" >y
find . -name Rabbit -print >z
if cmp -s y z; then : else echo Error on find test 1; fi
find . -name Bunny -print >z
if test -s z; then echo Error on find test 2; fi
rm Rabbit y z
#Test grep
grep "a" alpha >x
if cmp -s x alpha; then : ; else echo Error on grep test 1; fi
grep "a" ALPHA >x
if test -s x; then echo Error on grep test 2; fi
grep -v "0" alpha >x
if cmp -s x alpha; then : ; else echo Error on grep test 3; fi
grep -s "a" alpha >x
if test -s x; then echo Error on grep test 4; fi
if grep -s "a" alpha >x; then : else echo Error on grep test 5; fi
if grep -s "a" ALPHA >x; then echo Error on grep test 6; fi
#Test head
head -1 f1 >x
if cmp -s x alpha; then : else echo Error on head test 1; fi
head -2 f1 >x
cat alpha ALPHA >y
if cmp -s x y; then : else echo Error on head test 2; fi
#Test ls
mkdir FOO
cp passwd FOO/z
cp alpha FOO/x
cp ALPHA FOO/y
cd FOO
ls >w
cat >w1 <<END
w
x
y
z
END
if cmp -s w w1; then : ; else echo Error on ls test 1; fi
rm *
cd ..
rmdir FOO
#Test mkdir/rmdir
mkdir Foo Bar
if test -d Foo; then : ; else echo Error on mkdir test 1; fi
if test -d Bar; then : ; else echo Error on mkdir test 2; fi
rmdir Foo Bar
if test -d Foo; then echo Error on mkdir test 3; fi
if test -d Foo; then echo Error on rmdir test 4; fi
#Test mv
mkdir MVDIR
cp $f x
mv x y
mv y z
if cmp -s $f z; then : ; else echo Error on mv test 1; fi
cp $f x
mv x MVDIR/y
if cmp -s $f MVDIR/y; then : ; else echo Error on mv test 2; fi
#Test rev
rev <f1 | head -1 >ahpla
echo "zyxwvutsrqponmlkjihgfedcba" >x
if cmp -s x ahpla; then : ; else echo Error on rev test 1; fi
rev <$f >x
rev <x >y
if cmp -s $f x; then echo Error on rev test 2; fi
if cmp -s $f y; then : ; else echo error on rev test 3; fi
#Test shar
cp $f w
cp alpha x
cp ALPHA y
cp num z
shar w x y z >x1
rm w x y z
sh <x1 >/dev/null
if cmp -s w $f; then : ; else echo Error on shar test 1; fi
if cmp -s x alpha; then : ; else echo Error on shar test 2; fi
if cmp -s y ALPHA; then : ; else echo Error on shar test 3; fi
if cmp -s z num; then : ; else echo Error on shar test 4; fi
#Test sort
sort <$f >x
wc <$f >x1
wc <x >x2
if cmp -s x1 x2; then : ; else echo Error on sort test 1; fi
cat >x <<END
demit 10
epitonic 40
apoop 20
bibelot 3
comate 4
END
cat >y <<END
apoop 20
bibelot 3
comate 4
demit 10
epitonic 40
END
cat >z <<END
epitonic 40
demit 10
comate 4
bibelot 3
apoop 20
END
sort <x >x1
if cmp -s y x1; then : ; else echo Error on sort test 2; fi
sort -r <x1 >x2
if cmp -s x2 z; then : ; else echo Error on sort test 3; fi
sort +1 -n <x |head -1 >y
echo "bibelot 3" >z
if cmp -s y z; then : ; else echo Error on sort test 4; fi
#Test tail
tail -1 f1 >x
if cmp -s x special; then : ; else echo Error on tail test 1; fi
#Test tsort
cat >x <<END
a d
b e
c f
a c
p z
k p
a k
a b
b c
c d
d e
e f
f k
END
cat >answer <<END
a
b
c
d
e
f
k
p
z
END
tsort <x >y
if cmp -s y answer; then : ; else echo Error on tsort test 1; fi
#Test uue/uud
cp $f x
uue x
if test -s x.uue; then : ; else echo Error on uue/uud test 1; fi
rm x
uud x.uue
if cmp -s x $f; then : ; else echo Error on uue/uud test 2; fi
compress -fc x >x.Z 2>/dev/null
uue x.Z
rm x x.Z
uud x.uue
compress -cd x.Z >x
if cmp -s x $f; then : ; else echo Error on uue/uud test 3; fi
cd ..
rm -rf DIR_SH1
echo ok

260
test/sh2.sh Executable file
View File

@@ -0,0 +1,260 @@
#!/bin/sh
# Shell script #2 used to test MINIX.
PATH=:/bin:/usr/bin
export PATH
# CC="exec cc -wo -F" # nonstandard flags for ACK :-(
CC=cc
ARCH=`arch`
echo -n "Shell test 2 "
rm -rf DIR_SH2
mkdir DIR_SH2 # all files are created here
cd DIR_SH2
cat >file <<END
The time has come the walrus said to talk of many things
Of shoes and ships and sealing wax of cabbages and kings
Of why the sea is boiling hot and whether pigs have wings
END
f=file # scratch file
cat >makefile <<END # create a makefile
all: x.c
@$CC x.c >/dev/null 2>&1
END
cat >x.c <<END # create a C program
#include <stdio.h>
char s[] = {"MS-DOS: Just say no"}; /* used by strings later */
main()
{
int i;
for (i = 15; i < 18; i++) printf("%d\\n",i*i);
}
END
cat >answer <<END # C program should produce these results
225
256
289
END
make
if test -f a.out; then : ; else echo Compilation failed; fi
a.out >x
if test -f x; then : ; else echo No compiler output; fi
if cmp -s x answer; then : ; else echo Error in cc test 1; fi
#Test chmod
echo Hi there folks >x
if test -r x; then : ; else echo Error on chmod test 1; fi
chmod 377 x
if test -r x; then test -w / || echo Error on chmod test 2; fi
chmod 700 x
if test -r x; then : ; else echo Error on chmod test 3; fi
#Test cut
cat >x <<END # x is a test file with 3 columns
1 white bunny
2 gray rabbits
3 brown hares
4 black conies
END
cat >answer <<END # after cutting out cols 3-7, we get this
white
gray
brown
black
END
cut -c 3-7 x >y # extract columns 3-7
if cmp -s y answer; then : ; else echo Error in cut test 1; fi
#Test dd
dd if=$f of=x bs=12 count=1 2>/dev/null # x = bytes 0-11
dd if=$f of=y bs=6 count=4 skip=2 2>/dev/null # y = bytes 11-35
cat x y >z # z = bytes 0-35
dd if=$f of=answer bs=9 count=4 2>/dev/null # answer = bytes 0-35
if cmp -s z answer; then : ; else echo Error in dd test 1; fi
#Test df # hard to make a sensible Test here
rm ?
df >x
if test -r x; then : ; else echo Error in df Test 1; fi
#Test du # see df
rm ?
du >x
if test -r x; then : ; else echo Error in du Test 1; fi
#Test od
head -1 $f |od >x # see if od converts ascii to octal ok
if [ $ARCH = i86 -o $ARCH = i386 ]
then
cat >answer <<END
0000000 064124 020145 064564 062555 064040 071541 061440 066557
0000020 020145 064164 020145 060567 071154 071565 071440 064541
0000040 020144 067564 072040 066141 020153 063157 066440 067141
0000060 020171 064164 067151 071547 000012
0000071
END
else
cat >answer <<END
0000000 052150 062440 072151 066545 020150 060563 020143 067555
0000020 062440 072150 062440 073541 066162 072563 020163 060551
0000040 062040 072157 020164 060554 065440 067546 020155 060556
0000060 074440 072150 064556 063563 005000
0000071
END
fi
if cmp -s x answer; then : ; else echo Error in od test 1; fi
head -1 $f |od -d >x # see if od converts ascii to decimal ok
if [ $ARCH = i86 -o $ARCH = i386 ]
then
cat >answer <<END
0000000 26708 08293 26996 25965 26656 29537 25376 28015
0000020 08293 26740 08293 24951 29292 29557 29472 26977
0000040 08292 28532 29728 27745 08299 26223 27936 28257
0000060 08313 26740 28265 29543 00010
0000071
END
else
cat >answer <<END
0000000 21608 25888 29801 28005 08296 24947 08291 28525
0000020 25888 29800 25888 30561 27762 30067 08307 24937
0000040 25632 29807 08308 24940 27424 28518 08301 24942
0000060 31008 29800 26990 26483 02560
0000071
END
fi
if cmp -s x answer; then : ; else echo Error in od test 2; fi
#Test paste
cat >x <<END
red
green
blue
END
cat >y <<END
rood
groen
blauw
END
cat >answer <<END
red rood
green groen
blue blauw
END
paste x y >z
if cmp -s z answer; then : ; else echo Error in paste test 1; fi
#Test prep
echo >x <<END
"Hi," said Carol, laughing, "How's life?"
END
echo >answer <<END
hi
said
carol
laughing
how's
life
END
if cmp -s x answer; then : ; else echo Error in prep test 1; fi
#Test printenv
printenv >x
if grep HOME x >/dev/null; then : ; else echo Error in printenv test 1; fi
if grep PATH x >/dev/null; then : ; else echo Error in printenv test 2; fi
if grep SHELL x >/dev/null; then : ; else echo Error in printenv test 3; fi
if grep USER x >/dev/null; then : ; else echo Error in printenv test 4; fi
#Test pwd
pwd >Pwd_file
cd `pwd`
pwd >x
if test -s Pwd_file; then : ; else echo Error in pwd test 1; fi
if cmp -s Pwd_file x; then : ; else echo Error in pwd test 2; fi
#Test strings
strings a.out | grep "MS-DOS" >x
cat >answer <<END
MS-DOS: Just say no
END
if cmp -s x answer; then : ; else echo Error in strings test 1; fi
#Test sum
sum $f >x
cat >answer <<END
29904 1
END
if cmp -s x answer; then : ; else echo Error in sum test 1; fi
#Test tee
cat $f | tee x >/dev/null
if cmp -s x $f; then : ; else echo Error in tee test 1; fi
#Test true
if true ; then : ; else echo Error in true test 1; fi
#Test uniq
cat >x <<END
100
200
200
300
END
cat >answer <<END
100
200
300
END
uniq <x >y
if cmp -s y answer; then : ; else echo Error in uniq test 1; fi
#Test pipelines
cat >x <<END
the big black dog
the little white cat
the big white sheep
the little black cat
END
cat >answer <<END
2 big
2 black
2 cat
1 dog
2 little
1 sheep
4 the
2 white
END
prep x | sort | uniq -c >y1
sort +1 <y1 >y
if cmp -s y answer; then : ; else echo Error in pipeline test 1; fi
cat $f $f $f | sort | uniq >x
sort <$f >y
if cmp -s x y; then : ; else echo Error in pipeline test 2; fi
cd ..
rm -rf DIR_SH2
echo ok

8
test/t10a.c Normal file
View File

@@ -0,0 +1,8 @@
#include <stdlib.h>
_PROTOTYPE(int main, (void));
int main()
{
exit(0);
}

71
test/t11a.c Normal file
View File

@@ -0,0 +1,71 @@
/* t11a */
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define MAX_ERROR 4
int errct, subtest=1;
_PROTOTYPE(int main, (int argc, char *argv [], char *envp []));
_PROTOTYPE(int diff, (char *s1, char *s2));
_PROTOTYPE(void e, (int n));
int main(argc, argv, envp)
int argc;
char *argv[], *envp[];
{
/* See if arguments passed ok. */
char aa[4];
if (diff(argv[0], "t11a")) e(21);
if (diff(argv[1], "arg0")) e(22);
if (diff(argv[2], "arg1")) e(23);
if (diff(argv[3], "arg2")) e(24);
if (diff(envp[0], "spring")) e(25);
if (diff(envp[1], "summer")) e(26);
if (argc != 4) e(27);
/* Now see if the files are ok. */
if (read(3, aa, 4) != 2) e(28);
if (aa[0] != 7 || aa[1] != 9) e(29);
if (getuid() == 10) e(30);
if (geteuid() != 10) e(31);
if (getgid() == 20) e(32);
if (getegid() != 20) e(33);
if (open("t1", 0) < 0) e(34);
if (open("t2", 0) < 0) e(35);
exit(100);
}
int diff(s1, s2)
char *s1, *s2;
{
while (1) {
if (*s1 == 0 && *s2 == 0) return(0);
if (*s1 != *s2) return (1);
s1++;
s2++;
}
}
void e(n)
int n;
{
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}

55
test/t11b.c Normal file
View File

@@ -0,0 +1,55 @@
/* t11b */
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define MAX_ERROR 4
int errct, subtest=1;
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(int diff, (char *s1, char *s2));
_PROTOTYPE(void e, (int n));
int main(argc, argv)
int argc;
char *argv[];
{
/* See if arguments passed ok. */
if (diff(argv[0], "t11b")) e(31);
if (diff(argv[1], "abc")) e(32);
if (diff(argv[2], "defghi")) e(33);
if (diff(argv[3], "j")) e(34);
if (argv[4] != 0) e(35);
if (argc != 4) e(36);
exit(75);
}
int diff(s1, s2)
char *s1, *s2;
{
while (1) {
if (*s1 == 0 && *s2 == 0) return(0);
if (*s1 != *s2) return (1);
s1++;
s2++;
}
}
void e(n)
int n;
{
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}

150
test/test1.c Normal file
View File

@@ -0,0 +1,150 @@
/* test 1 */
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define SIGNUM 10
#define MAX_ERROR 4
#define ITERATIONS 10
_VOLATILE int glov, gct;
int errct;
int subtest;
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test1a, (void));
_PROTOTYPE(void parent, (void));
_PROTOTYPE(void child, (int i));
_PROTOTYPE(void test1b, (void));
_PROTOTYPE(void parent1, (int childpid));
_PROTOTYPE(void func, (int s));
_PROTOTYPE(void child1, (void));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 1 ");
fflush(stdout); /* have to flush for child's benefit */
system("rm -rf DIR_01; mkdir DIR_01");
chdir("DIR_01");
for (i = 0; i < ITERATIONS; i++) {
if (m & 00001) test1a();
if (m & 00002) test1b();
}
quit();
return(-1); /* impossible */
}
void test1a()
{
int i, n, pid;
subtest = 1;
n = 4;
for (i = 0; i < n; i++) {
if ((pid = fork())) {
if (pid < 0) {
printf("\nTest 1 fork failed\n");
exit(1);
}
parent();
} else
child(i);
}
}
void parent()
{
int n;
n = getpid();
wait(&n);
}
void child(i)
int i;
{
int n;
n = getpid();
exit(100+i);
}
void test1b()
{
int i, k;
subtest = 2;
for (i = 0; i < 4; i++) {
glov = 0;
signal(SIGNUM, func);
if ((k = fork())) {
if (k < 0) {
printf("Test 1 fork failed\n");
exit(1);
}
parent1(k);
} else
child1();
}
}
void parent1(childpid)
int childpid;
{
int n;
for (n = 0; n < 5000; n++);
while (kill(childpid, SIGNUM) < 0) /* null statement */
;
wait(&n);
}
void func(s)
int s; /* for ANSI */
{
glov++;
gct++;
}
void child1()
{
while (glov == 0);
exit(gct);
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

153
test/test10.c Normal file
View File

@@ -0,0 +1,153 @@
/* test 10 */
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
char *name[] = {"t10a", "t10b", "t10c", "t10d", "t10e", "t10f", "t10g",
"t10h", "t10i", "t10j"};
int errct;
long prog[300];
int psize;
_PROTOTYPE(int main, (void));
_PROTOTYPE(void spawn, (int n));
_PROTOTYPE(void mkfiles, (void));
_PROTOTYPE(void cr_file, (char *name, int size));
_PROTOTYPE(void rmfiles, (void));
_PROTOTYPE(void quit, (void));
int main()
{
int i, n, pid, r;
printf("Test 10 ");
fflush(stdout); /* have to flush for child's benefit */
system("rm -rf DIR_10; mkdir DIR_10; cp t10a DIR_10");
chdir("DIR_10");
pid = getpid();
/* Create files t10b ... t10h */
mkfiles();
if (getpid() == pid)
if (fork() == 0) {
execl("t10a", (char *) 0);
exit(0);
}
if (getpid() == pid)
if (fork() == 0) {
execl("t10b", (char *) 0);
exit(0);
}
if (getpid() == pid)
if (fork() == 0) {
execl("t10c", (char *) 0);
exit(0);
}
if (getpid() == pid)
if (fork() == 0) {
execl("t10d", (char *) 0);
exit(0);
}
srand(100);
for (i = 0; i < 60; i++) {
r = rand() & 07;
spawn(r);
}
for (i = 0; i < 4; i++) wait(&n);
rmfiles();
quit();
return(-1); /* impossible */
}
void spawn(n)
int n;
{
int pid, k;
if (pid = fork()) {
wait(&n); /* wait for some child (any one) */
} else {
k = execl(name[n], (char *) 0);
errct++;
printf("Child execl didn't take. file=%s errno=%d\n", name[n], errno);
rmfiles();
exit(1);
printf("Worse yet, EXIT didn't exit\n");
}
}
void mkfiles()
{
int fd;
fd = open("t10a", 0);
if (fd < 0) {
printf("Can't open t10a\n");
exit(1);
}
psize = read(fd, (char *) prog, 300 * 4);
cr_file("t10b", 1600);
cr_file("t10c", 1400);
cr_file("t10d", 2300);
cr_file("t10e", 3100);
cr_file("t10f", 2400);
cr_file("t10g", 1700);
cr_file("t10h", 1500);
cr_file("t10i", 4000);
cr_file("t10j", 2250);
close(fd);
}
void cr_file(name, size)
char *name;
int size;
{
int fd;
#if (CHIP == SPARC)
size += 4000;
#endif
prog[6] = (long) size;
fd = creat(name, 0755);
write(fd, (char *) prog, psize);
close(fd);
}
void rmfiles()
{
unlink("t10b");
unlink("t10c");
unlink("t10d");
unlink("t10e");
unlink("t10f");
unlink("t10g");
unlink("t10h");
unlink("t10i");
unlink("t10j");
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

228
test/test11.c Normal file
View File

@@ -0,0 +1,228 @@
/* test 11 */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define ITERATIONS 10
#define MAX_ERROR 1
int errct, subtest;
char *envp[3] = {"spring", "summer", 0};
char *passwd_file = "/etc/passwd";
_PROTOTYPE(int main, (int argc, char *argv[]));
_PROTOTYPE(void test11a, (void));
_PROTOTYPE(void test11b, (void));
_PROTOTYPE(void test11c, (void));
_PROTOTYPE(void test11d, (void));
_PROTOTYPE(void e, (int n));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
if (argc == 2) m = atoi(argv[1]);
printf("Test 11 ");
fflush(stdout); /* have to flush for child's benefit */
if (geteuid() != 0) {
printf("must be setuid root; test aborted\n");
exit(1);
}
if (getuid() == 0) {
printf("must be setuid root logged in as someone else; test aborted\n");
exit(1);
}
/*
system("rm -rf DIR_11; mkdir DIR_11");
chdir("DIR_11");
*/
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test11a();
if (m & 0002) test11b();
if (m & 0004) test11c();
if (m & 0010) test11d();
}
if (errct == 0)
printf("ok\n");
else
printf(" %d errors\n", errct);
/*
chdir("..");
system("rm -rf DIR_11");
*/
return(0);
}
void test11a()
{
/* Test exec */
int n, fd;
char aa[4];
subtest = 1;
if (fork()) {
wait(&n);
if (n != 25600) e(1);
unlink("t1");
unlink("t2");
} else {
if (chown("t11a", 10, 20) < 0) e(2);
chmod("t11a", 0666);
/* The following call should fail because the mode has no X
* bits on. If a bug lets it unexpectedly succeed, the child
* will print an error message since the arguments are wrong.
*/
execl("t11a", (char *) 0, envp); /* should fail -- no X bits */
/* Control should come here after the failed execl(). */
chmod("t11a", 06555);
if ((fd = creat("t1", 0600)) != 3) e(3);
if (close(fd) < 0) e(4);
if (open("t1", O_RDWR) != 3) e(5);
if (chown("t1", 10, 99) < 0) e(6);
if ((fd = creat("t2", 0060)) != 4) e(7);
if (close(fd) < 0) e(8);
if (open("t2", O_RDWR) != 4) e(9);
if (chown("t2", 99, 20) < 0) e(10);
if (setgid(6) < 0) e(11);
if (setuid(5) < 0) e(12);
if (getuid() != 5) e(13);
if (geteuid() != 5) e(14);
if (getgid() != 6) e(15);
if (getegid() != 6) e(16);
aa[0] = 3;
aa[1] = 5;
aa[2] = 7;
aa[3] = 9;
if (write(3, aa, 4) != 4) e(17);
lseek(3, 2L, 0);
execle("t11a", "t11a", "arg0", "arg1", "arg2", (char *) 0, envp);
e(18);
printf("Can't exec t11a\n");
exit(3);
}
}
void test11b()
{
int n;
char *argv[5];
subtest = 2;
if (fork()) {
wait(&n);
if (n != (75 << 8)) e(20);
} else {
/* Child tests execv. */
argv[0] = "t11b";
argv[1] = "abc";
argv[2] = "defghi";
argv[3] = "j";
argv[4] = 0;
execv("t11b", argv);
e(19);
}
}
void test11c()
{
/* Test getlogin() and cuserid(). This test MUST run setuid root. */
int n, etc_uid;
uid_t ruid, euid;
char *lnamep, *cnamep, *p;
char array[L_cuserid], save[L_cuserid], save2[L_cuserid];
FILE *stream;
subtest = 3;
errno = -2000; /* None of these calls set errno. */
array[0] = '@';
array[1] = '0';
save[0] = '#';
save[1] = '0';
ruid = getuid();
euid = geteuid();
lnamep = getlogin();
strcpy(save, lnamep);
cnamep = cuserid(array);
strcpy(save2, cnamep);
/* Because we are setuid root, cuser == array == 'root'; login != 'root' */
if (euid != 0) e(1);
if (ruid == 0) e(2);
if (strcmp(cnamep, "root") != 0) e(3);
if (strcmp(array, "root") != 0) e(4);
if ( (n = strlen(save)) == 0) e(5);
if (strcmp(save, cnamep) == 0) e(6); /* they must be different */
cnamep = cuserid(NULL);
if (strcmp(cnamep, save2) != 0) e(7);
/* Check login against passwd file. First lookup login in /etc/passwd. */
if (n == 0) return; /* if login not found, don't look it up */
if ( (stream = fopen(passwd_file, "r")) == NULL) e(8);
while (fgets(array, L_cuserid, stream) != NULL) {
if (strncmp(array, save, n) == 0) {
p = &array[0]; /* hunt for uid */
while (*p != ':') p++;
p++;
while (*p != ':') p++;
p++; /* p now points to uid */
etc_uid = atoi(p);
if (etc_uid != ruid) e(9);
break; /* 1 entry per login please */
}
}
fclose(stream);
}
void test11d()
{
int fd;
struct stat statbuf;
subtest = 4;
fd = creat("T11.1", 0750);
if (fd < 0) e(1);
if (chown("T11.1", 8, 1) != 0) e(2);
if (chmod("T11.1", 0666) != 0) e(3);
if (stat("T11.1", &statbuf) != 0) e(4);
if ((statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != 0666) e(5);
if (close(fd) != 0) e(6);
if (unlink("T11.1") != 0) e(7);
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}

55
test/test12.c Normal file
View File

@@ -0,0 +1,55 @@
/* test 12 */
/* Copyright (C) 1987 by Martin Leisner. All rights reserved. */
/* Used by permission. */
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define NUM_TIMES 1000
int errct = 0;
_PROTOTYPE(int main, (void));
_PROTOTYPE(void quit, (void));
int main()
{
register int i;
int k;
printf("Test 12 ");
fflush(stdout); /* have to flush for child's benefit */
system("rm -rf DIR_12; mkdir DIR_12");
chdir("DIR_12");
for (i = 0; i < NUM_TIMES; i++) switch (fork()) {
case 0: exit(1); break;
case -1:
printf("fork broke\n");
exit(1);
default: wait(&k); break;
}
quit();
return(-1); /* impossible */
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

72
test/test13.c Normal file
View File

@@ -0,0 +1,72 @@
/* test 13 */
/* File: pipes.c - created by Marty Leisner */
/* Leisner.Henr 1-Dec-87 8:55:04 */
/* Copyright (C) 1987 by Martin Leisner. All rights reserved. */
/* Used by permission. */
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define BLOCK_SIZE 1000
#define NUM_BLOCKS 1000
int errct = 0;
char buffer[BLOCK_SIZE];
_PROTOTYPE(int main, (void));
_PROTOTYPE(void quit, (void));
int main()
{
int stat_loc, pipefd[2];
register int i;
pipe(pipefd);
printf("Test 13 ");
fflush(stdout); /* have to flush for child's benefit */
system("rm -rf DIR_13; mkdir DIR_13");
chdir("DIR_13");
pipe(pipefd);
switch (fork()) {
case 0:
/* Child code */
for (i = 0; i < NUM_BLOCKS; i++)
if (read(pipefd[0], buffer, BLOCK_SIZE) != BLOCK_SIZE) break;
exit(0);
case -1:
perror("fork broke");
exit(1);
default:
/* Parent code */
for (i = 0; i < NUM_BLOCKS; i++) write(pipefd[1], buffer, BLOCK_SIZE);
wait(&stat_loc);
break;
}
quit();
return(-1); /* impossible */
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

82
test/test14.c Normal file
View File

@@ -0,0 +1,82 @@
/* Test 14. unlinking an open file. */
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define TRIALS 100
#define MAX_ERROR 4
char name[20] = {"TMP14."};
int errct;
int subtest = 1;
_PROTOTYPE(int main, (void));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
int main()
{
int fd0, i, pid;
printf("Test 14 ");
fflush(stdout);
system("rm -rf DIR_14; mkdir DIR_14");
chdir("DIR_14");
pid = getpid();
name[6] = (pid & 037) + 33;
name[7] = ((pid * pid) & 037) + 33;
name[8] = 0;
for (i = 0; i < TRIALS; i++) {
if ( (fd0 = creat(name, 0777)) < 0) e(1);
if (write(fd0, name, 20) != 20) e(2);
if (unlink(name) != 0) e(3);
if (close(fd0) != 0) e(4);
}
fd0 = creat(name, 0777);
write(fd0, name, 20);
unlink(name);
quit();
return(-1); /* impossible */
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

705
test/test15.c Normal file
View File

@@ -0,0 +1,705 @@
/* Test program for string(3) routines.
*
* Slightly modified from Henry Spencer's original routine.
* - incorporates semantic changes per the ANSI standard (original tests
* can be recovered by defining the symbol NOT_ANSI while compiling,
* except for the change of memcpy() to memmove()).
* - makes additional tests of functions on unaligned buffers and strings.
*/
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
_PROTOTYPE( int chdir, (char *_path)); /* from <unistd.h> */
#define STREQ(a, b) (strcmp((a), (b)) == 0)
char *it = "<UNSET>"; /* Routine name for message routines. */
int errct; /* count errors */
int waserror = 0; /* For exit status. */
char uctest[] = "\004\203"; /* For testing signedness of chars. */
int charsigned; /* Result. */
_PROTOTYPE(void check, (int thing, int number));
_PROTOTYPE(void equal, (char *a, char *b, int number));
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void first, (void));
_PROTOTYPE(void second, (void));
_PROTOTYPE(void quit, (void));
/*
- check - complain if condition is not true
*/
void check(thing, number)
int thing;
int number; /* Test number for error message. */
{
if (!thing) {
printf("%s flunked test %d\n", it, number);
waserror = 1;
errct++;
}
}
/*
- equal - complain if first two args don't strcmp as equal
*/
void equal(a, b, number)
char *a;
char *b;
int number; /* Test number for error message. */
{
check(a != NULL && b != NULL && STREQ(a, b), number);
}
char one[50];
char two[50];
#ifdef UNIXERR
#define ERR 1
#endif
#ifdef BERKERR
#define ERR 1
#endif
#ifdef ERR
int f;
extern char *sys_errlist[];
extern int sys_nerr;
#endif
/* ARGSUSED */
int main(argc, argv)
int argc;
char *argv[];
{
printf("Test 15 ");
fflush(stdout);
system("rm -rf DIR_15; mkdir DIR_15");
chdir("DIR_15");
/* First, establish whether chars are signed. */
if (uctest[0] < uctest[1])
charsigned = 0;
else
charsigned = 1;
/* Then, do the rest of the work. Split into two functions because
* some compilers get unhappy about a single immense function. */
first();
second();
errct = waserror;
quit();
return(-1); /* impossible */
}
void first()
{
/* Test strcmp first because we use it to test other things. */
it = "strcmp";
check(strcmp("", "") == 0, 1);/* Trivial case. */
check(strcmp("a", "a") == 0, 2); /* Identity. */
check(strcmp("abc", "abc") == 0, 3); /* Multicharacter. */
check(strcmp("abc", "abcd") < 0, 4); /* Length mismatches. */
check(strcmp("abcd", "abc") > 0, 5);
check(strcmp("abcd", "abce") < 0, 6); /* Honest miscompares. */
check(strcmp("abce", "abcd") > 0, 7);
check(strcmp("a\203", "a") > 0, 8); /* Tricky if char signed. */
#ifdef NOT_ANSI
if (charsigned)
check(strcmp("a\203", "a\003") < 0, 9);
else
check(strcmp("a\203", "a\003") > 0, 9);
#else
check(strcmp("a\203", "a\003") > 0, 9);
#endif
check(strcmp("abcd" + 1, "abcd" + 1) == 0, 10); /* Unaligned tests. */
check(strcmp("abcd" + 1, "abce" + 1) < 0, 11);
check(strcmp("abcd" + 1, "bcd") == 0, 12);
check(strcmp("abce" + 1, "bcd") > 0, 13);
check(strcmp("abcd" + 2, "bcd" + 1) == 0, 14);
check(strcmp("abcd" + 2, "bce" + 1) < 0, 15);
/* Test strcpy next because we need it to set up other tests. */
it = "strcpy";
check(strcpy(one, "abcd") == one, 1); /* Returned value. */
equal(one, "abcd", 2); /* Basic test. */
(void) strcpy(one, "x");
equal(one, "x", 3); /* Writeover. */
equal(one + 2, "cd", 4); /* Wrote too much? */
(void) strcpy(two, "hi there");
(void) strcpy(one, two);
equal(one, "hi there", 5); /* Basic test encore. */
equal(two, "hi there", 6); /* Stomped on source? */
(void) strcpy(one, "");
equal(one, "", 7); /* Boundary condition. */
(void) strcpy(one, "abcdef" + 1); /* Unaligned tests. */
equal(one, "bcdef", 8);
(void) strcpy(one + 1, "*xy" + 1);
equal(one, "bxy", 9);
equal(one + 4, "f", 10);
/* Strcat */
it = "strcat";
(void) strcpy(one, "ijk");
check(strcat(one, "lmn") == one, 1); /* Returned value. */
equal(one, "ijklmn", 2); /* Basic test. */
(void) strcpy(one, "x");
(void) strcat(one, "yz");
equal(one, "xyz", 3); /* Writeover. */
equal(one + 4, "mn", 4); /* Wrote too much? */
(void) strcpy(one, "gh");
(void) strcpy(two, "ef");
(void) strcat(one, two);
equal(one, "ghef", 5); /* Basic test encore. */
equal(two, "ef", 6); /* Stomped on source? */
(void) strcpy(one, "");
(void) strcat(one, "");
equal(one, "", 7); /* Boundary conditions. */
(void) strcpy(one, "ab");
(void) strcat(one, "");
equal(one, "ab", 8);
(void) strcpy(one, "");
(void) strcat(one, "cd");
equal(one, "cd", 9);
/* Strncat - first test it as strcat, with big counts, then test the
* count mechanism. */
it = "strncat";
(void) strcpy(one, "ijk");
check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */
equal(one, "ijklmn", 2); /* Basic test. */
(void) strcpy(one, "x");
(void) strncat(one, "yz", 99);
equal(one, "xyz", 3); /* Writeover. */
equal(one + 4, "mn", 4); /* Wrote too much? */
(void) strcpy(one, "gh");
(void) strcpy(two, "ef");
(void) strncat(one, two, 99);
equal(one, "ghef", 5); /* Basic test encore. */
equal(two, "ef", 6); /* Stomped on source? */
(void) strcpy(one, "");
(void) strncat(one, "", 99);
equal(one, "", 7); /* Boundary conditions. */
(void) strcpy(one, "ab");
(void) strncat(one, "", 99);
equal(one, "ab", 8);
(void) strcpy(one, "");
(void) strncat(one, "cd", 99);
equal(one, "cd", 9);
(void) strcpy(one, "ab");
(void) strncat(one, "cdef", 2);
equal(one, "abcd", 10); /* Count-limited. */
(void) strncat(one, "gh", 0);
equal(one, "abcd", 11); /* Zero count. */
(void) strncat(one, "gh", 2);
equal(one, "abcdgh", 12); /* Count and length equal. */
(void) strcpy(one, "abcdefghij"); /* Unaligned tests. */
(void) strcpy(one, "abcd");
(void) strcpy(one, "abc");
(void) strncat(one, "de" + 1, 1);
equal(one, "abce", 13);
equal(one + 4, "", 14);
equal(one + 5, "fghij", 15);
/* Strncmp - first test as strcmp with big counts, then test count code. */
it = "strncmp";
check(strncmp("", "", 99) == 0, 1); /* Trivial case. */
check(strncmp("a", "a", 99) == 0, 2); /* Identity. */
check(strncmp("abc", "abc", 99) == 0, 3); /* Multicharacter. */
check(strncmp("abc", "abcd", 99) < 0, 4); /* Length unequal. */
check(strncmp("abcd", "abc", 99) > 0, 5);
check(strncmp("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
check(strncmp("abce", "abcd", 99) > 0, 7);
check(strncmp("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
#ifdef NOT_ANSI
if (charsigned)
check(strncmp("a\203", "a\003", 2) < 0, 9);
else
check(strncmp("a\203", "a\003", 2) > 0, 9);
#else
check(strncmp("a\203", "a\003", 2) > 0, 9);
#endif
check(strncmp("abce", "abcd", 3) == 0, 10); /* Count limited. */
check(strncmp("abce", "abc", 3) == 0, 11); /* Count == length. */
check(strncmp("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
check(strncmp("abc", "def", 0) == 0, 13); /* Zero count. */
/* Strncpy - testing is a bit different because of odd semantics */
it = "strncpy";
check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
(void) strcpy(one, "abcdefgh");
(void) strncpy(one, "xyz", 2);
equal(one, "xycdefgh", 3); /* Copy cut by count. */
(void) strcpy(one, "abcdefgh");
(void) strncpy(one, "xyz", 3);/* Copy cut just before NUL. */
equal(one, "xyzdefgh", 4);
(void) strcpy(one, "abcdefgh");
(void) strncpy(one, "xyz", 4);/* Copy just includes NUL. */
equal(one, "xyz", 5);
equal(one + 4, "efgh", 6); /* Wrote too much? */
(void) strcpy(one, "abcdefgh");
(void) strncpy(one, "xyz", 5);/* Copy includes padding. */
equal(one, "xyz", 7);
equal(one + 4, "", 8);
equal(one + 5, "fgh", 9);
(void) strcpy(one, "abc");
(void) strncpy(one, "xyz", 0);/* Zero-length copy. */
equal(one, "abc", 10);
(void) strncpy(one, "", 2); /* Zero-length source. */
equal(one, "", 11);
equal(one + 1, "", 12);
equal(one + 2, "c", 13);
(void) strcpy(one, "hi there");
(void) strncpy(two, one, 9);
equal(two, "hi there", 14); /* Just paranoia. */
equal(one, "hi there", 15); /* Stomped on source? */
/* Strlen */
it = "strlen";
check(strlen("") == 0, 1); /* Empty. */
check(strlen("a") == 1, 2); /* Single char. */
check(strlen("abcd") == 4, 3);/* Multiple chars. */
check(strlen("abcd" + 1) == 3, 4); /* Unaligned test. */
/* Strchr */
it = "strchr";
check(strchr("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
check(strchr(one, 'c') == one + 2, 2); /* Basic test. */
check(strchr(one, 'd') == one + 3, 3); /* End of string. */
check(strchr(one, 'a') == one, 4); /* Beginning. */
check(strchr(one, '\0') == one + 4, 5); /* Finding NUL. */
(void) strcpy(one, "ababa");
check(strchr(one, 'b') == one + 1, 6); /* Finding first. */
(void) strcpy(one, "");
check(strchr(one, 'b') == NULL, 7); /* Empty string. */
check(strchr(one, '\0') == one, 8); /* NUL in empty string. */
/* Index - just like strchr */
it = "index";
check(index("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
check(index(one, 'c') == one + 2, 2); /* Basic test. */
check(index(one, 'd') == one + 3, 3); /* End of string. */
check(index(one, 'a') == one, 4); /* Beginning. */
check(index(one, '\0') == one + 4, 5); /* Finding NUL. */
(void) strcpy(one, "ababa");
check(index(one, 'b') == one + 1, 6); /* Finding first. */
(void) strcpy(one, "");
check(index(one, 'b') == NULL, 7); /* Empty string. */
check(index(one, '\0') == one, 8); /* NUL in empty string. */
/* Strrchr */
it = "strrchr";
check(strrchr("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
check(strrchr(one, 'c') == one + 2, 2); /* Basic test. */
check(strrchr(one, 'd') == one + 3, 3); /* End of string. */
check(strrchr(one, 'a') == one, 4); /* Beginning. */
check(strrchr(one, '\0') == one + 4, 5); /* Finding NUL. */
(void) strcpy(one, "ababa");
check(strrchr(one, 'b') == one + 3, 6); /* Finding last. */
(void) strcpy(one, "");
check(strrchr(one, 'b') == NULL, 7); /* Empty string. */
check(strrchr(one, '\0') == one, 8); /* NUL in empty string. */
/* Rindex - just like strrchr */
it = "rindex";
check(rindex("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
check(rindex(one, 'c') == one + 2, 2); /* Basic test. */
check(rindex(one, 'd') == one + 3, 3); /* End of string. */
check(rindex(one, 'a') == one, 4); /* Beginning. */
check(rindex(one, '\0') == one + 4, 5); /* Finding NUL. */
(void) strcpy(one, "ababa");
check(rindex(one, 'b') == one + 3, 6); /* Finding last. */
(void) strcpy(one, "");
check(rindex(one, 'b') == NULL, 7); /* Empty string. */
check(rindex(one, '\0') == one, 8); /* NUL in empty string. */
}
void second()
{
/* Strpbrk - somewhat like strchr */
it = "strpbrk";
check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
check(strpbrk(one, "c") == one + 2, 2); /* Basic test. */
check(strpbrk(one, "d") == one + 3, 3); /* End of string. */
check(strpbrk(one, "a") == one, 4); /* Beginning. */
check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
check(strpbrk(one, "cb") == one + 1, 6); /* Multiple search. */
(void) strcpy(one, "abcabdea");
check(strpbrk(one, "b") == one + 1, 7); /* Finding first. */
check(strpbrk(one, "cb") == one + 1, 8); /* With multiple search. */
check(strpbrk(one, "db") == one + 1, 9); /* Another variant. */
(void) strcpy(one, "");
check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
/* Strstr - somewhat like strchr */
it = "strstr";
check(strstr("abcd", "z") == NULL, 1); /* Not found. */
check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
(void) strcpy(one, "abcd");
check(strstr(one, "c") == one + 2, 3); /* Basic test. */
check(strstr(one, "bc") == one + 1, 4); /* Multichar. */
check(strstr(one, "d") == one + 3, 5); /* End of string. */
check(strstr(one, "cd") == one + 2, 6); /* Tail of string. */
check(strstr(one, "abc") == one, 7); /* Beginning. */
check(strstr(one, "abcd") == one, 8); /* Exact match. */
check(strstr(one, "abcde") == NULL, 9); /* Too long. */
check(strstr(one, "de") == NULL, 10); /* Past end. */
#ifdef NOT_ANSI
check(strstr(one, "") == one + 4, 11); /* Finding empty. */
#else
check(strstr(one, "") == one, 11); /* Finding empty. */
#endif
(void) strcpy(one, "ababa");
check(strstr(one, "ba") == one + 1, 12); /* Finding first. */
(void) strcpy(one, "");
check(strstr(one, "b") == NULL, 13); /* Empty string. */
check(strstr(one, "") == one, 14); /* Empty in empty string. */
(void) strcpy(one, "bcbca");
check(strstr(one, "bca") == one + 2, 15); /* False start. */
(void) strcpy(one, "bbbcabbca");
check(strstr(one, "bbca") == one + 1, 16); /* With overlap. */
/* Strspn */
it = "strspn";
check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
check(strspn("abcba", "ab") == 2, 2); /* Partial. */
check(strspn("abc", "qx") == 0, 3); /* None. */
check(strspn("", "ab") == 0, 4); /* Null string. */
check(strspn("abc", "") == 0, 5); /* Null search list. */
/* Strcspn */
it = "strcspn";
check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
check(strcspn("abc", "abc") == 0, 3); /* None. */
check(strcspn("", "ab") == 0, 4); /* Null string. */
check(strcspn("abc", "") == 3, 5); /* Null search list. */
/* Strtok - the hard one */
it = "strtok";
(void) strcpy(one, "first, second, third");
equal(strtok(one, ", "), "first", 1); /* Basic test. */
equal(one, "first", 2);
equal(strtok((char *) NULL, ", "), "second", 3);
equal(strtok((char *) NULL, ", "), "third", 4);
check(strtok((char *) NULL, ", ") == NULL, 5);
(void) strcpy(one, ", first, ");
equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
check(strtok((char *) NULL, ", ") == NULL, 7);
(void) strcpy(one, "1a, 1b; 2a, 2b");
equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
equal(strtok((char *) NULL, "; "), "1b", 9);
equal(strtok((char *) NULL, ", "), "2a", 10);
(void) strcpy(two, "x-y");
equal(strtok(two, "-"), "x", 11); /* New string before done. */
equal(strtok((char *) NULL, "-"), "y", 12);
check(strtok((char *) NULL, "-") == NULL, 13);
(void) strcpy(one, "a,b, c,, ,d");
equal(strtok(one, ", "), "a", 14); /* Different separators. */
equal(strtok((char *) NULL, ", "), "b", 15);
equal(strtok((char *) NULL, " ,"), "c", 16); /* Permute list too. */
equal(strtok((char *) NULL, " ,"), "d", 17);
check(strtok((char *) NULL, ", ") == NULL, 18);
check(strtok((char *) NULL, ", ") == NULL, 19); /* Persistence. */
(void) strcpy(one, ", ");
check(strtok(one, ", ") == NULL, 20); /* No tokens. */
(void) strcpy(one, "");
check(strtok(one, ", ") == NULL, 21); /* Empty string. */
(void) strcpy(one, "abc");
equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
check(strtok((char *) NULL, ", ") == NULL, 23);
(void) strcpy(one, "abc");
equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
check(strtok((char *) NULL, "") == NULL, 25);
(void) strcpy(one, "abcdefgh");
(void) strcpy(one, "a,b,c");
equal(strtok(one, ","), "a", 26); /* Basics again... */
equal(strtok((char *) NULL, ","), "b", 27);
equal(strtok((char *) NULL, ","), "c", 28);
check(strtok((char *) NULL, ",") == NULL, 29);
equal(one + 6, "gh", 30); /* Stomped past end? */
equal(one, "a", 31); /* Stomped old tokens? */
equal(one + 2, "b", 32);
equal(one + 4, "c", 33);
/* Memcmp */
it = "memcmp";
check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
check(memcmp("abce", "abcd", 4) > 0, 4);
check(memcmp("alph", "beta", 4) < 0, 5);
#ifdef NOT_ANSI
if (charsigned)
check(memcmp("a\203", "a\003", 2) < 0, 6);
else
check(memcmp("a\203", "a\003", 2) > 0, 6);
#else
check(memcmp("a\203", "a\003", 2) > 0, 6);
#endif
check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
check(memcmp("a" + 1, "a" + 1, 1) == 0, 9); /* Unaligned tests. */
check(memcmp("abc" + 1, "bc", 2) == 0, 10);
check(memcmp("bc", "abc" + 1, 2) == 0, 11);
check(memcmp("abcd" + 1, "abce" + 1, 3) < 0, 12);
check(memcmp("abce" + 1, "abcd" + 1, 3) > 0, 13);
/*
check(memcmp("a\203" + 1, "a\003" + 1, 1) > 0, 14);
*/
check(memcmp("abcde" + 1, "abcdf" + 1, 3) == 0, 15);
/* Memchr */
it = "memchr";
check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
check( (char *)memchr(one, 'c', 4) == one + 2, 2); /* Basic test. */
check( (char *)memchr(one, 'd', 4) == one + 3, 3); /* End of string. */
check( (char *)memchr(one, 'a', 4) == one, 4); /* Beginning. */
check( (char *)memchr(one, '\0', 5) == one + 4, 5); /* Finding NUL. */
(void) strcpy(one, "ababa");
check( (char *)memchr(one, 'b', 5) == one + 1, 6); /* Finding first. */
check( (char *)memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
check( (char *)memchr(one, 'a', 1) == one, 8); /* Singleton case. */
(void) strcpy(one, "a\203b");
check( (char *)memchr(one, 0203, 3) == one + 1, 9); /* Unsignedness. */
/* Memcpy
* Note that X3J11 says memcpy may fail on overlap. */
it = "memcpy";
check( (char *)memcpy(one, "abc", 4) == one, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
(void) strcpy(one, "abcdefgh");
(void) memcpy(one + 1, "xyz", 2);
equal(one, "axydefgh", 3); /* Basic test. */
(void) strcpy(one, "abc");
(void) memcpy(one, "xyz", 0);
equal(one, "abc", 4); /* Zero-length copy. */
(void) strcpy(one, "hi there");
(void) strcpy(two, "foo");
(void) memcpy(two, one, 9);
equal(two, "hi there", 5); /* Just paranoia. */
equal(one, "hi there", 6); /* Stomped on source? */
(void) strcpy(one, "abcde"); /* Unaligned tests. */
(void) memcpy(one + 1, "\0\0\0\0\0", 1);
equal(one, "a", 7);
equal(one + 2, "cde", 8);
(void) memcpy(one + 1, "xyz" + 1, 2);
equal(one, "ayzde", 9);
(void) memcpy(one + 1, "xyz" + 1, 3);
equal(one, "ayz", 10);
/* Memmove
* Note that X3J11 says memmove must work regardless of overlap. */
it = "memmove";
check( (char *)memmove(one, "abc", 4) == one, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
(void) strcpy(one, "abcdefgh");
(void) memmove(one + 1, "xyz", 2);
equal(one, "axydefgh", 3); /* Basic test. */
(void) strcpy(one, "abc");
(void) memmove(one, "xyz", 0);
equal(one, "abc", 4); /* Zero-length copy. */
(void) strcpy(one, "hi there");
(void) strcpy(two, "foo");
(void) memmove(two, one, 9);
equal(two, "hi there", 5); /* Just paranoia. */
equal(one, "hi there", 6); /* Stomped on source? */
(void) strcpy(one, "abcdefgh");
(void) memmove(one + 1, one, 9);
equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
(void) strcpy(one, "abcdefgh");
(void) memmove(one + 1, one + 2, 7);
equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
(void) strcpy(one, "abcdefgh");
(void) memmove(one, one, 9);
equal(one, "abcdefgh", 9); /* 100% overlap. */
(void) strcpy(one, "abcde"); /* Unaligned tests. */
(void) memmove(one + 1, "\0\0\0\0\0", 1);
equal(one, "a", 10);
equal(one + 2, "cde", 11);
(void) memmove(one + 1, "xyz" + 1, 2);
equal(one, "ayzde", 12);
(void) memmove(one + 1, "xyz" + 1, 3);
equal(one, "ayz", 13);
(void) strcpy(one, "abcdefgh");
(void) memmove(one + 2, one + 1, 8);
equal(one, "abbcdefgh", 14);
/* Memccpy - first test like memcpy, then the search part
* The SVID, the only place where memccpy is mentioned, says overlap
* might fail, so we don't try it. Besides, it's hard to see the
* rationale for a non-left-to-right memccpy. */
it = "memccpy";
check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
(void) strcpy(one, "abcdefgh");
(void) memccpy(one + 1, "xyz", 'q', 2);
equal(one, "axydefgh", 3); /* Basic test. */
(void) strcpy(one, "abc");
(void) memccpy(one, "xyz", 'q', 0);
equal(one, "abc", 4); /* Zero-length copy. */
(void) strcpy(one, "hi there");
(void) strcpy(two, "foo");
(void) memccpy(two, one, 'q', 9);
equal(two, "hi there", 5); /* Just paranoia. */
equal(one, "hi there", 6); /* Stomped on source? */
(void) strcpy(one, "abcdefgh");
(void) strcpy(two, "horsefeathers");
check( (char *)memccpy(two, one, 'f', 9) == two + 6, 7);/* Returned value. */
equal(one, "abcdefgh", 8); /* Source intact? */
equal(two, "abcdefeathers", 9); /* Copy correct? */
(void) strcpy(one, "abcd");
(void) strcpy(two, "bumblebee");
check((char *)memccpy(two, one, 'a', 4) == two + 1, 10); /* First char. */
equal(two, "aumblebee", 11);
check((char *)memccpy(two, one, 'd', 4) == two + 4, 12); /* Last char. */
equal(two, "abcdlebee", 13);
(void) strcpy(one, "xyz");
check((char *)memccpy(two, one, 'x', 1) == two + 1, 14); /* Singleton. */
equal(two, "xbcdlebee", 15);
/* Memset */
it = "memset";
(void) strcpy(one, "abcdefgh");
check( (char *) memset(one + 1, 'x', 3) == one + 1, 1); /* Return value. */
equal(one, "axxxefgh", 2); /* Basic test. */
(void) memset(one + 2, 'y', 0);
equal(one, "axxxefgh", 3); /* Zero-length set. */
(void) memset(one + 5, 0, 1);
equal(one, "axxxe", 4); /* Zero fill. */
equal(one + 6, "gh", 5); /* And the leftover. */
(void) memset(one + 2, 010045, 1);
equal(one, "ax\045xe", 6); /* Unsigned char convert. */
/* Bcopy - much like memcpy
* Berklix manual is silent about overlap, so don't test it. */
it = "bcopy";
(void) bcopy("abc", one, 4);
equal(one, "abc", 1); /* Simple copy. */
(void) strcpy(one, "abcdefgh");
(void) bcopy("xyz", one + 1, 2);
equal(one, "axydefgh", 2); /* Basic test. */
(void) strcpy(one, "abc");
(void) bcopy("xyz", one, 0);
equal(one, "abc", 3); /* Zero-length copy. */
(void) strcpy(one, "hi there");
(void) strcpy(two, "foo");
(void) bcopy(one, two, 9);
equal(two, "hi there", 4); /* Just paranoia. */
equal(one, "hi there", 5); /* Stomped on source? */
/* Bzero */
it = "bzero";
(void) strcpy(one, "abcdef");
bzero(one + 2, 2);
equal(one, "ab", 1); /* Basic test. */
equal(one + 3, "", 2);
equal(one + 4, "ef", 3);
(void) strcpy(one, "abcdef");
bzero(one + 2, 0);
equal(one, "abcdef", 4); /* Zero-length copy. */
/* Bcmp - somewhat like memcmp */
it = "bcmp";
check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
check(bcmp("abce", "abcd", 4) != 0, 4);
check(bcmp("alph", "beta", 4) != 0, 5);
check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
#ifdef ERR
/* Strerror - VERY system-dependent */
it = "strerror";
f = open("/", O_WRONLY); /* Should always fail. */
check(f < 0 && errno > 0 && errno < sys_nerr, 1);
equal(strerror(errno), sys_errlist[errno], 2);
#ifdef UNIXERR
equal(strerror(errno), "Is a directory", 3);
#endif
#ifdef BERKERR
equal(strerror(errno), "Permission denied", 3);
#endif
#endif
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

255
test/test16.c Normal file
View File

@@ -0,0 +1,255 @@
/* test 16 */
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <utime.h>
#include <stdio.h>
#define MAX_ERROR 4
int errct, subtest, passes;
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test16a, (void));
_PROTOTYPE(void get_times, (char *name, time_t *a, time_t *c, time_t *m));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m;
m = (argc == 2 ? atoi(argv[1]) : 0xFFFF);
system("rm -rf DIR_16; mkdir DIR_16");
chdir("DIR_16");
printf("Test 16 ");
fflush(stdout);
for (i = 0; i < 4; i++) {
if (m & 0001) test16a();
passes++;
}
quit();
return(-1); /* impossible */
}
void test16a()
{
/* Test atime, ctime, and mtime. */
int fd, fd1, fd2, fd3, fd4;
time_t a, c, m, pa, pc, pm, xa, xc, xm, ya, yc, ym, za, zc, zm, ta, tc, tm;
time_t wa, wc, wm;
char buf[1024];
struct stat s;
subtest = 1;
if (passes > 0) return; /* takes too long to repeat this test */
if ( (fd = creat("T16.a", 0666)) < 0) e(1);
if (write(fd, buf, 1024) != 1024) e(2);
if (close(fd) < 0) e(3);
sleep(1); /* wait 1 sec before continuing */
if ( (fd = open("T16.a", O_RDONLY)) < 0) e(4);
if (read(fd, buf, 3) != 3) e(5);
if (close(fd) != 0) e(6);
if (stat("T16.a", &s) != 0) e(7);
a = s.st_atime;
c = s.st_ctime;
m = s.st_mtime;
if (a == 0) {
/* Almost certainly means we are running a V1 file system. */
printf(" (atime = 0. Probably V1 file system. V2 tests skipped.) ");
return;
}
/* Many system calls affect atime, ctime, and mtime. Test them. They
* fall into several groups. The members of each group can be tested
* together. Start with creat(), mkdir(), and mkfifo, all of which
* set all 3 times on the created object, and ctime and mtime of the dir.
*/
if ( (fd = creat("T16.b", 0666)) < 0) e(8);
if (close(fd) != 0) e(9);
get_times("T16.b", &a, &c, &m);
get_times(".", &pa, &pc, &pm);
if (a != c) e(10);
if (a != m) e(11);
if (a != pc) e(12);
if (a != pm) e(13);
if (unlink("T16.b") < 0) e(14);
/* Test the times for mkfifo. */
if ( (fd = mkfifo("T16.c", 0666)) != 0) e(15);
if (access("T16.c", R_OK | W_OK) != 0) e(16);
get_times("T16.c", &a, &c, &m);
get_times(".", &pa, &pc, &pm);
if (a != c) e(17);
if (a != m) e(18);
if (a != pc) e(19);
if (a != pm) e(20);
if (unlink("T16.c") < 0) e(21);
/* Test the times for mkdir. */
if (mkdir("T16.d", 0666) < 0) e(22);
get_times("T16.d", &a, &c, &m);
get_times(".", &pa, &pc, &pm);
if (a != c) e(23);
if (a != m) e(24);
if (a != pc) e(25);
if (a != pm) e(26);
sleep(1);
if (rmdir("T16.d") < 0) e(27);
get_times(".", &xa, &xc, &xm);
if (c == xc) e(28);
if (m == xm) e(29);
if (xc != xm) e(30);
/* Test open(file, O_TRUNC). */
if ( (fd = open("T16.e", O_WRONLY|O_CREAT, 0666)) < 0) e(31);
if (write(fd, buf, 1024) != 1024) e(32);
if (close(fd) != 0) e(33);
get_times("T16.e", &a, &c, &m);
get_times(".", &pa, &pc, &pm);
sleep(1);
if ( (fd = open("T16.e", O_WRONLY|O_TRUNC)) < 0) e(34);
get_times("T16.e", &xa, &xc, &xm);
get_times(".", &ya, &yc, &ym);
if (c != m) e(35);
if (pc != pm) e(36);
if (c == xc) e(37);
if (m == xm) e(38);
if (yc != pc) e(39);
if (ym != pm) e(40);
if (close(fd) != 0) e(41);
/* Test the times for link/unlink. */
get_times("T16.e", &a, &c, &m);
get_times(".", &ya, &yc, &ym);
sleep(1);
if (link("T16.e", "T16.f") != 0) e(42); /* second link */
get_times("T16.e", &xa, &xc, &xm);
get_times(".", &pa, &pc, &pm);
if (a != xa) e(43);
if (m != xm) e(44);
#ifndef V1_FILESYSTEM
if (c == xc) e(45);
#endif
if (ya != pa) e(46);
if (yc == pc) e(47);
if (ym == pm) e(48);
if (yc != ym) e(49);
if (pc != pm) e(50);
sleep(1);
if (unlink("T16.f") != 0) e(46);
get_times("T16.e", &a, &c, &m);
get_times(".", &ya, &yc, &ym);
if (a != xa) e(51);
if (m != xm) e(52);
#ifndef V1_FILESYSTEM
if (c == xc) e(53);
#endif
if (pa != ya) e(54);
if (pc == yc) e(55);
if (pm == ym) e(56);
if (yc != ym) e(57);
if (unlink("T16.e") != 0) e(58);
/* Test rename, read, write, chmod, utime. */
get_times(".", &pa, &pc, &pm);
if ( (fd = open("T16.g", O_RDWR|O_CREAT)) < 0) e(59);
if ( (fd1 = open("T16.h", O_WRONLY|O_CREAT, 0666)) < 0) e(60);
if ( (fd2 = open("T16.i", O_WRONLY|O_CREAT, 0666)) < 0) e(61);
if ( (fd3 = open("T16.j", O_WRONLY|O_CREAT, 0666)) < 0) e(62);
if ( (fd4 = open("T16.k", O_RDWR|O_CREAT, 0666)) < 0) e(63);
if (write(fd, buf, 1024) != 1024) e(64);
get_times("T16.g", &a, &c, &m);
get_times("T16.h", &pa, &pc, &pm);
get_times("T16.i", &xa, &xc, &xm);
get_times("T16.j", &ya, &yc, &ym);
get_times("T16.k", &za, &zc, &zm);
get_times(".", &wa, &wc, &wm);
sleep(1);
lseek(fd, 0L, SEEK_SET);
if (read(fd, buf, 35) != 35) e(65);
get_times("T16.g", &ta, &tc, &tm);
if (a == ta || c != tc || m != tm) e(66);
if (write(fd1, buf, 35) != 35) e(67);
get_times("T16.h", &ta, &tc, &tm);
if (pa != ta || pc == tc || pm == tm) e(69);
if (rename("T16.i", "T16.i1") != 0) e(70);
get_times("T16.i1", &ta, &tc, &tm);
if (xa != ta || xc != tc || xm != tm) e(71);
get_times(".", &a, &c, &m);
if (a != wa || c == wc || m == wm || wc != wm) e(72);
if (chmod("T16.j", 0777) != 0) e(73);
get_times("T16.j", &ta, &tc, &tm);
if (ya != ta || yc == tc || ym != tm) e(74);
if (utime("T16.k", (void *) 0) != 0) e(75);
get_times("T16.k", &ta, &tc, &tm);
if (za == ta || zc == tc) e(76);
if (close(fd) != 0) e(77);
if (close(fd1) != 0) e(78);
if (close(fd2) != 0) e(79);
if (close(fd3) != 0) e(80);
if (close(fd4) != 0) e(81);
if (unlink("T16.g") != 0) e(82);
if (unlink("T16.h") != 0) e(83);
if (unlink("T16.i1") != 0) e(84);
if (unlink("T16.j") != 0) e(85);
if (unlink("T16.k") != 0) e(86);
}
void get_times(name, a, c, m)
char *name;
time_t *a, *c, *m;
{
struct stat s;
if (stat(name, &s) != 0) e(500);
*a = s.st_atime;
*c = s.st_ctime;
*m = s.st_mtime;
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

1168
test/test17.c Normal file

File diff suppressed because it is too large Load Diff

1350
test/test18.c Normal file

File diff suppressed because it is too large Load Diff

531
test/test19.c Normal file
View File

@@ -0,0 +1,531 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define MAX_ERROR 4
#define NB 30L
#define NBOUNDS 6
int errct, subtest, passes, pipesigs;
long t1;
char aa[100];
char b[4] = {0, 1, 2, 3}, c[4] = {10, 20, 30, 40}, d[4] = {6, 7, 8, 9};
long bounds[NBOUNDS] = {7, 9, 50, 519, 520, 40000L};
char buff[30000];
_PROTOTYPE(int main, (int argc, char *argv[]));
_PROTOTYPE(void test19a, (void));
_PROTOTYPE(void test19b, (void));
_PROTOTYPE(void test19c, (void));
_PROTOTYPE(void test19d, (void));
_PROTOTYPE(void test19e, (void));
_PROTOTYPE(void test19f, (void));
_PROTOTYPE(void test19g, (void));
_PROTOTYPE(void clraa, (void));
_PROTOTYPE(void pipecatcher, (int s));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m;
m = (argc == 2 ? atoi(argv[1]) : 0xFFFF);
if (geteuid() == 0 || getuid() == 0) {
printf("Test 19 cannot run as root; test aborted\n");
exit(1);
}
system("rm -rf DIR_19; mkdir DIR_19");
chdir("DIR_19");
printf("Test 19 ");
fflush(stdout);
for (i = 0; i < 4; i++) {
if (m & 0001) test19a();
if (m & 0002) test19b();
if (m & 0004) test19c();
if (m & 0010) test19d();
if (m & 0020) test19e();
if (m & 0040) test19f();
if (m & 0100) test19g();
passes++;
}
quit();
return(-1); /* impossible */
}
void test19a()
{
/* Test open with O_CREAT and O_EXCL. */
int fd;
subtest = 1;
if ( (fd = creat("T19.a1", 0777)) != 3) e(1); /* create test file */
if (close(fd) != 0) e(2);
if ( (fd = open("T19.a1", O_RDONLY)) != 3) e(3);
if (close(fd) != 0) e(4);
if ( (fd = open("T19.a1", O_WRONLY)) != 3) e(5);
if (close(fd) != 0) e(6);
if ( (fd = open("T19.a1", O_RDWR)) != 3) e(7);
if (close(fd) != 0) e(8);
/* See if O_CREAT actually creates a file. */
if ( (fd = open("T19.a2", O_RDONLY)) != -1) e(9); /* must fail */
if ( (fd = open("T19.a2", O_RDONLY | O_CREAT, 0444)) != 3) e(10);
if (close(fd) != 0) e(11);
if ( (fd = open("T19.a2", O_RDONLY)) != 3) e(12);
if (close(fd) != 0) e(13);
if ( (fd = open("T19.a2", O_WRONLY)) != -1) e(14);
if ( (fd = open("T19.a2", O_RDWR)) != -1) e(15);
/* See what O_CREAT does on an existing file. */
if ( (fd = open("T19.a2", O_RDONLY | O_CREAT, 0777)) != 3) e(16);
if (close(fd) != 0) e(17);
if ( (fd = open("T19.a2", O_RDONLY)) != 3) e(18);
if (close(fd) != 0) e(19);
if ( (fd = open("T19.a2", O_WRONLY)) != -1) e(20);
if ( (fd = open("T19.a2", O_RDWR)) != -1) e(21);
/* See if O_EXCL works. */
if ( (fd = open("T19.a2", O_RDONLY | O_EXCL)) != 3) e(22);
if (close(fd) != 0) e(23);
if ( (fd = open("T19.a2", O_WRONLY | O_EXCL)) != -1) e(24);
if ( (fd = open("T19.a3", O_RDONLY | O_EXCL)) != -1) e(25);
if ( (fd = open("T19.a3", O_RDONLY | O_CREAT | O_EXCL, 0444)) != 3) e(26);
if (close(fd) != 0) e(27);
errno = 0;
if ( (fd = open("T19.a3", O_RDONLY | O_CREAT | O_EXCL, 0444)) != -1) e(28);
if (errno != EEXIST) e(29);
if (unlink("T19.a1") != 0) e(30);
if (unlink("T19.a2") != 0) e(31);
if (unlink("T19.a3") != 0) e(32);
}
void test19b()
{
/* Test open with O_APPEND and O_TRUNC. */
int fd;
subtest = 2;
if ( (fd = creat("T19.b1", 0777)) != 3) e(1); /* create test file */
if (write(fd, b, 4) != 4) e(2);
if (close(fd) != 0) e(3);
clraa();
if ( (fd = open("T19.b1", O_RDWR | O_APPEND)) != 3) e(4);
if (read(fd, aa, 100) != 4) e(5);
if (aa[0] != 0 || aa[1] != 1 || aa[2] != 2 || aa[3] != 3) e(6);
if (close(fd) != 0) e(7);
if ( (fd = open("T19.b1", O_RDWR | O_APPEND)) != 3) e(8);
if (write(fd, b, 4) != 4) e(9);
if (lseek(fd, 0L, SEEK_SET) != 0L) e(10);
clraa();
if (read(fd, aa, 100) != 8) e(11);
if (aa[4] != 0 || aa[5] != 1 || aa[6] != 2 || aa[7] != 3) e(12);
if (close(fd) != 0) e(13);
if ( (fd = open("T19.b1", O_RDWR | O_TRUNC)) != 3) e(14);
if (read(fd, aa, 100) != 0) e(15);
if (close(fd) != 0) e(16);
unlink("T19.b1");
}
void test19c()
{
/* Test program for open(), close(), creat(), read(), write(), lseek(). */
int i, n, n1, n2;
subtest = 3;
if ((n = creat("foop", 0777)) != 3) e(1);
if ((n1 = creat("foop", 0777)) != 4) e(2);
if ((n2 = creat("/", 0777)) != -1) e(3);
if (close(n) != 0) e(4);
if ((n = open("foop", O_RDONLY)) != 3) e(5);
if ((n2 = open("nofile", O_RDONLY)) != -1) e(6);
if (close(n1) != 0) e(7);
/* N is the only one open now. */
for (i = 0; i < 2; i++) {
n1 = creat("File2", 0777);
if (n1 != 4) {
printf("creat yielded fd=%d, expected 4\n", n1);
e(8);
}
if ((n2 = open("File2", O_RDONLY)) != 5) e(9);
if (close(n1) != 0) e(10);
if (close(n2) != 0) e(11);
}
unlink("File2");
if (close(n) != 0) e(12);
/* All files closed now. */
for (i = 0; i < 2; i++) {
if ((n = creat("foop", 0777)) != 3) e(13);
if (close(n) != 0) e(14);
if ((n = open("foop", O_RDWR)) != 3) e(15);
/* Read/write tests */
if (write(n, b, 4) != 4) e(16);
if (read(n, aa, 4) != 0) e(17);
if (lseek(n, 0L, SEEK_SET) != 0L) e(18);
if (read(n, aa, 4) != 4) e(19);
if (aa[0] != 0 || aa[1] != 1 || aa[2] != 2 || aa[3] != 3) e(20);
if (lseek(n, 0L, SEEK_SET) != 0L) e(21);
if (lseek(n, 2L, SEEK_CUR) != 2L) e(22);
if (read(n, aa, 4) != 2) e(23);
if (aa[0] != 2 || aa[1] != 3 || aa[2] != 2 || aa[3] != 3) e(24);
if (lseek(n, 2L, SEEK_SET) != 2L) e(25);
clraa();
if (write(n, c, 4) != 4) e(26);
if (lseek(n, 0L, SEEK_SET) != 0L) e(27);
if (read(n, aa, 10) != 6) e(28);
if (aa[0] != 0 || aa[1] != 1 || aa[2] != 10 || aa[3] != 20) e(29);
if (lseek(n, 16L, SEEK_SET) != 16L) e(30);
if (lseek(n, 2040L, SEEK_END) != 2046L) e(31);
if (read(n, aa, 10) != 0) e(32);
if (lseek(n, 0L, SEEK_CUR) != 2046L) e(33);
clraa();
if (write(n, c, 4) != 4) e(34);
if (lseek(n, 0L, SEEK_CUR) != 2050L) e(35);
if (lseek(n, 2040L, SEEK_SET) != 2040L) e(36);
clraa();
if (read(n, aa, 20) != 10) e(37);
if (aa[0] != 0 || aa[5] != 0 || aa[6] != 10 || aa[9] != 40) e(38);
if (lseek(n, 10239L, SEEK_SET) != 10239L) e(39);
if (write(n, d, 2) != 2) e(40);
if (lseek(n, -2L, SEEK_END) != 10239L) e(41);
if (read(n, aa, 2) != 2) e(42);
if (aa[0] != 6 || aa[1] != 7) e(43);
if (lseek(n, NB * 1024L - 2L, SEEK_SET) != NB * 1024L - 2L) e(44);
if (write(n, b, 4) != 4) e(45);
if (lseek(n, 0L, SEEK_SET) != 0L) e(46);
if (lseek(n, -6L, SEEK_END) != 1024L * NB - 4) e(47);
clraa();
if (read(n, aa, 100) != 6) e(48);
if (aa[0] != 0 || aa[1] != 0 || aa[3] != 1 || aa[4] != 2|| aa[5] != 3)
e(49);
if (lseek(n, 20000L, SEEK_SET) != 20000L) e(50);
if (write(n, c, 4) != 4) e(51);
if (lseek(n, -4L, SEEK_CUR) != 20000L) e(52);
if (read(n, aa, 4) != 4) e(53);
if (aa[0] != 10 || aa[1] != 20 || aa[2] != 30 || aa[3] != 40) e(54);
if (close(n) != 0) e(55);
if ((n1 = creat("foop", 0777)) != 3) e(56);
if (close(n1) != 0) e(57);
unlink("foop");
}
}
void test19d()
{
/* Test read. */
int i, fd, pd[2];
char bb[100];
subtest = 4;
for (i = 0; i < 100; i++) bb[i] = i;
if ( (fd = creat("T19.d1", 0777)) != 3) e(1); /* create test file */
if (write(fd, bb, 100) != 100) e(2);
if (close(fd) != 0) e(3);
clraa();
if ( (fd = open("T19.d1", O_RDONLY)) != 3) e(4);
errno = 1000;
if (read(fd, aa, 0) != 0) e(5);
if (errno != 1000) e(6);
if (read(fd, aa, 100) != 100) e(7);
if (lseek(fd, 37L, SEEK_SET) != 37L) e(8);
if (read(fd, aa, 10) != 10) e(9);
if (lseek(fd, 0L, SEEK_CUR) != 47L) e(10);
if (read(fd, aa, 100) != 53) e(11);
if (aa[0] != 47) e(12);
if (read(fd, aa, 1) != 0) e(13);
if (close(fd) != 0) e(14);
/* Read from pipe with no writer open. */
if (pipe(pd) != 0) e(15);
if (close(pd[1]) != 0) e(16);
errno = 2000;
if (read(pd[0], aa, 1) != 0) e(17); /* must return EOF */
if (errno != 2000) e(18);
/* Read from a pipe with O_NONBLOCK set. */
if (fcntl(pd[0], F_SETFL, O_NONBLOCK) != 0) e(19); /* set O_NONBLOCK */
/*
if (read(pd[0], aa, 1) != -1) e(20);
if (errno != EAGAIN) e(21);
*/
if (close(pd[0]) != 0) e(19);
if (unlink("T19.d1") != 0) e(20);
}
void test19e()
{
/* Test link, unlink, stat, fstat, dup, umask. */
int i, j, n, n1, flag;
char a[255], b[255];
struct stat s, s1;
subtest = 5;
for (i = 0; i < 2; i++) {
umask(0);
if ((n = creat("T3", 0702)) < 0) e(1);
if (link("T3", "newT3") < 0) e(2);
if ((n1 = open("newT3", O_RDWR)) < 0) e(3);
for (j = 0; j < 255; j++) a[j] = j;
if (write(n, a, 255) != 255) e(4);
if (read(n1, b, 255) != 255) e(5);
flag = 0;
for (j = 0; j < 255; j++)
if (a[j] != b[j]) flag++;
if (flag) e(6);
if (unlink("T3") < 0) e(7);
if (close(n) < 0) e(8);
if (close(n1) < 0) e(9);
if ((n1 = open("newT3", O_RDONLY)) < 0) e(10);
if (read(n1, b, 255) != 255) e(11);
flag = 0;
for (j = 0; j < 255; j++)
if (a[j] != b[j]) flag++;
if (flag) e(12);
/* Now check out stat, fstat. */
if (stat("newT3", &s) < 0) e(13);
if (s.st_mode != (mode_t) 0100702) e(14);
/* The cast was because regular modes are
* negative :-(. Anyway, the magic number
* should be (S_IFREG | S_IRWXU | S_IWOTH)
* for POSIX.
*/
if (s.st_nlink != 1) e(15);
if (s.st_size != 255L) e(16);
if (fstat(n1, &s1) < 0) e(17);
if (s.st_dev != s1.st_dev) e(18);
if (s.st_ino != s1.st_ino) e(19);
if (s.st_mode != s1.st_mode) e(20);
if (s.st_nlink != s1.st_nlink) e(21);
if (s.st_uid != s1.st_uid) e(22);
if (s.st_gid != s1.st_gid) e(23);
if (s.st_rdev != s1.st_rdev) e(24);
if (s.st_size != s1.st_size) e(25);
if (s.st_atime != s1.st_atime) e(26);
if (close(n1) < 0) e(27);
if (unlink("newT3") < 0) e(28);
umask(040);
if ((n = creat("T3a", 0777)) < 0) e(29);
if (stat("T3a", &s) < 0) e(30);
if (s.st_mode != (mode_t) 0100737) e(31); /* negative :-( */
if (unlink("T3a") < 0) e(32);
if (close(n1) < 0) e(33);
/* Dup */
if ((n = creat("T3b", 0777)) < 0) e(34);
if (close(n) < 0) e(35);
if ((n = open("T3b", O_RDWR)) < 0) e(36);
if ((n1 = dup(n)) != n + 1) e(37);
if (write(n, a, 255) != 255) e(38);
read(n1, b, 20);
if (lseek(n, 0L, SEEK_SET) != 0L) e(39);
if ((j = read(n1, b, 1024)) != 255) e(40);
if (unlink("T3b") < 0) e(41);
if (close(n) < 0) e(42);
if (close(n1) < 0) e(43);
}
}
void test19f()
{
/* Test large files to see if indirect block stuff works. */
int fd, i;
long pos;
subtest = 6;
if (passes > 0) return; /* takes too long to repeat this test */
for (i = 0; i < NBOUNDS; i ++) {
pos = 1024L * bounds[i];
fd = creat("T19f", 0777);
if (fd < 0) e(10*i+1);
if (lseek(fd, pos, 0) < 0) e(10*i+2);
if (write(fd, buff, 30720) != 30720) e(10*i+3);
if (close(fd) < 0) e(10*i+3);
if (unlink("T19f") < 0) e(10*i+4);
}
}
void test19g()
{
/* Test POSIX calls for pipe, read, write, lseek and close. */
int pipefd[2], n, i, fd;
char buf[512], buf2[512];
subtest = 7;
for (i = 0; i < 512; i++) buf[i] = i % 128;
if (pipe(pipefd) < 0) e(1);
if (write(pipefd[1], buf, 512) != 512) e(2);
if (read(pipefd[0], buf2, 512) != 512) e(3);
if (close(pipefd[1]) != 0) e(4);
if (close(pipefd[1]) >= 0) e(5);
if (read(pipefd[0], buf2, 1) != 0) e(6);
if (close(pipefd[0]) != 0) e(7);
/* Test O_NONBLOCK on pipes. */
if (pipe(pipefd) < 0) e(8);
if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) != 0) e(9);
if (read(pipefd[0], buf2, 1) != -1) e(10);
if (errno != EAGAIN) e(11);
if (close(pipefd[0]) != 0) e(12);
if (close(pipefd[1]) != 0) e(13);
/* Test read and lseek. */
if ( (fd = creat("T19.g1", 0777)) != 3) e(14); /* create test file */
if (write(fd, buf, 512) != 512) e(15);
errno = 3000;
if (read(fd, buf2, 512) != -1) e(16);
if (errno != EBADF) e(17);
if (close(fd) != 0) e(18);
if ( (fd = open("T19.g1", O_RDWR)) != 3) e(19);
if (read(fd, buf2, 512) != 512) e(20);
if (read(fd, buf2, 512) != 0) e(21);
if (lseek(fd, 100L, SEEK_SET) != 100L) e(22);
if (read(fd, buf2, 512) != 412) e(23);
if (lseek(fd, 1000L, SEEK_SET) != 1000L) e(24);
/* Test write. */
if (lseek(fd, -1000L, SEEK_CUR) != 0) e(25);
if (write(fd, buf, 512) != 512) e(26);
if (lseek(fd, 2L, SEEK_SET) != 2) e(27);
if (write(fd, buf, 3) != 3) e(28);
if (lseek(fd, -2L, SEEK_CUR) != 3) e(29);
if (write(fd, &buf[30], 1) != 1) e(30);
if (lseek(fd, 2L, SEEK_CUR) != 6) e(31);
if (write(fd, &buf[60], 1) != 1) e(32);
if (lseek(fd, -512L, SEEK_END) != 0) e(33);
if (read(fd, buf2, 8) != 8) e(34);
errno = 4000;
if (buf2[0] != 0 || buf2[1] != 1 || buf2[2] != 0 || buf2[3] != 30) e(35);
if (buf2[4] != 2 || buf2[5] != 5 || buf2[6] != 60 || buf2[7] != 7) e(36);
/* Turn the O_APPEND flag on. */
if (fcntl(fd, F_SETFL, O_APPEND) != 0) e(37);
if (lseek(fd, 0L, SEEK_SET) != 0) e(38);
if (write(fd, &buf[100], 1) != 1) e(39);
if (lseek(fd, 0L, SEEK_SET) != 0) e(40);
if (read(fd, buf2, 10) != 10) e(41);
if (buf2[0] != 0) e(42);
if (lseek(fd, -1L, SEEK_END) != 512) e(43);
if (read(fd, buf2, 10) != 1) e(44);
if (buf2[0] != 100) e(45);
if (close(fd) != 0) e(46);
/* Now try write with O_NONBLOCK. */
if (pipe(pipefd) != 0) e(47);
if (fcntl(pipefd[1], F_SETFL, O_NONBLOCK) != 0) e(48);
if (write(pipefd[1], buf, 512) != 512) e(49);
if (write(pipefd[1], buf, 512) != 512) e(50);
errno = 0;
for (i = 1; i < 20; i++) {
n = write(pipefd[1], buf, 512);
if (n == 512) continue;
if (n != -1 || errno != EAGAIN) {e(51); break;}
}
if (read(pipefd[0], buf, 512) != 512) e(52);
if (close(pipefd[0]) != 0) e(53);
/* Write to a pipe with no reader. This should generate a signal. */
signal(SIGPIPE, pipecatcher);
errno = 0;
if (write(pipefd[1], buf, 1) != -1) e(54);
if (errno != EPIPE) e(55);
if (pipesigs != passes + 1) e(56); /* we should have had the sig now */
if (close(pipefd[1]) != 0) e(57);
errno = 0;
if (write(100, buf, 512) != -1) e(58);
if (errno != EBADF) e(59);
if (unlink("T19.g1") != 0) e(60);
}
void clraa()
{
int i;
for (i = 0; i < 100; i++) aa[i] = 0;
}
void pipecatcher(s)
int s; /* it is supposed to have an arg */
{
pipesigs++;
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
fflush(stdout); /* aargh! Most results go to stdout and are
* messed up by perror going to stderr.
* Should replace perror by printf and strerror
* in all the tests.
*/
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

416
test/test2.c Normal file
View File

@@ -0,0 +1,416 @@
/* test 2 */
#include <sys/types.h>
#include <sys/times.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#define ITERATIONS 5
#define MAX_ERROR 4
int is, array[4], parsigs, parcum, sigct, cumsig, errct, subtest;
int iteration, kk = 0, errct = 0;
char buf[2048];
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test2a, (void));
_PROTOTYPE(void test2b, (void));
_PROTOTYPE(void test2c, (void));
_PROTOTYPE(void test2d, (void));
_PROTOTYPE(void test2e, (void));
_PROTOTYPE(void test2f, (void));
_PROTOTYPE(void test2g, (void));
_PROTOTYPE(void test2h, (void));
_PROTOTYPE(void sigpip, (int s));
_PROTOTYPE(void quit, (void));
_PROTOTYPE(void e, (int n));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 2 ");
fflush(stdout); /* have to flush for child's benefit */
system("rm -rf DIR_02; mkdir DIR_02");
chdir("DIR_02");
for (i = 0; i < ITERATIONS; i++) {
iteration = i;
if (m & 0001) test2a();
if (m & 0002) test2b();
if (m & 0004) test2c();
if (m & 0010) test2d();
if (m & 0020) test2e();
if (m & 0040) test2f();
if (m & 0100) test2g();
if (m & 0200) test2h();
}
subtest = 100;
if (cumsig != ITERATIONS) e(101);
quit();
return(-1); /* impossible */
}
void test2a()
{
/* Test pipes */
int fd[2];
int n, i, j, q = 0;
subtest = 1;
if (pipe(fd) < 0) {
printf("pipe error. errno= %d\n", errno);
errct++;
quit();
}
i = fork();
if (i < 0) {
printf("fork failed\n");
errct++;
quit();
}
if (i != 0) {
/* Parent code */
close(fd[0]);
for (i = 0; i < 2048; i++) buf[i] = i & 0377;
for (q = 0; q < 8; q++) {
if (write(fd[1], buf, 2048) < 0) {
printf("write pipe err. errno=%d\n", errno);
errct++;
quit();
}
}
close(fd[1]);
wait(&q);
if (q != 256 * 58) {
printf("wrong exit code %d\n", q);
errct++;
quit();
}
} else {
/* Child code */
close(fd[1]);
for (q = 0; q < 32; q++) {
n = read(fd[0], buf, 512);
if (n != 512) {
printf("read yielded %d bytes, not 512\n", n);
errct++;
quit();
}
for (j = 0; j < n; j++)
if ((buf[j] & 0377) != (kk & 0377)) {
printf("wrong data: %d %d %d \n ",
j, buf[j] & 0377, kk & 0377);
} else {
kk++;
}
}
exit(58);
}
}
void test2b()
{
int fd[2], n;
char buf[4];
subtest = 2;
sigct = 0;
signal(SIGPIPE, sigpip);
pipe(fd);
if (fork()) {
/* Parent */
close(fd[0]);
while (sigct == 0) {
write(fd[1], buf, 1);
}
wait(&n);
} else {
/* Child */
close(fd[0]);
close(fd[1]);
exit(0);
}
}
void test2c()
{
int n;
subtest = 3;
signal(SIGINT, SIG_DFL);
is = 0;
if ((array[is++] = fork()) > 0) {
if ((array[is++] = fork()) > 0) {
if ((array[is++] = fork()) > 0) {
if ((array[is++] = fork()) > 0) {
signal(SIGINT, SIG_IGN);
kill(array[0], SIGINT);
kill(array[1], SIGINT);
kill(array[2], SIGINT);
kill(array[3], SIGINT);
wait(&n);
wait(&n);
wait(&n);
wait(&n);
} else {
pause();
}
} else {
pause();
}
} else {
pause();
}
} else {
pause();
}
}
void test2d()
{
int pid, stat_loc, s;
/* Test waitpid. */
subtest = 4;
/* Test waitpid(pid, arg2, 0) */
pid = fork();
if (pid < 0) e(1);
if (pid > 0) {
/* Parent. */
s = waitpid(pid, &stat_loc, 0);
if (s != pid) e(2);
if (WIFEXITED(stat_loc) == 0) e(3);
if (WIFSIGNALED(stat_loc) != 0) e(4);
if (WEXITSTATUS(stat_loc) != 22) e(5);
} else {
/* Child */
exit(22);
}
/* Test waitpid(-1, arg2, 0) */
pid = fork();
if (pid < 0) e(6);
if (pid > 0) {
/* Parent. */
s = waitpid(-1, &stat_loc, 0);
if (s != pid) e(7);
if (WIFEXITED(stat_loc) == 0) e(8);
if (WIFSIGNALED(stat_loc) != 0) e(9);
if (WEXITSTATUS(stat_loc) != 33) e(10);
} else {
/* Child */
exit(33);
}
/* Test waitpid(0, arg2, 0) */
pid = fork();
if (pid < 0) e(11);
if (pid > 0) {
/* Parent. */
s = waitpid(0, &stat_loc, 0);
if (s != pid) e(12);
if (WIFEXITED(stat_loc) == 0) e(13);
if (WIFSIGNALED(stat_loc) != 0) e(14);
if (WEXITSTATUS(stat_loc) != 44) e(15);
} else {
/* Child */
exit(44);
}
/* Test waitpid(0, arg2, WNOHANG) */
signal(SIGTERM, SIG_DFL);
pid = fork();
if (pid < 0) e(16);
if (pid > 0) {
/* Parent. */
s = waitpid(0, &stat_loc, WNOHANG);
if (s != 0) e(17);
if (kill(pid, SIGTERM) != 0) e(18);
if (waitpid(pid, &stat_loc, 0) != pid) e(19);
if (WIFEXITED(stat_loc) != 0) e(20);
if (WIFSIGNALED(stat_loc) == 0) e(21);
if (WTERMSIG(stat_loc) != SIGTERM) e(22);
} else {
/* Child */
pause();
}
/* Test some error conditions. */
errno = 9999;
if (waitpid(0, &stat_loc, 0) != -1) e(23);
if (errno != ECHILD) e(24);
errno = 9999;
if (waitpid(0, &stat_loc, WNOHANG) != -1) e(25);
if (errno != ECHILD) e(26);
}
void test2e()
{
int pid1, pid2, stat_loc, s;
/* Test waitpid with two children. */
subtest = 5;
if (iteration > 1) return; /* slow test, don't do it too much */
if ( (pid1 = fork())) {
/* Parent. */
if ( (pid2 = fork()) ) {
/* Parent. Collect second child first. */
s = waitpid(pid2, &stat_loc, 0);
if (s != pid2) e(1);
if (WIFEXITED(stat_loc) == 0) e(2);
if (WIFSIGNALED(stat_loc) != 0) e(3);
if (WEXITSTATUS(stat_loc) != 222) e(4);
/* Now collect first child. */
s = waitpid(pid1, &stat_loc, 0);
if (s != pid1) e(5);
if (WIFEXITED(stat_loc) == 0) e(6);
if (WIFSIGNALED(stat_loc) != 0) e(7);
if (WEXITSTATUS(stat_loc) != 111) e(8);
} else {
/* Child 2. */
sleep(2); /* child 2 delays before exiting. */
exit(222);
}
} else {
/* Child 1. */
exit(111); /* child 1 exits immediately */
}
}
void test2f()
{
/* test getpid, getppid, getuid, etc. */
pid_t pid, pid1, ppid, cpid, stat_loc, err;
subtest = 6;
errno = -2000;
err = 0;
pid = getpid();
if ( (pid1 = fork())) {
/* Parent. Do nothing. */
if (wait(&stat_loc) != pid1) e(1);
if (WEXITSTATUS(stat_loc) != (pid1 & 0377)) e(2);
} else {
/* Child. Get ppid. */
cpid = getpid();
ppid = getppid();
if (ppid != pid) err = 3;
if (cpid == ppid) err = 4;
exit(cpid & 0377);
}
if (err != 0) e(err);
}
void test2g()
{
/* test time(), times() */
time_t t1, t2;
clock_t t3, t4;
struct tms tmsbuf;
subtest = 7;
errno = -7000;
/* First time(). */
t1 = -1;
t2 = -2;
t1 = time(&t2);
if (t1 < 650000000L) e(1); /* 650000000 is Sept. 1990 */
if (t1 != t2) e(2);
t1 = -1;
t1 = time( (time_t *) NULL);
if (t1 < 650000000L) e(3);
t3 = times(&tmsbuf);
sleep(1);
t2 = time( (time_t *) NULL);
if (t2 < 0L) e(4);
if (t2 - t1 < 1) e(5);
/* Now times(). */
t4 = times(&tmsbuf);
if ( t4 == (clock_t) -1) e(6);
if (t4 - t3 < CLOCKS_PER_SEC) e(7);
if (tmsbuf.tms_utime < 0) e(8);
if (tmsbuf.tms_stime < 0) e(9);
if (tmsbuf.tms_cutime < 0) e(10);
if (tmsbuf.tms_cstime < 0) e(11);
}
void test2h()
{
/* Test getgroups(). */
gid_t g[10];
subtest = 8;
errno = -8000;
if (getgroups(10, g) != 0) e(1);
if (getgroups(1, g) != 0) e(2);
if (getgroups(0, g) != 0) e(3);
}
void sigpip(s)
int s; /* for ANSI */
{
sigct++;
cumsig++;
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(4);
}
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}

735
test/test20.c Normal file
View File

@@ -0,0 +1,735 @@
/* POSIX test program (20). Author: Andy Tanenbaum */
/* The following POSIX calls are tested:
*
* opendir()
* readdir()
* rewinddir()
* closedir()
* chdir()
* getcwd()
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include <stdio.h>
#define DIR_NULL (DIR*) NULL
#define ITERATIONS 5
#define MAX_FD 100 /* must be large enough to cause error */
#define BUF_SIZE PATH_MAX+20
#define ERR_CODE -1 /* error return */
#define RD_BUF 200
#define MAX_ERROR 4
char str[] = {"The time has come the walrus said to talk of many things.\n"};
char str2[] = {"Of ships and shoes and sealing wax, of cabbages and kings.\n"};
char str3[] = {"Of why the sea is boiling hot and whether pigs have wings\n"};
int subtest, errct;
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test20a, (void));
_PROTOTYPE(void checkdir, (DIR *dirp, int t));
_PROTOTYPE(void test20b, (void));
_PROTOTYPE(void test20c, (void));
_PROTOTYPE(void test20d, (void));
_PROTOTYPE(void test20e, (void));
_PROTOTYPE(void test20f, (void));
_PROTOTYPE(void test20g, (void));
_PROTOTYPE(void test20h, (void));
_PROTOTYPE(void test20i, (void));
_PROTOTYPE(void test20j, (void));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (geteuid() == 0 || getuid() == 0) {
printf("Test 20 cannot run as root; test aborted\n");
exit(1);
}
if (argc == 2) m = atoi(argv[1]);
printf("Test 20 ");
fflush(stdout);
system("rm -rf DIR_20; mkdir DIR_20");
chdir("DIR_20");
for (i = 0; i < ITERATIONS; i++) {
if (m & 00001) test20a(); /* test for correct operation */
if (m & 00002) test20b(); /* test general error handling */
if (m & 00004) test20c(); /* test for EMFILE error */
if (m & 00010) test20d(); /* test chdir() and getcwd() */
if (m & 00020) test20e(); /* test open() */
if (m & 00040) test20f(); /* test umask(), stat(), fstat() */
if (m & 00100) test20g(); /* test link() and unlink() */
if (m & 00200) test20h(); /* test access() */
if (m & 00400) test20i(); /* test chmod() and chown() */
if (m & 01000) test20j(); /* test utime() */
}
quit();
return(-1); /* impossible */
}
void test20a()
{
/* Subtest 1. Correct operation */
int f1, f2, f3, f4, f5;
DIR *dirp;
/* Remove any residue of previous tests. */
subtest = 1;
system("rm -rf foo");
/* Create a directory foo with 5 files in it. */
mkdir("foo", 0777);
if ((f1 = creat("foo/f1", 0666)) < 0) e(1);
if ((f2 = creat("foo/f2", 0666)) < 0) e(2);
if ((f3 = creat("foo/f3", 0666)) < 0) e(3);
if ((f4 = creat("foo/f4", 0666)) < 0) e(4);
if ((f5 = creat("foo/f5", 0666)) < 0) e(5);
/* Now remove 2 files to create holes in the directory. */
if (unlink("foo/f2") < 0) e(6);
if (unlink("foo/f4") < 0) e(7);
/* Close the files. */
close(f1);
close(f2);
close(f3);
close(f4);
close(f5);
/* Open the directory. */
dirp = opendir("./foo");
if (dirp == DIR_NULL) e(6);
/* Read the 5 files from it. */
checkdir(dirp, 2);
/* Rewind dir and test again. */
rewinddir(dirp);
checkdir(dirp, 3);
/* We're done. Close the directory stream. */
if (closedir(dirp) < 0) e(7);
/* Remove dir for next time. */
system("rm -rf foo");
}
void checkdir(dirp, t)
DIR *dirp; /* poinrter to directory stream */
int t; /* subtest number to use */
{
int i, f1, f2, f3, f4, f5, dot, dotdot, subt;
struct dirent *d;
char *s;
/* Save subtest number */
subt = subtest;
subtest = t;
/* Clear the counters. */
f1 = 0;
f2 = 0;
f3 = 0;
f4 = 0;
f5 = 0;
dot = 0;
dotdot = 0;
/* Read the directory. It should contain 5 entries, ".", ".." and 3
* files. */
for (i = 0; i < 5; i++) {
d = readdir(dirp);
if (d == (struct dirent *) NULL) {
e(1);
subtest = subt; /* restore subtest number */
return;
}
s = d->d_name;
if (strcmp(s, ".") == 0) dot++;
if (strcmp(s, "..") == 0) dotdot++;
if (strcmp(s, "f1") == 0) f1++;
if (strcmp(s, "f2") == 0) f2++;
if (strcmp(s, "f3") == 0) f3++;
if (strcmp(s, "f4") == 0) f4++;
if (strcmp(s, "f5") == 0) f5++;
}
/* Check results. */
d = readdir(dirp);
if (d != (struct dirent *) NULL) e(2);
if (f1 != 1 || f3 != 1 || f5 != 1) e(3);
if (f2 != 0 || f4 != 0) e(4);
if (dot != 1 || dotdot != 1) e(5);
subtest = subt;
return;
}
void test20b()
{
/* Subtest 4. Test error handling. */
int fd;
DIR *dirp;
subtest = 4;
if (opendir("foo/xyz/---") != DIR_NULL) e(1);
if (errno != ENOENT) e(2);
if (mkdir("foo", 0777) < 0) e(3);
if (chmod("foo", 0) < 0) e(4);
if (opendir("foo/xyz/--") != DIR_NULL) e(5);
if (errno != EACCES) e(6);
if (chmod("foo", 0777) != 0) e(7);
if (rmdir("foo") != 0) e(8);
if ((fd = creat("abc", 0666)) < 0) e(9);
if (close(fd) < 0) e(10);
if (opendir("abc/xyz") != DIR_NULL) e(11);
if (errno != ENOTDIR) e(12);
if ((dirp = opendir(".")) == DIR_NULL) e(13);
if (closedir(dirp) != 0) e(14);
if (unlink("abc") != 0) e(15);
}
void test20c()
{
/* Subtest 5. See what happens if we open too many directory streams. */
int i, j;
DIR *dirp[MAX_FD];
subtest = 5;
for (i = 0; i < MAX_FD; i++) {
dirp[i] = opendir(".");
if (dirp[i] == (DIR *) NULL) {
/* We have hit the limit. */
if (errno != EMFILE && errno != ENOMEM) e(1);
for (j = 0; j < i; j++) {
if (closedir(dirp[j]) != 0) e(2); /* close */
}
return;
}
}
/* Control should never come here. This is an error. */
e(3);
for (i = 0; i < MAX_FD; i++) closedir(dirp[i]); /* don't check */
}
void test20d()
{
/* Test chdir and getcwd(). */
int fd;
char *s;
char base[BUF_SIZE], buf2[BUF_SIZE], tmp[BUF_SIZE];
subtest = 6;
if (getcwd(base, BUF_SIZE) == (char *) NULL) e(1); /* get test dir's path */
if (system("rm -rf Dir") != 0) e(2); /* remove residue of previous test */
if (mkdir("Dir", 0777) < 0) e(3); /* create directory called "Dir" */
/* Change to Dir and verify that it worked. */
if (chdir("Dir") < 0) e(4); /* go to Dir */
s = getcwd(buf2, BUF_SIZE); /* get full path of Dir */
if (s == (char *) NULL) e(5); /* check for error return */
if (s != buf2) e(6); /* if successful, first arg is returned */
strcpy(tmp, base); /* concatenate base name and "/Dir" */
strcat(tmp, "/");
strcat(tmp, "Dir");
if (strcmp(tmp, s) != 0) e(7);
/* Change to ".." and verify that it worked. */
if (chdir("..") < 0) e(8);
if (getcwd(buf2, BUF_SIZE) != buf2) e(9);
if (strcmp(buf2, base) != 0) e(10);
/* Now make calls that do nothing, but do it in a strange way. */
if (chdir("Dir/..") < 0) e(11);
if (getcwd(buf2, BUF_SIZE) != buf2) e(12);
if (strcmp(buf2, base) != 0) e(13);
if (chdir("Dir/../Dir/..") < 0) e(14);
if (getcwd(buf2, BUF_SIZE) != buf2) e(15);
if (strcmp(buf2, base) != 0) e(16);
if (chdir("Dir/../Dir/../Dir/../Dir/../Dir/../Dir/../Dir/..") < 0) e(17);
if (getcwd(buf2, BUF_SIZE) != buf2) e(18);
if (strcmp(buf2, base) != 0) e(19);
/* Make Dir unreadable and unsearchable. Check error message. */
if (chmod("Dir", 0) < 0) e(20);
if (chdir("Dir") >= 0) e(21);
if (errno != EACCES) e(22);
/* Check error message for bad path. */
if (chmod("Dir", 0777) < 0) e(23);
if (chdir("Dir/x/y") != ERR_CODE) e(24);
if (errno != ENOENT) e(25);
if ( (fd=creat("Dir/x", 0777)) < 0) e(26);
if (close(fd) != 0) e(27);
if (chdir("Dir/x/y") != ERR_CODE) e(28);
if (errno != ENOTDIR) e(29);
/* Check empty string. */
if (chdir("") != ERR_CODE) e(30);
if (errno != ENOENT) e(31);
/* Remove the directory. */
if (unlink("Dir/x") != 0) e(32);
if (system("rmdir Dir") != 0) e(33);
}
void test20e()
{
/* Test open. */
int fd, bytes, bytes2;
char buf[RD_BUF];
subtest = 7;
unlink("T20"); /* get rid of it in case it exists */
/* Create a test file. */
bytes = strlen(str);
bytes2 = strlen(str2);
if ((fd = creat("T20", 0777)) < 0) e(1);
if (write(fd, str, bytes) != bytes) e(2); /* T20 now has 'bytes' bytes */
if (close(fd) != 0) e(3);
/* Test opening a file with O_RDONLY. */
if ((fd = open("T20", O_RDONLY)) < 0) e(4);
buf[0] = '\0';
if (read(fd, buf, RD_BUF) != bytes) e(5);
if (strncmp(buf, str, bytes) != 0) e(6);
if (close(fd) < 0) e(7);
/* Test the same thing, only with O_RDWR now. */
if ((fd = open("T20", O_RDWR)) < 0) e(8);
buf[0] = '\0';
if (read(fd, buf, RD_BUF) != bytes) e(9);
if (strncmp(buf, str, bytes) != 0) e(10);
if (close(fd) < 0) e(11);
/* Try opening and reading with O_WRONLY. It should fail. */
if ((fd = open("T20", O_WRONLY)) < 0) e(12);
buf[0] = '\0';
if (read(fd, buf, RD_BUF) >= 0) e(13);
if (close(fd) != 0) e(14);
/* Test O_APPEND. */
if ((fd = open("T20", O_RDWR | O_APPEND)) < 0) e(15);
if (lseek(fd, 0L, SEEK_SET) < 0) e(16); /* go to start of file */
if ( write(fd, str2, bytes2) != bytes2) e(17); /* write at start of file */
if (lseek(fd, 0L, SEEK_SET) < 0) e(18); /* go back to start again */
if (read(fd, buf, RD_BUF) != bytes + bytes2) e(19); /* read whole file */
if (strncmp(buf, str, bytes) != 0) e(20);
if (close(fd) != 0) e(21);
/* Get rid of the file. */
if (unlink("T20") < 0) e(22);
}
void test20f()
{
/* Test stat, fstat, umask. */
int i, fd;
mode_t m1;
struct stat stbuf1, stbuf2;
time_t t, t1;
subtest = 8;
m1 = umask(~0777);
if (system("rm -rf foo xxx") != 0) e(1);
if ((fd = creat("foo", 0777)) < 0) e(2);
if (stat("foo", &stbuf1) < 0) e(3);
if (fstat(fd, &stbuf2) < 0) e(4);
if (stbuf1.st_mode != stbuf2.st_mode) e(5);
if (stbuf1.st_ino != stbuf2.st_ino) e(6);
if (stbuf1.st_dev != stbuf2.st_dev) e(7);
if (stbuf1.st_nlink != stbuf2.st_nlink) e(8);
if (stbuf1.st_uid != stbuf2.st_uid) e(9);
if (stbuf1.st_gid != stbuf2.st_gid) e(10);
if (stbuf1.st_size != stbuf2.st_size) e(11);
if (stbuf1.st_atime != stbuf2.st_atime) e(12);
if (stbuf1.st_mtime != stbuf2.st_mtime) e(13);
if (stbuf1.st_ctime != stbuf2.st_ctime) e(14);
if (!S_ISREG(stbuf1.st_mode)) e(15);
if (S_ISDIR(stbuf1.st_mode)) e(16);
if (S_ISCHR(stbuf1.st_mode)) e(17);
if (S_ISBLK(stbuf1.st_mode)) e(18);
if (S_ISFIFO(stbuf1.st_mode)) e(19);
if ((stbuf1.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != 0777) e(20);
if (stbuf1.st_nlink != 1) e(21);
if (stbuf1.st_uid != getuid()) e(22);
if (stbuf1.st_gid != getgid()) e(23);
if (stbuf1.st_size != 0L) e(24);
/* First unlink, then close -- harder test */
if (unlink("foo") < 0) e(25);
if (close(fd) < 0) e(26);
/* Now try umask a bit more. */
fd = 0;
if ((i = umask(~0704)) != 0) e(27);
if ((fd = creat("foo", 0777)) < 0) e(28);
if (stat("foo", &stbuf1) < 0) e(29);
if (fstat(fd, &stbuf2) < 0) e(30);
if (stbuf1.st_mode != stbuf2.st_mode) e(31);
if ((stbuf1.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != 0704) e(32);
/* First unlink, then close -- harder test */
if (unlink("foo") < 0) e(33);
if (close(fd) < 0) e(34);
if (umask(m1) != 073) e(35);
/* Test some errors. */
if (system("mkdir Dir; date >Dir/x; chmod 666 Dir") != 0) e(36);
if (stat("Dir/x", &stbuf1) >= 0) e(37);
if (errno != EACCES) e(38);
if (stat("......", &stbuf1) >= 0) e(39);
if (errno != ENOENT) e(40);
if (stat("", &stbuf1) >= 0) e(41);
if (errno != ENOENT) e(42);
if (stat("xxx/yyy/zzz", &stbuf1) >= 0) e(43);
if (errno != ENOENT) e(44);
if (fstat(10000, &stbuf1) >= 0) e(45);
if (errno != EBADF) e(46);
if (chmod("Dir", 0777) != 0) e(47);
if (system("rm -rf foo Dir") != 0) e(48);
/* See if time looks reasonable. */
errno = 0;
t = time(&t1); /* current time */
if (t < 650000000L) e(49); /* 650000000 is Sept. 1990 */
unlink("T20f");
fd = creat("T20f", 0777);
if (fd < 0) e(50);
if (close(fd) < 0) e(51);
if (stat("T20f", &stbuf1) < 0) e(52);
if (stbuf1.st_mtime < t) e(53);
if (unlink("T20f") < 0) e(54);
}
void test20g()
{
/* Test link and unlink. */
int i, fd;
struct stat stbuf;
char name[4];
subtest = 9;
if (system("rm -rf L? L?? Dir; mkdir Dir") != 0) e(1);
if ( (fd = creat("L1", 0666)) < 0) e(2);
if (fstat(fd, &stbuf) != 0) e(3);
if (stbuf.st_nlink != 1) e(4);
if (link("L1", "L2") != 0) e(5);
if (fstat(fd, &stbuf) != 0) e(6);
if (stbuf.st_nlink != 2) e(7);
if (unlink("L2") != 0) e(8);
if (link("L1", "L2") != 0) e(9);
if (unlink("L1") != 0) e(10);
if (close(fd) != 0) e(11);
/* L2 exists at this point. */
if ( (fd = creat("L1", 0666)) < 0) e(12);
if (stat("L1", &stbuf) != 0) e(13);
if (stbuf.st_nlink != 1) e(14);
if (link("L1", "Dir/L2") != 0) e(15);
if (stat("L1", &stbuf) != 0) e(16);
if (stbuf.st_nlink != 2) e(17);
if (stat("Dir/L2", &stbuf) != 0) e(18);
if (stbuf.st_nlink != 2) e(19);
/* L1, L2, and Dir/L2 exist at this point. */
if (unlink("Dir/L2") != 0) e(20);
if (link("L1", "Dir/L2") != 0) e(21);
if (unlink("L1") != 0) e(22);
if (close(fd) != 0) e(23);
if (chdir("Dir") != 0) e(24);
if (unlink("L2") != 0) e(25);
if (chdir("..") != 0) e(26);
/* L2 exists at this point. Test linking to unsearchable dir. */
if (link("L2", "Dir/L2") != 0) e(27);
if (chmod("Dir", 0666) != 0) e(27);
if (link("L2", "Dir/L2") != -1) e(28);
if (errno != EACCES) e(29);
errno = 0;
if (link("Dir/L2", "L3") != -1) e(30);
if (errno != EACCES) e(31);
if (chmod("Dir", 0777) != 0) e(32);
if (unlink("Dir/L2") != 0) e(33);
if (unlink("L3") == 0) e(34);
/* L2 exists at this point. Test linking to unwriteable dir. */
if (chmod("Dir", 0555) != 0) e(35);
if (link("L2", "Dir/L2") != -1) e(36);
if (errno != EACCES) e(37);
if (chmod("Dir", 0777) != 0) e(38);
/* L2 exists at this point. Test linking mode 0 file. */
if (chmod("L2", 0) != 0) e(39);
if (link("L2", "L3") != 0) e(40);
if (stat("L3", &stbuf) != 0) e(41);
if (stbuf.st_nlink != 2) e(42);
if (unlink("L2") != 0) e(43);
/* L3 exists at this point. Test linking to an existing file. */
if ( (fd = creat("L1", 0666)) < 0) e(44);
if (link("L1", "L3") != -1) e(45);
if (errno != EEXIST) e(46);
errno = 0;
if (link("L1", "L1") != -1) e(47);
if (errno != EEXIST) e(48);
if (unlink("L3") != 0) e(49);
/* L1 exists at this point. Test creating too many links. */
if (LINK_MAX > 127) {
printf("[skip] "); /* takes too many resources */
} else {
name[0] = 'L';
name[1] = 'x';
name[2] = 1;
name[3] = 0;
for (i = 2; i <= LINK_MAX; i++) {
if (link("L1", name) != 0) e(50);
name[2]++;
}
if (stat("L1", &stbuf) != 0) e(51);
if (stbuf.st_nlink != LINK_MAX) e(52);
if (link("L1", "L2") != -1) e(53);
if (errno != EMLINK) e(54);
name[2] = 1;
for (i = 2; i <= LINK_MAX; i++) {
if (unlink(name) != 0) e(55);
name[2]++;
}
}
if (stat("L1", &stbuf) != 0) e(56);
if (stbuf.st_nlink != 1) e(57);
/* L1 exists. Test ENOENT. */
errno = 0;
if (link("xx/L1", "L2") != -1) e(58);
if (errno != ENOENT) e(59);
errno = 0;
if (link("L1", "xx/L2") != -1) e(60);
if (errno != ENOENT) e(61);
errno = 0;
if (link("L4", "L5") != -1) e(62);
if (errno != ENOENT) e(63);
errno = 0;
if (link("", "L5") != -1) e(64);
if (errno != ENOENT) e(65);
errno = 0;
if (link("L1", "") != -1) e(66);
if (errno != ENOENT) e(67);
/* L1 exists. Test ENOTDIR. */
errno = 0;
if (link("/dev/tty/x", "L2") != -1) e(68);
if (errno != ENOTDIR) e(69);
/* L1 exists. Test EPERM. */
if (link(".", "L2") != -1) e(70);
if (errno != EPERM) e(71);
/* L1 exists. Test unlink. */
if (link("L1", "Dir/L1") != 0) e(72);
if (chmod("Dir", 0666) != 0) e(73);
if (unlink("Dir/L1") != -1) e(74);
if (errno != EACCES) e(75);
errno = 0;
if (chmod("Dir", 0555) != 0) e(76);
if (unlink("Dir/L1") != -1) e(77);
if (errno != EACCES) e(78);
if (unlink("L7") != -1) e(79);
if (errno != ENOENT) e(80);
errno = 0;
if (unlink("") != -1) e(81);
if (errno != ENOENT) e(82);
if (unlink("Dir/L1/L2") != -1) e(83);
if (errno != ENOTDIR) e(84);
if (chmod("Dir", 0777) != 0) e(85);
if (unlink("Dir/L1") != 0) e(86);
if (unlink("Dir") != -1) e(87);
if (errno != EPERM) e(88);
if (unlink("L1") != 0) e(89);
if (system("rm -rf Dir") != 0) e(90);
if (close(fd) != 0) e(91);
}
void test20h()
{
/* Test access. */
int fd;
subtest = 10;
system("rm -rf A1");
if ( (fd = creat("A1", 0777)) < 0) e(1);
if (close(fd) != 0) e(2);
if (access("A1", R_OK) != 0) e(3);
if (access("A1", W_OK) != 0) e(4);
if (access("A1", X_OK) != 0) e(5);
if (access("A1", (R_OK|W_OK|X_OK)) != 0) e(6);
if (chmod("A1", 0400) != 0) e(7);
if (access("A1", R_OK) != 0) e(8);
if (access("A1", W_OK) != -1) e(9);
if (access("A1", X_OK) != -1) e(10);
if (access("A1", (R_OK|W_OK|X_OK)) != -1) e(11);
if (chmod("A1", 0077) != 0) e(12);
if (access("A1", R_OK) != -1) e(13);
if (access("A1", W_OK) != -1) e(14);
if (access("A1", X_OK) != -1) e(15);
if (access("A1", (R_OK|W_OK|X_OK)) != -1) e(16);
if (errno != EACCES) e(17);
if (access("", R_OK) != -1) e(18);
if (errno != ENOENT) e(19);
if (access("./A1/x", R_OK) != -1) e(20);
if (errno != ENOTDIR) e(21);
if (unlink("A1") != 0) e(22);
}
void test20i()
{
/* Test chmod. */
int fd, i;
struct stat stbuf;
subtest = 11;
system("rm -rf A1");
if ( (fd = creat("A1", 0777)) < 0) e(1);
for (i = 0; i < 511; i++) {
if (chmod("A1", i) != 0) e(100+i);
if (fstat(fd, &stbuf) != 0) e(200+i);
if ( (stbuf.st_mode&(S_IRWXU|S_IRWXG|S_IRWXO)) != i) e(300+i);
}
if (close(fd) != 0) e(2);
if (chmod("A1/x", 0777) != -1) e(3);
if (errno != ENOTDIR) e(4);
if (chmod("Axxx", 0777) != -1) e(5);
if (errno != ENOENT) e(6);
errno = 0;
if (chmod ("", 0777) != -1) e(7);
if (errno != ENOENT) e(8);
/* Now perform limited chown tests. These should work even as non su */
i = getuid();
/* DEBUG -- Not yet implemented
if (chown("A1", i, 0) != 0) e(9);
if (chown("A1", i, 1) != 0) e(10);
if (chown("A1", i, 2) != 0) e(11);
if (chown("A1", i, 3) != 0) e(12);
if (chown("A1", i, 4) != 0) e(13);
if (chown("A1", i, 0) != 0) e(14);
*/
if (unlink("A1") != 0) e(9);
}
void test20j()
{
/* Test utime. */
int fd;
time_t tloc;
struct utimbuf times;
struct stat stbuf;
subtest = 12;
if (system("rm -rf A2") != 0) e(1);
if ( (fd = creat("A2", 0666)) < 0) e(2);
times.modtime = 100;
if (utime("A2", &times) != 0) e(3);
if (stat("A2", &stbuf) != 0) e(4);
if (stbuf.st_mtime != 100) e(5);
tloc = time((time_t *)NULL); /* get current time */
times.modtime = tloc;
if (utime("A2", &times) != 0) e(6);
if (stat("A2", &stbuf) != 0) e(7);
if (stbuf.st_mtime != tloc) e(8);
if (close(fd) != 0) e(9);
if (unlink("A2") != 0) e(10);
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
fflush(stdout); /* stdout and stderr are mixed horribly */
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

691
test/test21.c Normal file
View File

@@ -0,0 +1,691 @@
/* POSIX test program (21). Author: Andy Tanenbaum */
/* The following POSIX calls are tested:
*
* rename(), mkdir(), rmdir()
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define ITERATIONS 1
#define MAX_ERROR 4
int subtest, errct;
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test21a, (void));
_PROTOTYPE(void test21b, (void));
_PROTOTYPE(void test21c, (void));
_PROTOTYPE(void test21d, (void));
_PROTOTYPE(void test21e, (void));
_PROTOTYPE(void test21f, (void));
_PROTOTYPE(void test21g, (void));
_PROTOTYPE(void test21h, (void));
_PROTOTYPE(void test21i, (void));
_PROTOTYPE(void test21k, (void));
_PROTOTYPE(void test21l, (void));
_PROTOTYPE(void test21m, (void));
_PROTOTYPE(void test21n, (void));
_PROTOTYPE(void test21o, (void));
_PROTOTYPE(int get_link, (char *name));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (geteuid() == 0 || getuid() == 0) {
printf("Test 21 cannot run as root; test aborted\n");
exit(1);
}
if (argc == 2) m = atoi(argv[1]);
printf("Test 21 ");
fflush(stdout);
system("rm -rf DIR_21; mkdir DIR_21");
chdir("DIR_21");
for (i = 0; i < ITERATIONS; i++) {
if (m & 00001) test21a();
if (m & 00002) test21b();
if (m & 00004) test21c();
if (m & 00010) test21d();
if (m & 00020) test21e();
if (m & 00040) test21f();
if (m & 01000) test21g();
if (m & 00200) test21h();
if (m & 00400) test21i();
if (m & 01000) test21k();
if (m & 02000) test21l();
if (m & 04000) test21m();
if (m & 010000) test21n();
if (m & 020000) test21o();
}
quit();
return(-1); /* impossible */
}
void test21a()
{
/* Test rename(). */
int fd, fd2;
char buf[PATH_MAX+1], buf1[PATH_MAX+1], buf2[PATH_MAX+1];
struct stat stat1, stat2;
subtest = 1;
unlink("A1"); /* get rid of it if it exists */
unlink("A2"); /* get rid of it if it exists */
unlink("A3"); /* get rid of it if it exists */
unlink("A4"); /* get rid of it if it exists */
unlink("A5"); /* get rid of it if it exists */
unlink("A6"); /* get rid of it if it exists */
unlink("A7"); /* get rid of it if it exists */
/* Basic test. Rename A1 to A2 and then A2 to A3. */
if ( (fd=creat("A1", 0666)) < 0) e(1);
if (write(fd, buf, 20) != 20) e(2);
if (close(fd) < 0) e(3);
if (rename("A1", "A2") < 0) e(4);
if ( (fd=open("A2", O_RDONLY)) < 0) e(5);
if (rename("A2", "A3") < 0) e(6);
if ( (fd2=open("A3", O_RDONLY)) < 0) e(7);
if (close(fd) != 0) e(8);
if (close(fd2) != 0) e(9);
if (unlink("A3") != 0) e(10);
/* Now get the absolute path name of the current directory using getcwd()
* and use it to test RENAME using different combinations of relative and
* absolute path names.
*/
if (getcwd(buf, PATH_MAX) == (char *) NULL) e(11);
if ( (fd = creat("A4", 0666)) < 0) e(12);
if (write(fd, buf, 30) != 30) e(13);
if (close(fd) != 0) e(14);
strcpy(buf1, buf);
strcat(buf1, "/A4");
if (rename(buf1, "A5") != 0) e(15); /* rename(absolute, relative) */
if (access("A5", 6) != 0) e(16); /* use access to see if file exists */
strcpy(buf2, buf);
strcat(buf2, "/A6");
if (rename("A5", buf2) != 0) e(17); /* rename(relative, absolute) */
if (access("A6", 6) != 0) e(18);
if (access(buf2, 6) != 0) e(19);
strcpy(buf1, buf);
strcat(buf1, "/A6");
strcpy(buf2, buf);
strcat(buf2, "/A7");
if (rename(buf1, buf2) != 0) e(20); /* rename(absolute, absolute) */
if (access("A7", 6) != 0) e(21);
if (access(buf2, 6) != 0) e(22);
/* Try renaming using names like "./A8" */
if (rename("A7", "./A8") != 0) e(23);
if (access("A8", 6) != 0) e(24);
if (rename("./A8", "A9") != 0) e(25);
if (access("A9", 6) != 0) e(26);
if (rename("./A9", "./A10") != 0) e(27);
if (access("A10", 6) != 0) e(28);
if (access("./A10", 6) != 0) e(29);
if (unlink("A10") != 0) e(30);
/* Now see if directories can be renamed. */
if (system("rm -rf ?uzzy scsi") != 0) e(31);
if (system("mkdir fuzzy") != 0) e(32);
if (rename("fuzzy", "wuzzy") != 0) e(33);
if ( (fd=creat("wuzzy/was_a_bear", 0666)) < 0) e(34);
if (access("wuzzy/was_a_bear", 6) != 0) e(35);
if (unlink("wuzzy/was_a_bear") != 0) e(36);
if (close(fd) != 0) e(37);
if (rename("wuzzy", "buzzy") != 0) e(38);
if (system("rmdir buzzy") != 0) e(39);
/* Now start testing the case that 'new' exists. */
if ( (fd = creat("horse", 0666)) < 0) e(40);
if ( (fd2 = creat("sheep", 0666)) < 0) e(41);
if (write(fd, buf, PATH_MAX) != PATH_MAX) e(42);
if (write(fd2, buf, 23) != 23) e(43);
if (stat("horse", &stat1) != 0) e(44);
if (rename("horse", "sheep") != 0) e(45);
if (stat("sheep", &stat2) != 0) e(46);
if (stat1.st_dev != stat2.st_dev) e(47);
if (stat1.st_ino != stat2.st_ino) e(48);
if (stat2.st_size != PATH_MAX) e(49);
if (access("horse", 6) == 0) e(50);
if (close(fd) != 0) e(51);
if (close(fd2) != 0) e(52);
if (rename("sheep", "sheep") != 0) e(53);
if (unlink("sheep") != 0) e(54);
/* Now try renaming something to a directory that already exists. */
if (system("mkdir fuzzy wuzzy") != 0) e(55);
if ( (fd = creat("fuzzy/was_a_bear", 0666)) < 0) e(56);
if (close(fd) != 0) e(57);
if (rename("fuzzy", "wuzzy") != 0) e(58); /* 'new' is empty dir */
if (system("mkdir scsi") != 0) e(59);
if (rename("scsi", "wuzzy") == 0) e(60); /* 'new' is full dir */
if (errno != EEXIST && errno != ENOTEMPTY) e(61);
/* Test 14 character names--always tricky. */
if (rename("wuzzy/was_a_bear", "wuzzy/was_not_a_bear") != 0) e(62);
if (access("wuzzy/was_not_a_bear", 6) != 0) e(63);
if (rename("wuzzy/was_not_a_bear", "wuzzy/was_not_a_duck") != 0) e(64);
if (access("wuzzy/was_not_a_duck", 6) != 0) e(65);
if (rename("wuzzy/was_not_a_duck", "wuzzy/was_a_bird") != 0) e(65);
if (access("wuzzy/was_a_bird", 6) != 0) e(66);
/* Test moves between directories. */
if (rename("wuzzy/was_a_bird", "beast") != 0) e(67);
if (access("beast", 6) != 0) e(68);
if (rename("beast", "wuzzy/was_a_cat") != 0) e(69);
if (access("wuzzy/was_a_cat", 6) != 0) e(70);
/* Test error conditions. 'scsi' and 'wuzzy/was_a_cat' exist now. */
if (rename("wuzzy/was_a_cat", "wuzzy/was_a_dog") != 0) e(71);
if (access("wuzzy/was_a_dog", 6) != 0) e(72);
if (chmod("wuzzy", 0) != 0) e(73);
errno = 0;
if (rename("wuzzy/was_a_dog", "wuzzy/was_a_pig") != -1) e(74);
if (errno != EACCES) e(75);
errno = 0;
if (rename("wuzzy/was_a_dog", "doggie") != -1) e(76);
if (errno != EACCES) e(77);
errno = 0;
if ( (fd = creat("beast", 0666)) < 0) e(78);
if (close(fd) != 0) e(79);
if (rename("beast", "wuzzy/was_a_twit") != -1) e(80);
if (errno != EACCES) e(81);
errno = 0;
if (rename("beast", "wuzzy") != -1) e(82);
if (errno != EISDIR) e(83);
errno = 0;
if (rename("beest", "baste") != -1) e(84);
if (errno != ENOENT) e(85);
errno = 0;
if (rename("wuzzy", "beast") != -1) e(86);
if (errno != ENOTDIR) e(87);
/* Test prefix rule. */
errno = 0;
if (chmod("wuzzy", 0777) != 0) e(88);
if (unlink("wuzzy/was_a_dog") != 0) e(89);
strcpy(buf1, buf);
strcat(buf1, "/wuzzy");
if (rename(buf, buf1) != -1) e(90);
if (errno != EINVAL) e(91);
if (system("rm -rf wuzzy beast scsi") != 0) e(92);
}
void test21b()
{
/* Test mkdir() and rmdir(). */
int i;
char name[3];
struct stat statbuf;
subtest = 2;
/* Simple stuff. */
if (mkdir("D1", 0700) != 0) e(1);
if (stat("D1", &statbuf) != 0) e(2);
if (!S_ISDIR(statbuf.st_mode)) e(3);
if ( (statbuf.st_mode & 0777) != 0700) e(4);
if (rmdir("D1") != 0) e(5);
/* Make and remove 40 directories. By doing so, the directory has to
* grow to 2 blocks. That presents plenty of opportunity for bugs.
*/
name[0] = 'D';
name[2] = '\0';
for (i = 0; i < 40; i++) {
name[1] = 'A' + i;
if (mkdir(name, 0700 + i%7) != 0) e(10+i); /* for simplicity */
}
for (i = 0; i < 40; i++) {
name[1] = 'A' + i;
if (rmdir(name) != 0) e(50+i);
}
}
void test21c()
{
/* Test mkdir() and rmdir(). */
subtest = 3;
if (mkdir("D1", 0777) != 0) e(1);
if (mkdir("D1/D2", 0777) != 0) e(2);
if (mkdir("D1/D2/D3", 0777) != 0) e(3);
if (mkdir("D1/D2/D3/D4", 0777) != 0) e(4);
if (mkdir("D1/D2/D3/D4/D5", 0777) != 0) e(5);
if (mkdir("D1/D2/D3/D4/D5/D6", 0777) != 0) e(6);
if (mkdir("D1/D2/D3/D4/D5/D6/D7", 0777) != 0) e(7);
if (mkdir("D1/D2/D3/D4/D5/D6/D7/D8", 0777) != 0) e(8);
if (mkdir("D1/D2/D3/D4/D5/D6/D7/D8/D9", 0777) != 0) e(9);
if (access("D1/D2/D3/D4/D5/D6/D7/D8/D9", 7) != 0) e(10);
if (rmdir("D1/D2/D3/D4/D5/D6/D7/D8/D9") != 0) e(11);
if (rmdir("D1/D2/D3/D4/D5/D6/D7/D8") != 0) e(12);
if (rmdir("D1/D2/D3/D4/D5/D6/D7") != 0) e(13);
if (rmdir("D1/D2/D3/D4/D5/D6") != 0) e(11);
if (rmdir("D1/D2/D3/D4/D5") != 0) e(13);
if (rmdir("D1/D2/D3/D4") != 0) e(14);
if (rmdir("D1/D2/D3") != 0) e(15);
if (rmdir("D1/D2") != 0) e(16);
if (rmdir("D1") != 0) e(17);
}
void test21d()
{
/* Test making directories with files and directories in them. */
int fd1, fd2, fd3, fd4, fd5, fd6, fd7, fd8, fd9;
subtest = 4;
if (mkdir("D1", 0777) != 0) e(1);
if (mkdir("D1/D2", 0777) != 0) e(2);
if (mkdir("./D1/D3", 0777) != 0) e(3);
if (mkdir("././D1/D4", 0777) != 0) e(4);
if ( (fd1 = creat("D1/D2/x", 0700)) < 0) e(5);
if ( (fd2 = creat("D1/D2/y", 0700)) < 0) e(6);
if ( (fd3 = creat("D1/D2/z", 0700)) < 0) e(7);
if ( (fd4 = creat("D1/D3/x", 0700)) < 0) e(8);
if ( (fd5 = creat("D1/D3/y", 0700)) < 0) e(9);
if ( (fd6 = creat("D1/D3/z", 0700)) < 0) e(10);
if ( (fd7 = creat("D1/D4/x", 0700)) < 0) e(11);
if ( (fd8 = creat("D1/D4/y", 0700)) < 0) e(12);
if ( (fd9 = creat("D1/D4/z", 0700)) < 0) e(13);
if (unlink("D1/D2/z") != 0) e(14);
if (unlink("D1/D2/y") != 0) e(15);
if (unlink("D1/D2/x") != 0) e(16);
if (unlink("D1/D3/x") != 0) e(17);
if (unlink("D1/D3/z") != 0) e(18);
if (unlink("D1/D3/y") != 0) e(19);
if (unlink("D1/D4/y") != 0) e(20);
if (unlink("D1/D4/z") != 0) e(21);
if (unlink("D1/D4/x") != 0) e(22);
if (rmdir("D1/D2") != 0) e(23);
if (rmdir("D1/D3") != 0) e(24);
if (rmdir("D1/D4") != 0) e(25);
if (rmdir("D1") != 0) e(26);
if (close(fd1) != 0) e(27);
if (close(fd2) != 0) e(28);
if (close(fd3) != 0) e(29);
if (close(fd4) != 0) e(30);
if (close(fd5) != 0) e(31);
if (close(fd6) != 0) e(32);
if (close(fd7) != 0) e(33);
if (close(fd8) != 0) e(34);
if (close(fd9) != 0) e(35);
}
void test21e()
{
/* Test error conditions. */
subtest = 5;
if (mkdir("D1", 0677) != 0) e(1);
errno = 0;
if (mkdir("D1/D2", 0777) != -1) e(2);
if (errno != EACCES) e(3);
if (chmod ("D1", 0577) != 0) e(4);
errno = 0;
if (mkdir("D1/D2", 0777) != -1) e(5);
if (errno != EACCES) e(6);
if (chmod ("D1", 0777) != 0) e(7);
errno = 0;
if (mkdir("D1", 0777) != -1) e(8);
if (errno != EEXIST) e(9);
#if NAME_MAX == 14
if (mkdir("D1/ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0777) != 0) e(10);
if (access("D1/ABCDEFGHIJKLMN", 7 ) != 0) e(11);
if (rmdir("D1/ABCDEFGHIJKLMNOPQ") != 0) e(12);
if (access("D1/ABCDEFGHIJKLMN", 7 ) != -1) e(13);
#endif
errno = 0;
if (mkdir("D1/D2/x", 0777) != -1) e(14);
if (errno != ENOENT) e(15);
/* A particularly nasty test is when the parent has mode 0. Although
* this is unlikely to work, it had better not muck up the file system
*/
if (mkdir("D1/D2", 0777) != 0) e(16);
if (chmod("D1", 0) != 0) e(17);
errno = 0;
if (rmdir("D1/D2") != -1) e(18);
if (errno != EACCES) e(19);
if (chmod("D1", 0777) != 0) e(20);
if (rmdir("D1/D2") != 0) e(21);
if (rmdir("D1") != 0) e(22);
}
void test21f()
{
/* The rename() function affects the link count of all the files and
* directories it goes near. Test to make sure it gets everything ok.
* There are four cases:
*
* 1. rename("d1/file1", "d1/file2"); - rename file without moving it
* 2. rename("d1/file1", "d2/file2"); - move a file to another dir
* 3. rename("d1/dir1", "d2/dir2"); - rename a dir without moving it
* 4. rename("d1/dir1", "d2/dir2"); - move a dir to another dir
*
* Furthermore, a distinction has to be made when the target file exists
* and when it does not exist, giving 8 cases in all.
*/
int fd, D1_before, D1_after, x_link, y_link;
/* Test case 1: renaming a file within the same directory. */
subtest = 6;
if (mkdir("D1", 0777) != 0) e(1);
if ( (fd = creat("D1/x", 0777)) < 0) e(2);
if (close(fd) != 0) e(3);
D1_before = get_link("D1");
x_link = get_link("D1/x");
if (rename("D1/x", "D1/y") != 0) e(4);
y_link = get_link("D1/y");
D1_after = get_link("D1");
if (D1_before != 2) e(5);
if (D1_after != 2) e(6);
if (x_link != 1) e(7);
if (y_link != 1) e(8);
if (access("D1/y", 7) != 0) e(9);
if (unlink("D1/y") != 0) e(10);
if (rmdir("D1") != 0) e(11);
}
void test21g()
{
int fd, D1_before, D1_after, D2_before, D2_after, x_link, y_link;
/* Test case 2: move a file to a new directory. */
subtest = 7;
if (mkdir("D1", 0777) != 0) e(1);
if (mkdir("D2", 0777) != 0) e(2);
if ( (fd = creat("D1/x", 0777)) < 0) e(3);
if (close(fd) != 0) e(4);
D1_before = get_link("D1");
D2_before = get_link("D2");
x_link = get_link("D1/x");
if (rename("D1/x", "D2/y") != 0) e(5);
y_link = get_link("D2/y");
D1_after = get_link("D1");
D2_after = get_link("D2");
if (D1_before != 2) e(6);
if (D2_before != 2) e(7);
if (D1_after != 2) e(8);
if (D2_after != 2) e(9);
if (x_link != 1) e(10);
if (y_link != 1) e(11);
if (access("D2/y", 7) != 0) e(12);
if (unlink("D2/y") != 0) e(13);
if (rmdir("D1") != 0) e(14);
if (rmdir("D2") != 0) e(15);
}
void test21h()
{
int D1_before, D1_after, x_link, y_link;
/* Test case 3: renaming a directory within the same directory. */
subtest = 8;
if (mkdir("D1", 0777) != 0) e(1);
if (mkdir("D1/X", 0777) != 0) e(2);
D1_before = get_link("D1");
x_link = get_link("D1/X");
if (rename("D1/X", "D1/Y") != 0) e(3);
y_link = get_link("D1/Y");
D1_after = get_link("D1");
if (D1_before != 3) e(4);
if (D1_after != 3) e(5);
if (x_link != 2) e(6);
if (y_link != 2) e(7);
if (access("D1/Y", 7) != 0) e(8);
if (rmdir("D1/Y") != 0) e(9);
if (get_link("D1") != 2) e(10);
if (rmdir("D1") != 0) e(11);
}
void test21i()
{
int D1_before, D1_after, D2_before, D2_after, x_link, y_link;
/* Test case 4: move a directory to a new directory. */
subtest = 9;
if (mkdir("D1", 0777) != 0) e(1);
if (mkdir("D2", 0777) != 0) e(2);
if (mkdir("D1/X", 0777) != 0) e(3);
D1_before = get_link("D1");
D2_before = get_link("D2");
x_link = get_link("D1/X");
if (rename("D1/X", "D2/Y") != 0) e(4);
y_link = get_link("D2/Y");
D1_after = get_link("D1");
D2_after = get_link("D2");
if (D1_before != 3) e(5);
if (D2_before != 2) e(6);
if (D1_after != 2) e(7);
if (D2_after != 3) e(8);
if (x_link != 2) e(9);
if (y_link != 2) e(10);
if (access("D2/Y", 7) != 0) e(11);
if (rename("D2/Y", "D1/Z") != 0) e(12);
if (get_link("D1") != 3) e(13);
if (get_link("D2") != 2) e(14);
if (rmdir("D1/Z") != 0) e(15);
if (get_link("D1") != 2) e(16);
if (rmdir("D1") != 0) e(17);
if (rmdir("D2") != 0) e(18);
}
void test21k()
{
/* Now test the same 4 cases, except when the target exists. */
int fd, D1_before, D1_after, x_link, y_link;
/* Test case 5: renaming a file within the same directory. */
subtest = 10;
if (mkdir("D1", 0777) != 0) e(1);
if ( (fd = creat("D1/x", 0777)) < 0) e(2);
if (close(fd) != 0) e(3);
if ( (fd = creat("D1/y", 0777)) < 0) e(3);
if (close(fd) != 0) e(4);
D1_before = get_link("D1");
x_link = get_link("D1/x");
if (rename("D1/x", "D1/y") != 0) e(5);
y_link = get_link("D1/y");
D1_after = get_link("D1");
if (D1_before != 2) e(6);
if (D1_after != 2) e(7);
if (x_link != 1) e(8);
if (y_link != 1) e(9);
if (access("D1/y", 7) != 0) e(10);
if (unlink("D1/y") != 0) e(11);
if (rmdir("D1") != 0) e(12);
}
void test21l()
{
int fd, D1_before, D1_after, D2_before, D2_after, x_link, y_link;
/* Test case 6: move a file to a new directory. */
subtest = 11;
if (mkdir("D1", 0777) != 0) e(1);
if (mkdir("D2", 0777) != 0) e(2);
if ( (fd = creat("D1/x", 0777)) < 0) e(3);
if (close(fd) != 0) e(4);
if ( (fd = creat("D2/y", 0777)) < 0) e(5);
if (close(fd) != 0) e(6);
D1_before = get_link("D1");
D2_before = get_link("D2");
x_link = get_link("D1/x");
if (rename("D1/x", "D2/y") != 0) e(7);
y_link = get_link("D2/y");
D1_after = get_link("D1");
D2_after = get_link("D2");
if (D1_before != 2) e(8);
if (D2_before != 2) e(9);
if (D1_after != 2) e(10);
if (D2_after != 2) e(11);
if (x_link != 1) e(12);
if (y_link != 1) e(13);
if (access("D2/y", 7) != 0) e(14);
if (unlink("D2/y") != 0) e(15);
if (rmdir("D1") != 0) e(16);
if (rmdir("D2") != 0) e(17);
}
void test21m()
{
int D1_before, D1_after, x_link, y_link;
/* Test case 7: renaming a directory within the same directory. */
subtest = 12;
if (mkdir("D1", 0777) != 0) e(1);
if (mkdir("D1/X", 0777) != 0) e(2);
if (mkdir("D1/Y", 0777) != 0) e(3);
D1_before = get_link("D1");
x_link = get_link("D1/X");
if (rename("D1/X", "D1/Y") != 0) e(4);
y_link = get_link("D1/Y");
D1_after = get_link("D1");
if (D1_before != 4) e(5);
if (D1_after != 3) e(6);
if (x_link != 2) e(7);
if (y_link != 2) e(8);
if (access("D1/Y", 7) != 0) e(9);
if (rmdir("D1/Y") != 0) e(10);
if (get_link("D1") != 2) e(11);
if (rmdir("D1") != 0) e(12);
}
void test21n()
{
int D1_before, D1_after, D2_before, D2_after, x_link, y_link;
/* Test case 8: move a directory to a new directory. */
subtest = 13;
if (mkdir("D1", 0777) != 0) e(1);
if (mkdir("D2", 0777) != 0) e(2);
if (mkdir("D1/X", 0777) != 0) e(3);
if (mkdir("D2/Y", 0777) != 0) e(4);
D1_before = get_link("D1");
D2_before = get_link("D2");
x_link = get_link("D1/X");
if (rename("D1/X", "D2/Y") != 0) e(5);
y_link = get_link("D2/Y");
D1_after = get_link("D1");
D2_after = get_link("D2");
if (D1_before != 3) e(6);
if (D2_before != 3) e(7);
if (D1_after != 2) e(8);
if (D2_after != 3) e(9);
if (x_link != 2) e(10);
if (y_link != 2) e(11);
if (access("D2/Y", 7) != 0) e(12);
if (rename("D2/Y", "D1/Z") != 0) e(13);
if (get_link("D1") != 3) e(14);
if (get_link("D2") != 2) e(15);
if (rmdir("D1/Z") != 0) e(16);
if (get_link("D1") != 2) e(17);
if (rmdir("D1") != 0) e(18);
if (rmdir("D2") != 0) e(19);
}
void test21o()
{
/* Test trying to remove . and .. */
subtest = 14;
if (mkdir("D1", 0777) != 0) e(1);
if (chdir("D1") != 0) e(2);
if (rmdir(".") == 0) e(3);
if (rmdir("..") == 0) e(4);
if (mkdir("D2", 0777) != 0) e(5);
if (mkdir("D3", 0777) != 0) e(6);
if (mkdir("D4", 0777) != 0) e(7);
if (rmdir("D2/../D3/../D4") != 0) e(8); /* legal way to remove D4 */
if (rmdir("D2/../D3/../D2/..") == 0) e(9); /* removing self is illegal */
if (rmdir("D2/../D3/../D2/../..") == 0) e(10);/* removing parent is illegal*/
if (rmdir("../D1/../D1/D3") != 0) e(11); /* legal way to remove D3 */
if (rmdir("./D2/../D2") != 0) e(12); /* legal way to remove D2 */
if (chdir("..") != 0) e(13);
if (rmdir("D1") != 0) e(14);
}
int get_link(name)
char *name;
{
struct stat statbuf;
if (stat(name, &statbuf) != 0) {
printf("Unable to stat %s\n", name);
errct++;
return(-1);
}
return(statbuf.st_nlink);
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

202
test/test22.c Normal file
View File

@@ -0,0 +1,202 @@
/* test22: umask() (p) Jan-Mark Wams. email: jms@cs.vu.nl */
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <stdio.h>
#define MAX_ERROR 4 /* Stop after ``MAX_ERROR'' errors. */
#define ITERATIONS 2
#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)
int errct = 0; /* Total error counter. */
int subtest = 1;
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test22a, (void));
_PROTOTYPE(int mode, (char *filename));
_PROTOTYPE(int umode, (char *filename));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 22 ");
fflush(stdout);
system("chmod 777 DIR_22/* DIR_22/*/* > /dev/null 2>&1");
System("rm -rf DIR_22; mkdir DIR_22");
Chdir("DIR_22");
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test22a();
}
quit();
}
void test22a()
{
int fd1, fd2;
int i, oldmask;
int stat_loc; /* For the wait sys call. */
subtest = 1;
system("chmod 777 ../DIR_22/* ../DIR_22/*/* > /dev/null 2>&1");
System("rm -rf ../DIR_22/*");
oldmask = 0123; /* Set oldmask and umask. */
umask(oldmask); /* Set oldmask and umask. */
/* Check all the possible values of umask. */
for (i = 0000; i <= 0777; i++) {
if (oldmask != umask(i)) e(1); /* set umask() */
fd1 = open("open", O_CREAT, 0777);
if (fd1 != 3) e(2); /* test open(), */
fd2 = creat("creat", 0777);
if (fd2 != 4) e(3); /* creat(), */
if (mkdir("dir", 0777) != 0) e(4); /* mkdir(), */
if (mkfifo("fifo", 0777) != 0) e(5); /* and mkfifo(). */
if (umode("open") != i) e(6); /* see if they have */
if (umode("creat") != i) e(7); /* the proper mode */
if (umode("dir") != i) e(8);
if (umode("fifo") != i) e(9);
/* Clean up */
if (close(fd1) != 0) e(10);
if (close(fd2) != 0) e(11); /* close fd's and */
unlink("open"); /* clean the dir */
unlink("creat");
rmdir("dir");
unlink("fifo");
oldmask = i; /* save current mask */
}
/* Check-reset mask */
if (umask(0124) != 0777) e(12);
/* Check if a umask of 0000 leaves the modes alone. */
if (umask(0000) != 0124) e(13);
for (i = 0000; i <= 0777; i++) {
fd1 = open("open", O_CREAT, i);
if (fd1 != 3) e(14); /* test open(), */
fd2 = creat("creat", i);
if (fd2 != 4) e(15); /* creat(), */
if (mkdir("dir", i) != 0) e(16); /* mkdir(), */
if (mkfifo("fifo", i) != 0) e(17); /* and mkfifo(). */
if (mode("open") != i) e(18); /* see if they have */
if (mode("creat") != i) e(19); /* the proper mode */
if (mode("dir") != i) e(20);
if (mode("fifo") != i) e(21);
/* Clean up */
if (close(fd1) != 0) e(22);
if (close(fd2) != 0) e(23);
if (unlink("open") != 0) e(24);
unlink("creat");
rmdir("dir");
unlink("fifo");
}
/* Check if umask survives a fork() */
if (umask(0124) != 0000) e(25);
switch (fork()) {
case -1: fprintf(stderr, "Can't fork\n"); break;
case 0:
mkdir("bar", 0777); /* child makes a dir */
exit(0);
default:
if (wait(&stat_loc) == -1) e(26);
}
if (umode("bar") != 0124) e(27);
rmdir("bar");
/* Check if umask in child changes umask in parent. */
switch (fork()) {
case -1: fprintf(stderr, "Can't fork\n"); break;
case 0:
switch (fork()) {
case -1:
fprintf(stderr, "Can't fork\n");
break;
case 0:
if (umask(0432) != 0124) e(28);
exit(0);
default:
if (wait(&stat_loc) == -1) e(29);
}
if (umask(0423) != 0124) e(30);
exit(0);
default:
if (wait(&stat_loc) == -1) e(31);
}
if (umask(0342) != 0124) e(32);
/* See if extra bits are ignored */
if (umask(0xFFFF) != 0342) e(33);
if (umask(0xFE00) != 0777) e(34);
if (umask(01777) != 0000) e(35);
if (umask(0022) != 0777) e(36);
}
int mode(arg)
char *arg;
{ /* return the file mode. */
struct stat st;
Stat(arg, &st);
return st.st_mode & 0777;
}
int umode(arg)
char *arg;
{ /* return the umask used for this file */
return 0777 ^ mode(arg);
}
void e(n)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
system("chmod 777 ../DIR_22/* ../DIR_22/*/* > /dev/null 2>&1");
System("rm -rf DIR_22");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

420
test/test23.c Normal file
View File

@@ -0,0 +1,420 @@
/* test23: chdir(), getcwd() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <limits.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 3
#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)
int errct;
int subtest;
int superuser; /* True if we are root. */
char cwd[PATH_MAX]; /* Space for path names. */
char cwd2[PATH_MAX];
char buf[PATH_MAX];
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test23a, (void));
_PROTOTYPE(void test23b, (void));
_PROTOTYPE(void test23c, (void));
_PROTOTYPE(void makelongnames, (void)); /* Fill MaxName etc. */
_PROTOTYPE(char *last_index, (char *string, int ch));
_PROTOTYPE(char *my_getcwd, (char *buf, int size));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 23 ");
fflush(stdout);
System("rm -rf DIR_23; mkdir DIR_23");
Chdir("DIR_23");
makelongnames();
superuser = (geteuid() == 0);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test23a(); /* Test normal operation */
if (m & 0002) test23b(); /* Test critical operation */
if (m & 0004) test23c(); /* Test error operation */
}
quit();
}
void test23a()
{ /* Test normal operation. */
register int i;
subtest = 1;
System("rm -rf ../DIR_23/*");
/* Let's do some fiddeling with path names. */
if (getcwd(cwd, PATH_MAX) != cwd) e(1);
if (chdir(cwd) != 0) e(2);
if (getcwd(buf, PATH_MAX) != buf) e(3);
if (strcmp(buf, cwd) != 0) e(4);
if (chdir(".") != 0) e(5);
if (getcwd(buf, PATH_MAX) != buf) e(6);
if (strcmp(buf, cwd) != 0) e(7);
if (chdir("./././.") != 0) e(8);
if (getcwd(buf, PATH_MAX) != buf) e(9);
if (strcmp(buf, cwd) != 0) e(10);
/* Creat a working dir named "foo", remove any previous residues. */
System("rm -rf foo");
if (mkdir("foo", 0777) != 0) e(11);
/* Do some more fiddeling with path names. */
if (chdir("foo/.././foo/..") != 0) e(12); /* change to cwd */
if (getcwd(buf, PATH_MAX) != buf) e(13);
if (strcmp(buf, cwd) != 0) e(13);
if (chdir("foo") != 0) e(14); /* change to foo */
if (chdir("..") != 0) e(15); /* and back again */
if (getcwd(buf, PATH_MAX) != buf) e(16);
if (strcmp(buf, cwd) != 0) e(17);
/* Make 30 sub dirs, eg. ./bar/bar/bar/bar/bar...... */
System("rm -rf bar"); /* get ridd of bar */
for (i = 0; i < 30; i++) {
if (mkdir("bar", 0777) != 0) e(18);
if (chdir("bar") != 0) e(19); /* change to bar */
}
for (i = 0; i < 30; i++) {
if (chdir("..") != 0) e(20); /* and back again */
if (rmdir("bar") != 0) e(21);
}
/* Make sure we are back where we started. */
if (getcwd(buf, PATH_MAX) != buf) e(22);
if (strcmp(buf, cwd) != 0) e(23);
System("rm -rf bar"); /* just incase */
/* Do some normal checks on `Chdir()' and `getcwd()' */
if (chdir("/") != 0) e(24);
if (getcwd(buf, PATH_MAX) != buf) e(25);
if (strcmp(buf, "/") != 0) e(26);
if (chdir("..") != 0) e(27); /* go to parent of / */
if (getcwd(buf, PATH_MAX) != buf) e(28);
if (strcmp(buf, "/") != 0) e(29);
if (chdir(cwd) != 0) e(30);
if (getcwd(buf, PATH_MAX) != buf) e(31);
if (strcmp(buf, cwd) != 0) e(32);
if (chdir("/etc") != 0) e(33); /* /etc might be on RAM */
if (getcwd(buf, PATH_MAX) != buf) e(34); /* might make a difference */
if (strcmp(buf, "/etc") != 0) e(35);
if (chdir(cwd) != 0) e(36);
if (getcwd(buf, PATH_MAX) != buf) e(37);
if (strcmp(buf, cwd) != 0) e(38);
if (chdir(".//.//") != 0) e(39); /* .//.// == current dir */
if (getcwd(buf, PATH_MAX) != buf) e(40);
if (strcmp(buf, cwd) != 0) e(41); /* we might be at '/' */
#ifdef _MINIX
/* XXX - my_getcwd() is old rubbish. It reads the directory directly instead
* of through the directory library. It uses a fixed size buffer instead of
* a size related to PATH_MAX, NAME_MAX or the size required.
*/
if (my_getcwd(buf, PATH_MAX) != buf) e(42); /* get cwd my way */
if (strcmp(cwd, buf) != 0) e(43);
#endif
System("rm -rf foo");
}
void test23b()
{ /* Test critical values. */
subtest = 2;
System("rm -rf ../DIR_23/*");
/* Fiddle with the size (2nt) parameter of `getcwd ()'. */
if (getcwd(cwd, PATH_MAX) != cwd) e(1); /* get cwd */
if (getcwd(buf, strlen(cwd)) != (char *) 0) e(2); /* size 1 to small */
if (errno != ERANGE) e(3);
if (getcwd(buf, PATH_MAX) != buf) e(4);
if (strcmp(buf, cwd) != 0) e(5);
Chdir(cwd); /* getcwd might cd / */
if (getcwd(buf, strlen(cwd) + 1) != buf) e(6); /* size just ok */
if (getcwd(buf, PATH_MAX) != buf) e(7);
if (strcmp(buf, cwd) != 0) e(8);
/* Let's see how "MaxName" and "ToLongName" are handled. */
if (mkdir(MaxName, 0777) != 0) e(9);
if (chdir(MaxName) != 0) e(10);
if (chdir("..") != 0) e(11);
if (rmdir(MaxName) != 0) e(12);
if (getcwd(buf, PATH_MAX) != buf) e(13);
if (strcmp(buf, cwd) != 0) e(14);
if (chdir(MaxPath) != 0) e(15);
if (getcwd(buf, PATH_MAX) != buf) e(16);
if (strcmp(buf, cwd) != 0) e(17);
if (chdir(ToLongName) != -1) e(18);
#ifdef _POSIX_NO_TRUNC
# if _POSIX_NO_TRUNC - 0 != -1
if (errno != ENAMETOOLONG) e(20);
# else
if (errno != ENOENT) e(20);
# endif
#else
# include "error, this case requires dynamic checks and is not handled"
#endif
if (getcwd(buf, PATH_MAX) != buf) e(21);
if (strcmp(buf, cwd) != 0) e(22);
if (chdir(ToLongPath) != -1) e(23);
if (errno != ENAMETOOLONG) e(24);
if (getcwd(buf, PATH_MAX) != buf) e(25);
if (strcmp(buf, cwd) != 0) e(26);
}
void test23c()
{ /* Check reaction to errors */
subtest = 3;
System("rm -rf ../DIR_23/*");
if (getcwd(cwd, PATH_MAX) != cwd) e(1); /* get cwd */
/* Creat a working dir named "foo", remove any previous residues. */
System("rm -rf foo; mkdir foo");
/* Check some obviouse errors. */
if (chdir("") != -1) e(2);
if (errno != ENOENT) e(3);
if (getcwd(buf, PATH_MAX) != buf) e(4);
if (strcmp(buf, cwd) != 0) e(5);
if (getcwd(buf, 0) != (char *) 0) e(6);
if (errno != EINVAL) e(7);
if (getcwd(buf, PATH_MAX) != buf) e(8);
if (strcmp(buf, cwd) != 0) e(9);
if (getcwd(buf, 0) != (char *) 0) e(10);
if (errno != EINVAL) e(11);
if (getcwd(buf, PATH_MAX) != buf) e(12);
if (strcmp(buf, cwd) != 0) e(13);
if (chdir(cwd) != 0) e(14); /* getcwd might be buggy. */
/* Change the mode of foo, and check the effect. */
if (chdir("foo") != 0) e(15); /* change to foo */
if (mkdir("bar", 0777) != 0) e(16); /* make a new dir bar */
if (getcwd(cwd2, PATH_MAX) != cwd2) e(17); /* get the new cwd */
if (getcwd(buf, 3) != (char *) 0) e(18); /* size is too small */
if (errno != ERANGE) e(19);
if (getcwd(buf, PATH_MAX) != buf) e(20);
if (strcmp(buf, cwd2) != 0) e(21);
Chdir(cwd2); /* getcwd() might cd / */
System("chmod 377 ."); /* make foo unreadable */
if (getcwd(buf, PATH_MAX) != buf) e(22); /* dir not readable */
if (getcwd(buf, PATH_MAX) != buf) e(23);
if (strcmp(buf, cwd2) != 0) e(24);
if (chdir("bar") != 0) e(25); /* at .../foo/bar */
if (!superuser) {
if (getcwd(buf, PATH_MAX) != (char *) 0) e(26);
if (errno != EACCES) e(27);
}
if (superuser) {
if (getcwd(buf, PATH_MAX) != buf) e(28);
}
if (chdir(cwd2) != 0) e(29);
if (getcwd(buf, PATH_MAX) != buf) e(30);
if (strcmp(buf, cwd2) != 0) e(31);
System("chmod 677 ."); /* make foo inaccessable */
if (!superuser) {
if (getcwd(buf, PATH_MAX) != (char *) 0) e(32); /* try to get cwd */
if (errno != EACCES) e(33); /* but no access */
if (chdir("..") != -1) e(34); /* try to get back */
if (errno != EACCES) e(35); /* again no access */
if (chdir(cwd) != 0) e(36); /* get back to cwd */
/* `Chdir()' might do path optimizing, it shouldn't. */
if (chdir("foo/..") != -1) e(37); /* no op */
if (chdir("foo") != -1) e(38); /* try to cd to foo */
if (errno != EACCES) e(39); /* no have access */
if (getcwd(buf, PATH_MAX) != buf) e(40);
if (strcmp(buf, cwd) != 0) e(41);
}
if (superuser) {
if (getcwd(buf, PATH_MAX) != buf) e(42);
if (strcmp(buf, cwd2) != 0) e(43);
if (chdir("..") != 0) e(44); /* get back to cwd */
if (chdir("foo") != 0) e(45); /* get back to foo */
if (chdir(cwd) != 0) e(46); /* get back to cwd */
}
if (getcwd(buf, PATH_MAX) != buf) e(47); /* check we are */
if (strcmp(buf, cwd) != 0) e(48); /* back at cwd. */
Chdir(cwd); /* just in case... */
if (chdir("/etc/passwd") != -1) e(49); /* try to change to a file */
if (errno != ENOTDIR) e(50);
if (getcwd(buf, PATH_MAX) != buf) e(51);
if (strcmp(buf, cwd) != 0) e(52);
if (chdir("/notexist") != -1) e(53);
if (errno != ENOENT) e(54);
if (getcwd(buf, PATH_MAX) != buf) e(55);
if (strcmp(buf, cwd) != 0) e(56);
System("chmod 777 foo");
if (chdir("foo") != 0) e(57);
/* XXX - this comment was botched by 'pretty'. */
/* * Since `foo' is the cwd, it should not be removeable but * if it
* were, this code would be found here; *
*
* System ("cd .. ; rm -rf foo"); remove foo * if (chdir (".")
* != -1) e(); try go to. * if (errno != ENOENT) e();
* hould not be an entry * if (chdir ("..") != -1) e(); try
* to get back * if (errno != ENOENT) e(); should not be
* an entry * if (getcwd (buf, PATH_MAX) != (char *)0) e(); don't
* know where we are *
*
* What should errno be now ? The cwd might be gone if te superuser *
* removed the cwd. (Might even have linked it first.) But this *
* testing should be done by the test program for `rmdir()'. */
if (chdir(cwd) != 0) e(58);
}
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 */
}
/* The following code, is take from pwd written by Adri Koppes */
/* My_getcwd() helper. */
char *last_index(string, ch)
char *string;
char ch;
{
register char *retval = '\0';
while (*string != '\0') {
if (*string == ch) retval = string;
string++;
}
return(retval);
}
char *my_getcwd(buf, size)
char *buf;
int size;
{ /* should be like getcwd() */
int sd;
register int fd;
register char *n;
char name[128];
struct stat s, st, sk;
struct direct d;
if (size <= 0) return(char *) 0;
*buf = '\0';
*name = '\0';
stat(".", &s);
do {
if ((fd = open("..", O_RDONLY)) < 0) return(char *) 0;
st.st_dev = s.st_dev;
st.st_ino = s.st_ino;
stat("..", &s);
Chdir("..");
sd = sizeof(struct direct);
if (s.st_dev == st.st_dev) {
do {
if (read(fd, (char *) &d, sd) < sd) return(char *) 0;
} while (d.d_ino != st.st_ino);
} else {
do {
if (read(fd, (char *) &d, sd) < sd) return(char *) 0;
stat(d.d_name, &sk);
} while ((sk.st_dev != st.st_dev) ||
(sk.st_ino != st.st_ino));
}
close(fd);
if (strcmp(".", d.d_name) != 0) {
strcat(name, "/");
strcat(name, d.d_name);
}
} while ((s.st_ino != st.st_ino) || (s.st_dev != st.st_dev));
if (*name == '\0')
strncat(buf, "/", size);
else
while ((n = last_index(name, '/')) != NULL) {
n[NAME_MAX] = '\0';
strncat(buf, n, size - strlen(buf));
*n = '\0';
}
strncat(buf, name, size - strlen(buf));
buf[size - 1] = '\0';
Chdir(buf); /* get back there */
return buf;
}
void e(n)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_23");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

405
test/test24.c Normal file
View File

@@ -0,0 +1,405 @@
/* Test24: opendir, readdir, rewinddir, closedir Author: Jan-Mark Wams */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <time.h>
#include <stdio.h>
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void chk_dir, (DIR * dirpntr));
_PROTOTYPE(void test24a, (void));
_PROTOTYPE(void test24b, (void));
_PROTOTYPE(void test24c, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
#define OVERFLOW_DIR_NR (OPEN_MAX + 1)
#define MAX_ERROR 4
#define ITERATIONS 5
#define DIRENT0 ((struct dirent *) NULL)
#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)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 24 ");
fflush(stdout);
System("rm -rf DIR_24; mkdir DIR_24");
Chdir("DIR_24");
makelongnames();
superuser = (geteuid() == 0);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test24a();
if (m & 0002) test24b();
if (m & 0004) test24c();
}
quit();
}
void test24a()
{ /* Test normal operations. */
int fd3, fd4, fd5;
DIR *dirp;
int j, ret, fd, flags;
struct stat st1, st2;
int stat_loc;
time_t time1;
subtest = 1;
System("rm -rf ../DIR_24/*");
if ((fd = dup(0)) != 3) e(1); /* dup stdin */
close(fd); /* free the fd again */
dirp = opendir("/"); /* open "/" */
if (dirp == ((DIR *) NULL)) e(2); /* has to succseed */
if ((fd = dup(0)) <= 2) e(3); /* dup stdin */
if (fd > 3) { /* if opendir() uses fd 3 */
flags = fcntl(3, F_GETFD); /* get fd fags of 3 */
if (!(flags & FD_CLOEXEC)) e(4); /* it should be closed on */
} /* exec..() calls */
close(fd); /* free the fd again */
ret = closedir(dirp); /* close, we don't need it */
if (ret == -1) e(5); /* closedir () unsucces full */
if (ret != 0) e(6); /* should be 0 or -1 */
if ((fd = dup(0)) != 3) e(7); /* see if next fd is same */
close(fd); /* free the fd again */
System("rm -rf foo; mkdir foo");
Chdir("foo");
System("touch f1 f2 f3 f4 f5"); /* make f1 .. f5 */
System("rm f[24]"); /* creat `holes' in entrys */
Chdir("..");
if ((dirp = opendir("foo")) == ((DIR *) NULL)) e(8); /* open foo */
chk_dir(dirp); /* test if foo's ok */
for (j = 0; j < 10; j++) {
errno = j * 47 % 7; /* there should */
if (readdir(dirp) != DIRENT0) e(9); /* be nomore dir */
if (errno != j * 47 % 7) e(10); /* entrys */
}
rewinddir(dirp); /* rewind foo */
chk_dir(dirp); /* test foosok */
for (j = 0; j < 10; j++) {
errno = j * 23 % 7; /* there should */
if (readdir(dirp) != DIRENT0) e(11); /* be nomore dir */
if (errno != j * 23 % 7) e(12); /* entrys */
}
if ((fd4 = creat("foo/f4", 0666)) <= 2) e(13); /* Open a file. */
System("rm foo/f4"); /* Kill entry. */
rewinddir(dirp); /* Rewind foo. */
if ((fd3 = open("foo/f3", O_WRONLY)) <= 2) e(14); /* Open more files. */
if ((fd5 = open("foo/f5", O_WRONLY)) <= 2) e(15);
if (write(fd3, "Hello", 6) != 6) e(16);
if (write(fd4, "Hello", 6) != 6) e(17); /* write some data */
if (close(fd5) != 0) e(18);
chk_dir(dirp);
for (j = 0; j < 10; j++) {
errno = j * 101 % 7; /* there should */
if (readdir(dirp) != DIRENT0) e(19); /* be nomore dir */
if (errno != j * 101 % 7) e(20); /* entrys */
}
if (close(fd4) != 0) e(21); /* shouldn't matter */
if (close(fd3) != 0) e(22); /* when we do this */
if (closedir(dirp) != 0) e(23); /* close foo again */
Chdir("foo");
if ((dirp = opendir(".//")) == ((DIR *) NULL)) e(24); /* open foo again */
Chdir("..");
chk_dir(dirp); /* foosok? */
for (j = 0; j < 10; j++) {
errno = (j * 101) % 7; /* there should */
if (readdir(dirp) != DIRENT0) e(25); /* be nomore dir */
if (errno != (j * 101) % 7) e(26); /* entrys */
}
if (closedir(dirp) != 0) e(27); /* It should be closable */
stat("foo", &st1); /* get stat */
time(&time1);
while (time1 >= time((time_t *)0))
;
if ((dirp = opendir("foo")) == ((DIR *) NULL)) e(28); /* open, */
if (readdir(dirp) == DIRENT0) e(29); /* read and */
stat("foo", &st2); /* get new stat */
if (st1.st_atime > st2.st_atime) e(30); /* st_atime check */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
rewinddir(dirp); /* rewind childs dirp */
if (readdir(dirp) == DIRENT0) e(31); /* read should be ok */
if (closedir(dirp) != 0) e(32); /* close child'd foo */
exit(0); /* 0 stops here */
default:
if (wait(&stat_loc) == -1) e(33); /* PARENT wait()'s */
break;
}
if (closedir(dirp) != 0) e(34); /* close parent's foo */
}
void test24b()
{
/* See what happens with too many dir's open. Check if file size seems ok,
* and independency.
*/
int i, j; /* i = highest open dir count */
DIR *dirp[OVERFLOW_DIR_NR], *dp;
struct dirent *dep, *dep1, *dep2;
char name[NAME_MAX + 2]; /* buffer for file name, and count */
int dot = 0, dotdot = 0;
subtest = 2;
System("rm -rf ../DIR_24/*");
for (i = 0; i < OVERFLOW_DIR_NR; i++) {
dirp[i] = opendir("/");
if (dirp[i] == ((DIR *) NULL)) {
if (errno != EMFILE) e(1);
break;
}
}
if (i <= 4) e(2); /* sounds resanable */
if (i >= OVERFLOW_DIR_NR) e(3); /* might be to small */
for (j = 0; j < i; j++) {
if (closedir(dirp[(j + 5) % i]) != 0) e(4); /* neat! */
}
/* Now check if number of bytes in d_name can go up till NAME_MAX */
System("rm -rf foo; mkdir foo");
Chdir("foo");
name[0] = 0;
for (i = 0; i <= NAME_MAX; i++) {
if (strcat(name, "X") != name) e(5);
close(creat(name, 0666)); /* fails once on */
} /* XX..XX, 1 too long */
Chdir("..");
/* Now change i-th X to Y in name buffer record file of length i. */
if ((dp = opendir("foo")) == ((DIR *) NULL)) e(6);
while ((dep = readdir(dp)) != DIRENT0) {
if (strcmp("..", dep->d_name) == 0)
dotdot++;
else if (strcmp(".", dep->d_name) == 0)
dot++;
else
name[strlen(dep->d_name)] += 1; /* 'X' + 1 == 'Y' */
}
if (closedir(dp) != 0) e(7);
for (i = 1; i <= NAME_MAX; i++) { /* Check if every length */
if (name[i] != 'Y') e(8); /* has been seen once. */
}
/* Check upper and lower bound. */
if (name[0] != 'X') e(9);
if (name[NAME_MAX + 1] != '\0') e(10);
/* Now check if two simultaniouse open dirs do the same */
if ((dirp[1] = opendir("foo")) == ((DIR *) NULL)) e(11);
if ((dirp[2] = opendir("foo")) == ((DIR *) NULL)) e(12);
if ((dep1 = readdir(dirp[1])) == DIRENT0) e(13);
if ((dep2 = readdir(dirp[2])) == DIRENT0) e(14);
if (dep1->d_name == dep2->d_name) e(15); /* 1 & 2 Should be */
strcpy(name, dep2->d_name); /* differand buffers */
if (strcmp(dep1->d_name, name) != 0) e(16); /* But hold the same */
if ((dep1 = readdir(dirp[1])) == DIRENT0) e(17);
if ((dep1 = readdir(dirp[1])) == DIRENT0) e(18); /* lose some entries */
if ((dep1 = readdir(dirp[1])) == DIRENT0) e(19); /* Using dirp 1 has */
if (dep1->d_name == dep2->d_name) e(20); /* no effect on 2 */
if (strcmp(dep2->d_name, name) != 0) e(21);
rewinddir(dirp[1]); /* Rewinding dirp 1 */
if ((dep2 = readdir(dirp[2])) == DIRENT0) e(22); /* can't effect 2 */
if (strcmp(dep2->d_name, name) == 0) e(23); /* Must be next */
if (closedir(dirp[1]) != 0) e(24); /* Closing dirp 1 */
if ((dep2 = readdir(dirp[2])) == DIRENT0) e(25); /* can't effect 2 */
if (strcmp(dep2->d_name, name) == 0) e(26); /* Must be next */
if (closedir(dirp[2]) != 0) e(27);
}
void test24c()
{
/* Test whether wrong things go wrong right. */
DIR *dirp;
subtest = 3;
System("rm -rf ../DIR_24/*");
if (opendir("foo/bar/nono") != ((DIR *) NULL)) e(1); /* nonexistent */
if (errno != ENOENT) e(2);
System("mkdir foo; chmod 677 foo"); /* foo inaccesable */
if (opendir("foo/bar/nono") != ((DIR *) NULL)) e(3);
if (superuser) {
if (errno != ENOENT) e(4); /* su has access */
System("chmod 377 foo");
if ((dirp = opendir("foo")) == ((DIR *) NULL)) e(5);
if (closedir(dirp) != 0) e(6);
}
if (!superuser) {
if (errno != EACCES) e(7); /* we don't ;-) */
System("chmod 377 foo");
if (opendir("foo") != ((DIR *) NULL)) e(8);
}
System("chmod 777 foo");
if (mkdir(MaxName, 0777) != 0) e(9); /* make longdir */
if ((dirp = opendir(MaxName)) == ((DIR *) NULL)) e(10); /* open it */
if (closedir(dirp) != 0) e(11); /* close it */
if (rmdir(MaxName) != 0) e(12); /* then remove it */
if ((dirp = opendir(MaxPath)) == ((DIR *) NULL)) e(13); /* open '.' */
if (closedir(dirp) != 0) e(14); /* close it */
#if 0 /* XXX - anything could happen with the bad pointer */
if (closedir(dirp) != -1) e(15); /* close it again */
if (closedir(dirp) != -1) e(16); /* and again */
#endif /* 0 */
if (opendir(ToLongName) != ((DIR *) NULL)) e(17); /* is too long */
#ifdef _POSIX_NO_TRUNC
# if _POSIX_NO_TRUNC - 0 != -1
if (errno != ENAMETOOLONG) e(18);
# else
if (errno != ENOENT) e(19);
# endif
#else
# include "error, this case requires dynamic checks and is not handled"
#endif
if (opendir(ToLongPath) != ((DIR *) NULL)) e(20); /* path is too long */
if (errno != ENAMETOOLONG) e(21);
System("touch foo/abc"); /* make a file */
if (opendir("foo/abc") != ((DIR *) NULL)) e(22); /* not a dir */
if (errno != ENOTDIR) e(23);
}
void chk_dir(dirp) /* dir should contain */
DIR *dirp; /* (`f1', `f3', `f5', `.', `..') */
{ /* no more, no less */
int f1 = 0, f2 = 0, f3 = 0, f4 = 0, f5 = 0, /* counters for all */
other = 0, dot = 0, dotdot = 0; /* possible entrys */
int i;
struct dirent *dep;
char *fname;
int oldsubtest = subtest;
subtest = 4;
for (i = 0; i < 5; i++) { /* 3 files and `.' and `..' == 5 entrys */
dep = readdir(dirp);
if (dep == DIRENT0) { /* not einough */
if (dep == DIRENT0) e(1);
break;
}
fname = dep->d_name;
if (strcmp(fname, ".") == 0)
dot++;
else if (strcmp(fname, "..") == 0)
dotdot++;
else if (strcmp(fname, "f1") == 0)
f1++;
else if (strcmp(fname, "f2") == 0)
f2++;
else if (strcmp(fname, "f3") == 0)
f3++;
else if (strcmp(fname, "f4") == 0)
f4++;
else if (strcmp(fname, "f5") == 0)
f5++;
else
other++;
} /* do next dir entry */
if (dot != 1) e(2); /* Check the entrys */
if (dotdot != 1) e(3);
if (f1 != 1) e(4);
if (f3 != 1) e(5);
if (f5 != 1) e(6);
if (f2 != 0) e(7);
if (f4 != 0) e(8);
if (other != 0) e(9);
subtest = oldsubtest;
}
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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_24");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

733
test/test25.c Normal file
View File

@@ -0,0 +1,733 @@
/* test25: open (), close () (p) Jan-Mark Wams. email: jms@cs.vu.nl */
/* Not tested: O_NONBLOCK on special files, supporting it.
** On a read-only file system, some error reports are to be expected.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 2
#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 Creat(f) if (close(creat(f,0777))!=0) printf("Can't creat %s\n",f)
#define Report(s,n) printf("Subtest %d" s,subtest,(n))
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test25a, (void));
_PROTOTYPE(void test25b, (void));
_PROTOTYPE(void test25c, (void));
_PROTOTYPE(void test25d, (void));
_PROTOTYPE(void test25e, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (geteuid() == 0 || getuid() == 0) {
printf("Test 25 cannot run as root; test aborted\n");
exit(1);
}
if (argc == 2) m = atoi(argv[1]);
printf("Test 25 ");
fflush(stdout);
System("rm -rf DIR_25; mkdir DIR_25");
Chdir("DIR_25");
makelongnames();
superuser = (geteuid() == 0);
/* Close all files, the parent might have opened. */
for (i = 3; i < 100; i++) close(i);
for (i = 0; i < ITERATIONS; i++) {
if (m & 001) test25a();
if (m & 002) test25b();
if (m & 004) test25c();
if (m & 010) test25d();
if (m & 020) test25e();
}
quit();
}
void test25a()
{ /* Test fcntl flags. */
subtest = 1;
#define EXCLUDE(a,b) (((a)^(b)) == ((a)|(b)))
#define ADDIT (O_APPEND | O_CREAT | O_EXCL | O_NONBLOCK | O_TRUNC)
/* If this compiles all flags are defined but they have to be or-able. */
if (!(EXCLUDE(O_NONBLOCK, O_TRUNC))) e(1);
if (!(EXCLUDE(O_EXCL, O_NONBLOCK | O_TRUNC))) e(2);
if (!(EXCLUDE(O_CREAT, O_EXCL | O_NONBLOCK | O_TRUNC))) e(3);
if (!(EXCLUDE(O_APPEND, O_CREAT | O_EXCL | O_NONBLOCK | O_TRUNC))) e(4);
if (!(EXCLUDE(O_RDONLY, ADDIT))) e(5);
if (!(EXCLUDE(O_WRONLY, ADDIT))) e(6);
if (!(EXCLUDE(O_RDWR, ADDIT))) e(7);
}
void test25b()
{ /* Test normal operation. */
#define BUF_SIZE 1024
int fd1, fd2, fd3, fd4, fd5;
char buf[BUF_SIZE];
struct stat st1, st2, st3;
time_t time1, time2;
int stat_loc;
subtest = 2;
System("rm -rf ../DIR_25/*");
System("echo Hello > he"); /* make test files */
System("echo Hello > ha"); /* size 6 bytes */
System("echo Hello > hi");
System("echo Hello > ho");
/* Check path resolution. Check if lowest fds are returned */
if ((fd1 = open("he", O_RDONLY)) != 3) e(1);
if (read(fd1, buf, BUF_SIZE) != 6) e(2);
if ((fd2 = open("./ha", O_RDONLY)) != 4) e(3);
if ((fd3 = open("../DIR_25/he", O_RDWR)) != 5) e(4);
if ((fd4 = open("ho", O_WRONLY)) != 6) e(5);
if (close(fd4) != 0) e(6);
if (close(fd1) != 0) e(7);
if ((fd1 = open("./././ho", O_RDWR)) != 3) e(8);
if ((fd4 = open("../DIR_25/he", O_RDONLY)) != 6) e(9);
if (close(fd2) != 0) e(10);
if (close(fd3) != 0) e(11);
if ((fd2 = open("ha", O_RDONLY)) != 4) e(12);
if ((fd3 = open("/etc/passwd", O_RDONLY)) != 5) e(13);
if (close(fd4) != 0) e(14); /* close all */
if (close(fd1) != 0) e(15);
if (close(fd3) != 0) e(16);
/* Check if processes share fd2, and if they have independent new fds */
System("rm -rf /tmp/sema.25");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
if ((fd1 = open("he", O_WRONLY)) != 3) e(17);
if ((fd3 = open("../././DIR_25/ha", O_WRONLY)) != 5) e(18);
if ((fd4 = open("../DIR_25/hi", O_WRONLY)) != 6) e(19);
if ((fd5 = open("ho", O_WRONLY)) != 7) e(20);
system("while test ! -f /tmp/sema.25; do sleep 1; done"); /* parent */
if (read(fd2, buf, BUF_SIZE) != 3) e(21); /* gets Hel */
if (strncmp(buf, "lo\n", 3) != 0) e(22); /* we get lo */
if (close(fd1) != 0) e(23);
if (close(fd2) != 0) e(24);
if (close(fd3) != 0) e(25);
if (close(fd4) != 0) e(26);
if (close(fd5) != 0) e(27);
exit(0);
default:
if ((fd1 = open("ha", O_RDONLY)) != 3) e(28);
if ((fd3 = open("./he", O_RDONLY)) != 5) e(29);
if ((fd4 = open("../DIR_25/hi", O_RDWR)) != 6) e(30);
if ((fd5 = open("ho", O_WRONLY)) != 7) e(31);
if (close(fd1) != 0) e(32);
if (read(fd2, buf, 3) != 3) e(33); /* get Hel */
Creat("/tmp/sema.25");
if (strncmp(buf, "Hel", 3) != 0) e(34);
if (close(fd2) != 0) e(35);
if (close(fd3) != 0) e(36);
if (close(fd4) != 0) e(37);
if (close(fd5) != 0) e(38);
if (wait(&stat_loc) == -1) e(39);
if (stat_loc != 0) e(40);
}
System("rm -f /tmp/sema.25");
/* Check if the file status information is updated correctly */
Stat("hi", &st1); /* get info */
Stat("ha", &st2); /* of files */
time(&time1);
while (time1 >= time((time_t *)0))
; /* wait a sec */
if ((fd1 = open("hi", O_RDONLY)) != 3) e(41); /* open files */
if ((fd2 = open("ha", O_WRONLY)) != 4) e(42);
if (read(fd1, buf, 1) != 1) e(43); /* read one */
if (close(fd1) != 0) e(44); /* close one */
Stat("hi", &st3); /* get info */
if (st1.st_uid != st3.st_uid) e(45);
if (st1.st_gid != st3.st_gid) e(46); /* should be same */
if (st1.st_mode != st3.st_mode) e(47);
if (st1.st_size != st3.st_size) e(48);
if (st1.st_nlink != st3.st_nlink) e(49);
if (st1.st_mtime != st3.st_mtime) e(50);
if (st1.st_ctime != st3.st_ctime) e(51);
#ifndef V1_FILESYSTEM
if (st1.st_atime >= st3.st_atime) e(52); /* except for atime. */
#endif
if (write(fd2, "Howdy\n", 6) != 6) e(53); /* Update c & mtime. */
if ((fd1 = open("ha", O_RDWR)) != 3) e(54);
if (read(fd1, buf, 6) != 6) e(55); /* Update atime. */
if (strncmp(buf, "Howdy\n", 6) != 0) e(56);
if (close(fd1) != 0) e(57);
Stat("ha", &st3);
if (st2.st_uid != st3.st_uid) e(58);
if (st2.st_gid != st3.st_gid) e(59); /* should be same */
if (st2.st_mode != st3.st_mode) e(60);
if (st2.st_nlink != st3.st_nlink) e(61);
if (st2.st_ctime >= st3.st_ctime) e(62);
#ifndef V1_FILESYSTEM
if (st2.st_atime >= st3.st_atime) e(63);
#endif
if (st2.st_mtime >= st3.st_mtime) e(64);
if (st2.st_size != st3.st_size) e(65);
if (close(fd2) != 0) e(66);
/* Let's see if RDONLY files are read only. */
if ((fd1 = open("hi", O_RDONLY)) != 3) e(67);
if (write(fd1, " again", 7) != -1) e(68); /* we can't write */
if (errno != EBADF) e(69); /* a read only fd */
if (read(fd1, buf, 7) != 6) e(70); /* but we can read */
if (close(fd1) != 0) e(71);
/* Let's see if WRONLY files are write only. */
if ((fd1 = open("hi", O_WRONLY)) != 3) e(72);
if (read(fd1, buf, 7) != -1) e(73); /* we can't read */
if (errno != EBADF) e(74); /* a write only fd */
if (write(fd1, "hELLO", 6) != 6) e(75); /* but we can write */
if (close(fd1) != 0) e(76);
/* Let's see if files are closable only once. */
if (close(fd1) != -1) e(77);
if (errno != EBADF) e(78);
/* Let's see how calling close() with bad fds is handled. */
if (close(10) != -1) e(79);
if (errno != EBADF) e(80);
if (close(111) != -1) e(81);
if (errno != EBADF) e(82);
if (close(-432) != -1) e(83);
if (errno != EBADF) e(84);
/* Let's see if RDWR files are read & write able. */
if ((fd1 = open("hi", O_RDWR)) != 3) e(85);
if (read(fd1, buf, 6) != 6) e(86); /* we can read */
if (strncmp(buf, "hELLO", 6) != 0) e(87); /* and we can write */
if (write(fd1, "Hello", 6) != 6) e(88); /* a read write fd */
if (close(fd1) != 0) e(89);
/* Check if APPENDed files are realy appended */
if ((fd1 = open("hi", O_RDWR | O_APPEND)) != 3) e(90); /* open hi */
/* An open should set the file offset to 0. */
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 0) e(91);
/* Writing 0 bytes should not have an effect. */
if (write(fd1, "", 0) != 0) e(92);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 0) e(93); /* the end? */
/* A seek befor a wirte should not matter with O_APPEND. */
Stat("hi", &st1);
if (lseek(fd1, (off_t) - 3, SEEK_END) != st1.st_size - 3) e(94);
/* By writing 1 byte, we force the offset to the end of the file */
if (write(fd1, "1", 1) != 1) e(95);
Stat("hi", &st1);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(96);
if (write(fd1, "2", 1) != 1) e(97);
Stat("hi", &st1);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(98);
if (write(fd1, "3", 1) != 1) e(99);
Stat("hi", &st1);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(100);
if (lseek(fd1, (off_t) - 2, SEEK_CUR) <= 0) e(101);
if (write(fd1, "4", 1) != 1) e(102);
/* Since the mode was O_APPEND, the offset should be reset to EOF */
Stat("hi", &st1);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(103);
if (lseek(fd1, (off_t) - 4, SEEK_CUR) != st1.st_size - 4) e(104);
if (read(fd1, buf, BUF_SIZE) != 4) e(105);
if (strncmp(buf, "1234", 4) != 0) e(106);
if (close(fd1) != 0) e(107);
/* Check the effect of O_CREAT */
Stat("ho", &st1);
fd1 = open("ho", O_RDWR | O_CREAT, 0000);
if (fd1 != 3) e(108);
Stat("ho", &st2);
if (memcmp(&st1, &st2, sizeof(struct stat)) != 0) e(109);
if (read(fd1, buf, 6) != 6) e(110);
if (strncmp(buf, "Hello\n", 6) != 0) e(111);
if (write(fd1, "@", 1) != 1) e(112);
if (close(fd1) != 0) e(113);
(void) umask(0000);
fd1 = open("ho", O_RDWR | O_CREAT | O_EXCL, 0777);
if (fd1 != -1) e(114); /* ho exists */
System("rm -rf new");
time(&time1);
while (time1 >= time((time_t *)0))
;
fd1 = open("new", O_RDWR | O_CREAT, 0716);
if (fd1 != 3) e(115); /* new file */
Stat("new", &st1);
time(&time2);
while (time2 >= time((time_t *)0))
;
time(&time2);
if (st1.st_uid != geteuid()) e(116); /* try this as superuser. */
if (st1.st_gid != getegid()) e(117);
if ((st1.st_mode & 0777) != 0716) e(118);
if (st1.st_nlink != 1) e(119);
if (st1.st_mtime <= time1) e(120);
if (st1.st_mtime >= time2) e(121);
#ifndef V1_FILESYSTEM
if (st1.st_atime != st1.st_mtime) e(122);
#endif
if (st1.st_ctime != st1.st_mtime) e(123);
if (st1.st_size != 0) e(124);
if (write(fd1, "I'm new in town", 16) != 16) e(125);
if (lseek(fd1, (off_t) - 5, SEEK_CUR) != 11) e(126);
if (read(fd1, buf, 5) != 5) e(127);
if (strncmp(buf, "town", 5) != 0) e(128);
if (close(fd1) != 0) e(129);
/* Let's test the O_TRUNC flag on this new file. */
time(&time1);
while (time1 >= time((time_t *)0));
if ((fd1 = open("new", O_RDWR | O_TRUNC)) != 3) e(130);
Stat("new", &st1);
time(&time2);
while (time2 >= time((time_t *)0));
time(&time2);
if ((st1.st_mode & 0777) != 0716) e(131);
if (st1.st_size != (size_t) 0) e(132); /* TRUNCed ? */
if (st1.st_mtime <= time1) e(133);
if (st1.st_mtime >= time2) e(134);
if (st1.st_ctime != st1.st_mtime) e(135);
if (close(fd1) != 0) e(136);
/* Test if file permission bits and the file ownership are unchanged. */
/* So we will see if `O_CREAT' has no effect if the file exists. */
if (superuser) {
System("echo > bar; chmod 077 bar"); /* Make bar 077 */
System("chown daemon bar");
System("chgrp daemon bar"); /* Daemon's bar */
fd1 = open("bar", O_RDWR | O_CREAT | O_TRUNC, 0777); /* knock knock */
if (fd1 == -1) e(137);
if (write(fd1, "foo", 3) != 3) e(138); /* rewrite bar */
if (close(fd1) != 0) e(139);
Stat("bar", &st1);
if (st1.st_uid != 1) e(140); /* bar is still */
if (st1.st_gid != 1) e(141); /* owned by daemon */
if ((st1.st_mode & 0777) != 077) e(142); /* mode still is 077 */
if (st1.st_size != (size_t) 3) e(143); /* 3 bytes long */
/* We do the whole thing again, but with O_WRONLY */
fd1 = open("bar", O_WRONLY | O_CREAT | O_TRUNC, 0777);
if (fd1 == -1) e(144);
if (write(fd1, "foobar", 6) != 6) e(145); /* rewrite bar */
if (close(fd1) != 0) e(146);
Stat("bar", &st1);
if (st1.st_uid != 1) e(147); /* bar is still */
if (st1.st_gid != 1) e(148); /* owned by daemon */
if ((st1.st_mode & 0777) != 077) e(149); /* mode still is 077 */
if (st1.st_size != (size_t) 6) e(150); /* 6 bytes long */
}
}
void test25c()
{ /* Test normal operation Part two. */
int fd1, fd2;
char buf[BUF_SIZE];
struct stat st;
int stat_loc;
static int iteration=0;
subtest = 3;
iteration++;
System("rm -rf ../DIR_25/*");
/* Fifo file test here. */
if (mkfifo("fifo", 0777) != 0) e(1);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20); /* Give child 20 seconds to live. */
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(2);
if (read(fd1, buf, BUF_SIZE) != 23) e(3);
if (strncmp(buf, "1 2 3 testing testing\n", 23) != 0) e(4);
if (close(fd1) != 0) e(5);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(6);
if (write(fd1, "1 2 3 testing testing\n", 23) != 23) e(7);
if (close(fd1) != 0) e(8);
if (wait(&stat_loc) == -1) e(9);
if (stat_loc != 0) e(10); /* The alarm went off? */
}
/* Try opening for writing with O_NONBLOCK. */
fd1 = open("fifo", O_WRONLY | O_NONBLOCK);
if (fd1 != -1) e(11);
if (errno != ENXIO) e(12);
close(fd1);
/* Try opening for writing with O_NONBLOCK and O_CREAT. */
fd1 = open("fifo", O_WRONLY | O_CREAT | O_NONBLOCK, 0777);
if (fd1 != -1) e(13);
if (errno != ENXIO) e(14);
close(fd1);
/* Both the NONBLOCK and the EXCLusive give raise to error. */
fd1 = open("fifo", O_WRONLY | O_CREAT | O_EXCL | O_NONBLOCK, 0777);
if (fd1 != -1) e(15);
if (errno != EEXIST && errno != ENXIO) e(16);
close(fd1); /* Just in case. */
/* Try opening for reading with O_NONBLOCK. */
fd1 = open("fifo", O_RDONLY | O_NONBLOCK);
if (fd1 != 3) e(17);
if (close(fd1) != 0) e(18);
/* Nopt runs out of memory. ;-< We just cut out some valid code */
/* FIFO's should always append. (They have no file position.) */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20); /* Give child 20 seconds to live. */
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(19);
if ((fd2 = open("fifo", O_WRONLY)) != 4) e(20);
if (write(fd1, "I did see Elvis.\n", 18) != 18) e(21);
if (write(fd2, "I DID.\n", 8) != 8) e(22);
if (close(fd2) != 0) e(23);
if (close(fd1) != 0) e(24);
exit(0);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(25);
if (read(fd1, buf, 18) != 18) e(26);
if (strncmp(buf, "I did see Elvis.\n", 18) != 0) e(27);
if (read(fd1, buf, BUF_SIZE) != 8) e(28);
if (strncmp(buf, "I DID.\n", 8) != 0) e(29);
if (close(fd1) != 0) e(30);
if (wait(&stat_loc) == -1) e(31);
if (stat_loc != 0) e(32); /* The alarm went off? */
}
/* O_TRUNC should have no effect on FIFO files. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20); /* Give child 20 seconds to live. */
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(33);
if (write(fd1, "I did see Elvis.\n", 18) != 18) e(34);
if ((fd2 = open("fifo", O_WRONLY | O_TRUNC)) != 4) e(35);
if (write(fd2, "I DID.\n", 8) != 8) e(36);
if (close(fd2) != 0) e(37);
if (close(fd1) != 0) e(38);
exit(0);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(39);
if (read(fd1, buf, 18) != 18) e(40);
if (strncmp(buf, "I did see Elvis.\n", 18) != 0) e(41);
if (read(fd1, buf, BUF_SIZE) != 8) e(42);
if (strncmp(buf, "I DID.\n", 8) != 0) e(43);
if (close(fd1) != 0) e(44);
if (wait(&stat_loc) == -1) e(45);
if (stat_loc != 0) e(46); /* The alarm went off? */
}
/* Closing the last fd should flush all data to the bitbucket. */
System("rm -rf /tmp/sema.25");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20); /* Give child 20 seconds to live. */
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(47);
if (write(fd1, "I did see Elvis.\n", 18) != 18) e(48);
Creat("/tmp/sema.25");
sleep(2); /* give parent a chance to open */
/* this was sleep(1), but that's too short: child also sleeps(1) */
if (close(fd1) != 0) e(49);
exit(0);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(50);
/* Make `sure' write has closed. */
while (stat("/tmp/sema.25", &st) != 0) sleep(1);
if (close(fd1) != 0) e(51);
if ((fd1 = open("fifo", O_RDONLY | O_NONBLOCK)) != 3) e(52);
if (read(fd1, buf, BUF_SIZE) != 18) e(53);
if (close(fd1) != 0) e(54);
if (wait(&stat_loc) == -1) e(55);
if (stat_loc != 0) e(56); /* The alarm went off? */
}
/* Let's try one too many. */
System("rm -rf /tmp/sema.25");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20); /* Give child 20 seconds to live. */
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(57);
if (write(fd1, "I did see Elvis.\n", 18) != 18) e(58);
/* Keep open till second reader is opened. */
while (stat("/tmp/sema.25", &st) != 0) sleep(1);
if (close(fd1) != 0) e(59);
exit(0);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(60);
if (read(fd1, buf, 2) != 2) e(61);
if (strncmp(buf, "I ", 2) != 0) e(62);
if (close(fd1) != 0) e(63);
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(64);
/* Signal second reader is open. */
Creat("/tmp/sema.25");
if (read(fd1, buf, 4) != 4) e(65);
if (strncmp(buf, "did ", 4) != 0) e(66);
if ((fd2 = open("fifo", O_RDONLY)) != 4) e(67);
if (read(fd2, buf, BUF_SIZE) != 12) e(68);
if (strncmp(buf, "see Elvis.\n", 12) != 0) e(69);
if (close(fd2) != 0) e(70);
if (close(fd1) != 0) e(71);
if (wait(&stat_loc) == -1) e(72);
if (stat_loc != 0) e(73); /* The alarm went off? */
}
System("rm -rf fifo /tmp/sema.25");
/* O_TRUNC should have no effect on directroys. */
System("mkdir dir; touch dir/f1 dir/f2 dir/f3");
if ((fd1 = open("dir", O_WRONLY | O_TRUNC)) != -1) e(74);
if (errno != EISDIR) e(75);
close(fd1);
/* Opening a directory for reading should be possible. */
if ((fd1 = open("dir", O_RDONLY)) != 3) e(76);
if (close(fd1) != 0) e(77);
if (unlink("dir/f1") != 0) e(78); /* Should still be there. */
if (unlink("dir/f2") != 0) e(79);
if (unlink("dir/f3") != 0) e(80);
if (rmdir("dir") != 0) e(81);
if (!superuser) {
/* Test if O_CREAT is not usable to open files with the wrong mode */
(void) umask(0200); /* nono has no */
System("touch nono"); /* write bit */
(void) umask(0000);
fd1 = open("nono", O_RDWR | O_CREAT, 0777); /* try to open */
if (fd1 != -1) e(82);
if (errno != EACCES) e(83); /* but no access */
}
}
void test25d()
{
int fd;
subtest = 4;
System("rm -rf ../DIR_25/*");
/* Test maximal file name length. */
if ((fd = open(MaxName, O_RDWR | O_CREAT, 0777)) != 3) e(1);
if (close(fd) != 0) e(2);
MaxPath[strlen(MaxPath) - 2] = '/';
MaxPath[strlen(MaxPath) - 1] = 'a'; /* make ././.../a */
if ((fd = open(MaxPath, O_RDWR | O_CREAT, 0777)) != 3) e(3);
if (close(fd) != 0) e(4);
MaxPath[strlen(MaxPath) - 1] = '/'; /* make ././.../a */
}
void test25e()
{
int fd;
char *noread = "noread"; /* Name for unreadable file. */
char *nowrite = "nowrite"; /* Same for unwritable. */
int stat_loc;
subtest = 5;
System("rm -rf ../DIR_25/*");
mkdir("bar", 0777); /* make bar */
/* Check if no access on part of path generates the correct error. */
System("chmod 677 bar"); /* rw-rwxrwx */
if (open("bar/nono", O_RDWR | O_CREAT, 0666) != -1) e(1);
if (errno != EACCES) e(2);
/* Ditto for no write permission. */
System("chmod 577 bar"); /* r-xrwxrwx */
if (open("bar/nono", O_RDWR | O_CREAT, 0666) != -1) e(3);
if (errno != EACCES) e(4);
/* Clean up bar. */
System("rm -rf bar");
/* Improper flags set on existing file. */
System("touch noread; chmod 377 noread"); /* noread */
if (open(noread, O_RDONLY) != -1) e(5);
if (open(noread, O_RDWR) != -1) e(6);
if (open(noread, O_RDWR | O_CREAT, 0777) != -1) e(7);
if (open(noread, O_RDWR | O_CREAT | O_TRUNC, 0777) != -1) e(8);
if ((fd = open(noread, O_WRONLY)) != 3) e(9);
if (close(fd) != 0) e(10);
System("touch nowrite; chmod 577 nowrite"); /* nowrite */
if (open(nowrite, O_WRONLY) != -1) e(11);
if (open(nowrite, O_RDWR) != -1) e(12);
if (open(nowrite, O_RDWR | O_CREAT, 0777) != -1) e(13);
if (open(nowrite, O_RDWR | O_CREAT | O_TRUNC, 0777) != -1) e(14);
if ((fd = open(nowrite, O_RDONLY)) != 3) e(15);
if (close(fd) != 0) e(16);
if (superuser) {
/* If we can make a file ownd by some one else, test access again. */
System("chmod 733 noread");
System("chown bin noread");
System("chgrp system noread");
System("chmod 755 nowrite");
System("chown bin nowrite");
System("chgrp system nowrite");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
setuid(1);
setgid(1); /* become daemon */
if (open(noread, O_RDONLY) != -1) e(17);
if (open(noread, O_RDWR) != -1) e(18);
if (open(noread, O_RDWR | O_CREAT, 0777) != -1) e(19);
fd = open(noread, O_RDWR | O_CREAT | O_TRUNC, 0777);
if (fd != -1) e(20);
if ((fd = open(noread, O_WRONLY)) != 3) e(21);
if (close(fd) != 0) e(22);
if (open(nowrite, O_WRONLY) != -1) e(23);
if (open(nowrite, O_RDWR) != -1) e(24);
if (open(nowrite, O_RDWR | O_CREAT, 0777) != -1) e(25);
fd = open(nowrite, O_RDWR | O_CREAT | O_TRUNC, 0777);
if (fd != -1) e(26);
if ((fd = open(nowrite, O_RDONLY)) != 3) e(27);
if (close(fd) != 0) e(28);
exit(0);
default:
if (wait(&stat_loc) == -1) e(29);
}
}
/* Clean up the noread and nowrite files. */
System("rm -rf noread nowrite");
/* Test the O_EXCL flag. */
System("echo > exists");
if (open("exists", O_RDWR | O_CREAT | O_EXCL, 0777) != -1) e(30);
if (errno != EEXIST) e(31);
if (open("exists", O_RDONLY | O_CREAT | O_EXCL, 0777) != -1) e(32);
if (errno != EEXIST) e(33);
if (open("exists", O_WRONLY | O_CREAT | O_EXCL, 0777) != -1) e(34);
if (errno != EEXIST) e(35);
fd = open("exists", O_RDWR | O_CREAT | O_EXCL | O_TRUNC, 0777);
if (fd != -1) e(36);
if (errno != EEXIST) e(37);
fd = open("exists", O_RDONLY | O_CREAT | O_EXCL | O_TRUNC, 0777);
if (fd != -1) e(38);
if (errno != EEXIST) e(39);
fd = open("exists", O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0777);
if (fd != -1) e(40);
if (errno != EEXIST) e(41);
/* Test ToLongName and ToLongPath */
if ((fd = open(ToLongName, O_RDWR | O_CREAT, 0777)) != 3) e(45);
if (close(fd) != 0) e(46);
ToLongPath[PATH_MAX - 2] = '/';
ToLongPath[PATH_MAX - 1] = 'a';
if ((fd = open(ToLongPath, O_RDWR | O_CREAT, 0777)) != -1) e(47);
if (errno != ENAMETOOLONG) e(48);
if (close(fd) != -1) e(49);
ToLongPath[PATH_MAX - 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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_25");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

357
test/test26.c Normal file
View File

@@ -0,0 +1,357 @@
/* test26: 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/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
#define MAX_ERROR 4
#define ITERATIONS 4
#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 test26a, (void));
_PROTOTYPE(void test26b, (void));
_PROTOTYPE(void test26c, (void));
_PROTOTYPE(int stateq, (struct stat *stp1, struct stat *stp2));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int __n));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 26 ");
fflush(stdout);
System("rm -rf DIR_26; mkdir DIR_26");
Chdir("DIR_26");
superuser = (getuid() == 0);
makelongnames();
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test26a();
if (m & 0002) test26b();
if (m & 0004) test26c();
}
quit();
}
void test26a()
{ /* Test normal operation. */
struct stat st1, st2, st3;
time_t time1;
subtest = 1;
/* Clean up any residu. */
System("rm -rf ../DIR_26/*");
System("touch foo"); /* make source file */
Stat("foo", &st1); /* get info of foo */
Stat(".", &st2); /* and the cwd */
time(&time1);
while (time1 >= time((time_t *)0))
; /* wait a sec */
if (link("foo", "bar") != 0) e(1); /* link foo to bar */
Stat("foo", &st3); /* get new status */
if (st1.st_nlink + 1 != st3.st_nlink) e(2); /* link count foo up 1 */
#ifndef V1_FILESYSTEM
if (st1.st_ctime >= st3.st_ctime) e(3); /* check stattime changed */
#endif
Stat(".", &st1); /* get parend dir info */
if (st2.st_ctime >= st1.st_ctime) e(4); /* ctime and mtime */
if (st2.st_mtime >= st1.st_mtime) e(5); /* should be updated */
Stat("bar", &st2); /* get info of bar */
if (st2.st_nlink != st3.st_nlink) e(6); /* link count foo == bar */
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 */
if (st2.st_uid != st3.st_uid) e(9); /* check uid same */
if (st2.st_gid != st3.st_gid) e(10); /* check gid same */
if (st2.st_size != st3.st_size) e(11); /* check size */
if (st2.st_ctime != st3.st_ctime) e(12); /* check ctime */
if (st2.st_atime != st3.st_atime) e(13); /* check atime */
if (st2.st_mtime != st3.st_mtime) e(14); /* check mtime */
Stat("foo", &st1); /* get fooinfo */
Stat(".", &st2); /* get dir info */
time(&time1);
while (time1 >= time((time_t *)0))
; /* wait a sec */
if (unlink("bar") != 0) e(15);/* rm bar */
if (stat("bar", &st2) != -1) e(16); /* it's gone */
Stat("foo", &st3); /* get foo again */
if (st1.st_nlink != st3.st_nlink + 1) e(17); /* link count back to normal */
#ifndef V1_FILESYSTEM
if (st1.st_ctime >= st3.st_ctime) e(18); /* check ctime */
#endif
Stat(".", &st3); /* get parend dir info */
if (st2.st_ctime >= st3.st_ctime) e(19); /* ctime and mtime */
if (st2.st_mtime >= st3.st_mtime) e(20); /* should be updated */
}
void test26b()
{
register int nlink;
char *bar = "bar.xxxxx"; /* xxxxx will hold a number up to 99999 */
struct stat st, st2;
subtest = 2;
/* Clean up any residu. */
System("rm -rf ../DIR_26/*");
/* Test what happens if we make LINK_MAX number of links. */
System("touch foo");
if (LINK_MAX > 127) {
printf("[skip] "); /* takes too many resources */
} else {
if (LINK_MAX >= 99999) e(1); /* check "xxxxx" are enough */
for (nlink = 2; nlink <= LINK_MAX; nlink++) {
bar[4] = (char) ((nlink / 10000) % 10) + '0';
bar[5] = (char) ((nlink / 1000) % 10) + '0';
bar[6] = (char) ((nlink / 100) % 10) + '0';
bar[7] = (char) ((nlink / 10) % 10) + '0';
bar[8] = (char) (nlink % 10) + '0';
if (link("foo", bar) != 0) e(2);
Stat(bar, &st);
if (st.st_nlink != nlink) e(3);
Stat("foo", &st);
if (st.st_nlink != nlink) e(4);
}
/* Check if we have LINK_MAX links that are all the same. */
Stat("foo", &st);
if (st.st_nlink != LINK_MAX) e(5);
for (nlink = 2; nlink <= LINK_MAX; nlink++) {
bar[4] = (char) ((nlink / 10000) % 10) + '0';
bar[5] = (char) ((nlink / 1000) % 10) + '0';
bar[6] = (char) ((nlink / 100) % 10) + '0';
bar[7] = (char) ((nlink / 10) % 10) + '0';
bar[8] = (char) (nlink % 10) + '0';
Stat(bar, &st2);
if (!stateq(&st, &st2)) e(6);
}
/* Test no more links are possible. */
if (link("foo", "nono") != -1) e(7);
if (stat("nono", &st) != -1) e(8);
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--) {
bar[4] = (char) ((nlink / 100) % 10) + '0';
bar[5] = (char) ((nlink / 10) % 10) + '0';
bar[6] = (char) (nlink % 10) + '0';
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()
{
subtest = 3;
/* Clean up any residu. */
System("rm -rf ../DIR_26/*");
/* Check some simple things. */
if (link("bar/nono", "nono") != -1) e(1); /* nonexistent */
if (errno != ENOENT) e(2);
Chdir("..");
System("touch DIR_26/foo");
System("chmod 677 DIR_26"); /* make inaccesable */
if (!superuser) {
if (unlink("DIR_26/foo") != -1) e(3);
if (errno != EACCES) e(4);
}
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 */
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 */
}
void e(n)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
chdir("..");
system("rm -rf DIR_26");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

351
test/test27.c Normal file
View File

@@ -0,0 +1,351 @@
/* test27: stat() fstat() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <limits.h>
#include <time.h>
#include <stdio.h>
#define MODE_MASK (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID)
#define MAX_ERROR 4
#define ITERATIONS 2
#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)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX];
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1];
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test27a, (void));
_PROTOTYPE(void test27b, (void));
_PROTOTYPE(void test27c, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int __n));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 27 ");
fflush(stdout);
System("rm -rf DIR_27; mkdir DIR_27");
Chdir("DIR_27");
superuser = (getuid() == 0);
makelongnames();
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test27a();
if (m & 0002) test27b();
if (m & 0004) test27c();
}
quit();
}
void test27a()
{ /* Test Normal operation. */
struct stat st1, st2;
time_t time1, time2;
int fd, pfd[2];
subtest = 1;
time(&time1); /* get time before */
while (time1 >= time((time_t *)0))
; /* Wait for time to change. */
System("echo 7bytes > foo; chmod 4750 foo");
if (stat("foo", &st1) != 0) e(1); /* get foo's info */
time(&time2);
while (time2 >= time((time_t *)0))
; /* Wait for next second. */
time(&time2); /* get time after */
if ((st1.st_mode & MODE_MASK) != 04750) e(2);
if (st1.st_nlink != 1) e(3); /* check stat */
if (st1.st_uid != geteuid()) e(4);
#if defined(NGROUPS_MAX) && NGROUPS_MAX == 0
if (st1.st_gid != getegid()) e(5);
#endif /* defined(NGROUPS_MAX) && NGROUPS_MAX == 0 */
if (st1.st_size != (size_t) 7) e(6);
if (st1.st_atime <= time1) e(7);
if (st1.st_atime >= time2) e(8);
if (st1.st_ctime <= time1) e(9);
if (st1.st_ctime >= time2) e(10);
if (st1.st_mtime <= time1) e(11);
if (st1.st_mtime >= time2) e(12);
/* Compair stat and fstat. */
System("echo 7bytes > bar");
fd = open("bar", O_RDWR | O_APPEND); /* the bar is open! */
if (fd != 3) e(13); /* should be stderr + 1 */
if (stat("bar", &st1) != 0) e(14); /* get bar's info */
if (fstat(fd, &st2) != 0) e(15); /* get bar's info */
/* St1 en st2 should be the same. */
if (st1.st_dev != st2.st_dev) e(16);
if (st1.st_ino != st2.st_ino) e(17);
if (st1.st_mode != st2.st_mode) e(18);
if (st1.st_nlink != st2.st_nlink) e(19);
if (st1.st_uid != st2.st_uid) e(20);
if (st1.st_gid != st2.st_gid) e(21);
if (st1.st_size != st2.st_size) e(22);
if (st1.st_atime != st2.st_atime) e(23);
if (st1.st_ctime != st2.st_ctime) e(24);
if (st1.st_mtime != st2.st_mtime) e(25);
time(&time1); /* wait a sec. */
while (time1 >= time((time_t *)0))
;
System("chmod 755 bar"); /* chainge mode */
System("rm -f foobar; ln bar foobar"); /* chainge # links */
if (write(fd, "foo", 4) != 4) e(26); /* write a bit (or two) */
if (stat("bar", &st2) != 0) e(27); /* get new info */
if (st2.st_dev != st1.st_dev) e(28);
if (st2.st_ino != st1.st_ino) e(29); /* compair the fealds */
if ((st2.st_mode & MODE_MASK) != 0755) e(30);
if (!S_ISREG(st2.st_mode)) e(31);
if (st2.st_nlink != st1.st_nlink + 1) e(32);
if (st2.st_uid != st1.st_uid) e(33);
if (st2.st_gid != st1.st_gid) e(34);
if (st2.st_size != (size_t) 11) e(35);
if (st2.st_atime != st1.st_atime) e(36);
if (st2.st_ctime <= st1.st_ctime) e(37);
if (st2.st_mtime <= st1.st_mtime) e(38);
if (close(fd) != 0) e(39); /* sorry the bar is closed */
/* Check special file. */
if (stat("/dev/tty", &st1) != 0) e(40);
if (!S_ISCHR(st1.st_mode)) e(41);
#ifdef _MINIX
if (stat("/dev/ram", &st1) != 0) e(42);
if (!S_ISBLK(st1.st_mode)) e(43);
#endif
/* Check fifos. */
time(&time1);
while (time1 >= time((time_t *)0))
;
if (mkfifo("fifo", 0640) != 0) e(44);
if (stat("fifo", &st1) != 0) e(45); /* get fifo's info */
time(&time2);
while (time2 >= time((time_t *)0))
;
time(&time2);
if (!S_ISFIFO(st1.st_mode)) e(46);
if (st1.st_nlink != 1) e(47); /* check the stat info */
if (st1.st_uid != geteuid()) e(48);
#if defined(NGROUPS_MAX) && NGROUPS_MAX == 0
if (st1.st_gid != getegid()) e(49);
#endif /* defined(NGROUPS_MAX) && NGROUPS_MAX == 0 */
if (st1.st_size != (size_t) 0) e(50);
if (st1.st_atime <= time1) e(51);
if (st1.st_atime >= time2) e(52);
if (st1.st_ctime <= time1) e(53);
if (st1.st_ctime >= time2) e(54);
if (st1.st_mtime <= time1) e(55);
if (st1.st_mtime >= time2) e(56);
/* Note: the st_mode of a fstat on a pipe should contain a isfifo bit. */
/* Check pipes. */
time(&time1);
while (time1 >= time((time_t *)0))
;
if (pipe(pfd) != 0) e(57);
if (fstat(pfd[0], &st1) != 0) e(58); /* get pipe input info */
time(&time2);
while (time2 >= time((time_t *)0))
;
time(&time2);
if (!(S_ISFIFO(st1.st_mode))) e(59); /* check stat struct */
if (st1.st_uid != geteuid()) e(60);
if (st1.st_gid != getegid()) e(61);
if (st1.st_size != (size_t) 0) e(62);
if (st1.st_atime <= time1) e(63);
if (st1.st_atime >= time2) e(64);
if (st1.st_ctime <= time1) e(65);
if (st1.st_ctime >= time2) e(66);
if (st1.st_mtime <= time1) e(67);
if (st1.st_mtime >= time2) e(68);
if (fstat(pfd[1], &st1) != 0) e(69); /* get pipe output info */
if (!(S_ISFIFO(st1.st_mode))) e(70);
if (st1.st_uid != geteuid()) e(71);
if (st1.st_gid != getegid()) e(72);
if (st1.st_size != (size_t) 0) e(73);
if (st1.st_atime < time1) e(74);
if (st1.st_atime > time2) e(75);
if (st1.st_ctime < time1) e(76);
if (st1.st_ctime > time2) e(77);
if (st1.st_mtime < time1) e(78);
if (st1.st_mtime > time2) e(79);
if (close(pfd[0]) != 0) e(80);
if (close(pfd[1]) != 0) e(81);/* close pipe */
/* Check dirs. */
time(&time1);
while (time1 >= time((time_t *)0))
;
System("mkdir dir");
if (stat("dir", &st1) != 0) e(82); /* get dir info */
time(&time2);
while (time2 >= time((time_t *)0))
;
time(&time2);
if (!(S_ISDIR(st1.st_mode))) e(83); /* check stat struct */
if (st1.st_uid != geteuid()) e(84);
#if defined(NGROUPS_MAX) && NGROUPS_MAX == 0
if (st1.st_gid != getegid()) e(85);
#endif /* defined(NGROUPS_MAX) && NGROUPS_MAX == 0 */
if (st1.st_atime < time1) e(86);
if (st1.st_atime > time2) e(87);
if (st1.st_ctime < time1) e(88);
if (st1.st_ctime > time2) e(89);
if (st1.st_mtime < time1) e(90);
if (st1.st_mtime > time2) e(91);
System("rm -rf ../DIR_27/*");
}
void test27b()
{ /* Test maxima. */
struct stat st;
int fd;
subtest = 2;
/* Check stats on maximum length files names. */
if (mkdir(MaxName, 0777) != 0) e(1);
if (stat(MaxName, &st) != 0) e(2);
if ((fd = open(MaxName, O_RDONLY)) != 3) e(3);
if (fstat(fd, &st) != 0) e(4);
if (close(fd) != 0) e(5);
if (rmdir(MaxName) != 0) e(6);
if (stat(MaxPath, &st) != 0) e(7);
if ((fd = open(MaxPath, O_RDONLY)) != 3) e(8);
if (fstat(fd, &st) != 0) e(9);
if (close(fd) != 0) e(10);
System("rm -rf ../DIR_27/*");
}
void test27c()
{ /* Test error response. */
struct stat st;
int fd, i;
subtest = 3;
System("echo Hi > foo"); /* Make a file called foo. */
/* Check if a un searchable dir is handled ok. */
Chdir(".."); /* cd .. */
System("chmod 677 DIR_27"); /* no search permission */
if (stat("DIR_27/nono", &st) != -1) e(1);
if (superuser) {
if (errno != ENOENT) e(2); /* su has access */
}
if (!superuser) {
if (errno != EACCES) e(3); /* we don't ;-) */
}
System("chmod 777 DIR_27");
Chdir("DIR_27"); /* back to test dir */
/* Check on ToLongName etc. */
#ifdef _POSIX_NO_TRUNC
# if _POSIX_NO_TRUNC - 0 != -1
if (stat(ToLongName, &st) != -1) e(4); /* name is too long */
if (errno != ENAMETOOLONG) e(5);
# endif
#else
# include "error, this case requires dynamic checks and is not handled"
#endif
if (stat(ToLongPath, &st) != -1) e(6); /* path is too long */
if (errno != ENAMETOOLONG) e(7);
/* Test some common errors. */
if (stat("nono", &st) != -1) e(8); /* nono nonexistent */
if (errno != ENOENT) e(9);
if (stat("", &st) != -1) e(10); /* try empty */
if (errno != ENOENT) e(11);
if (stat("foo/bar", &st) != -1) e(12); /* foo is a file */
if (errno != ENOTDIR) e(13);
/* Test fstat on file descriptors that are not open. */
for (i = 3; i < 6; i++) {
if (fstat(i, &st) != -1) e(14);
if (errno != EBADF) e(15);
}
/* Test if a just closed file is `fstat()'-able. */
if ((fd = open("foo", O_RDONLY)) != 3) e(16); /* open foo */
if (fstat(fd, &st) != 0) e(17); /* get stat */
if (close(fd) != 0) e(18); /* close it */
if (fstat(fd, &st) != -1) e(19); /* get stat */
if (errno != EBADF) e(20);
System("rm -rf ../DIR_27/*");
}
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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_27");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

449
test/test28.c Normal file
View File

@@ -0,0 +1,449 @@
/* test28: mkdir() rmdir() Author: Jan-Mark Wams (jms@cs.vu.nl) */
/*
** Not tested readonly file systems (EROFS.)
** Not tested fs full (ENOSPC.)
** Not really tested EBUSY.
** Not tested unlinking busy directories.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <limits.h>
#include <time.h>
#include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 2
#define DIRENT0 ((struct dirent *) NULL)
#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)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX];
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1];
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test28a, (void));
_PROTOTYPE(void test28c, (void));
_PROTOTYPE(void test28b, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 28 ");
fflush(stdout);
superuser = (getuid() == 0);
makelongnames();
system("chmod 777 DIR_28/* DIR_28/*/* > /dev/null 2>&1");
System("rm -rf DIR_28; mkdir DIR_28");
Chdir("DIR_28");
umask(0000); /* no umask */
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test28a();
if (m & 0002) test28b();
if (m & 0004) test28c();
}
quit();
}
void test28a()
{
int mode; /* used in for loop */
struct stat st;
time_t time1, time2;
DIR *dirp;
struct dirent *dep;
int dot = 0, dotdot = 0;
subtest = 1;
System("rm -rf foo /tmp/foo");/* clean up junk */
/* Check relative path names */
if (mkdir("./foo", 0777) != 0) e(1); /* make a dir foo */
if (mkdir("./foo/bar", 0777) != 0) e(2); /* make foo/bar */
if (rmdir("foo/bar") != 0) e(3); /* delete bar */
if (mkdir("foo/../foo/bar", 0777) != 0) e(4); /* make bar again */
if (rmdir("./foo/bar") != 0) e(5); /* and remove again */
/* Foo should be empty (ie. contain only "." and ".." */
if ((dirp = opendir("foo")) == (DIR *) NULL) e(6); /* open foo */
if ((dep = readdir(dirp)) == DIRENT0) e(7); /* get first entry */
if (strcmp(dep->d_name, ".") == 0) dot += 1; /* record what it is */
if (strcmp(dep->d_name, "..") == 0) dotdot += 1;
if ((dep = readdir(dirp)) == DIRENT0) e(8); /* get second entry */
if (strcmp(dep->d_name, ".") == 0) dot += 1; /* record again */
if (strcmp(dep->d_name, "..") == 0) dotdot += 1;
if ((dep = readdir(dirp)) != DIRENT0) e(9); /* no 3d entry */
if (dot == 1 && dotdot != 1) e(10); /* only . and .. */
if (closedir(dirp) != 0) e(11); /* close foo */
if (rmdir("./foo") != 0) e(12); /* remove dir foo */
/* Check absolute path names */
if (mkdir("/tmp/foo", 0777) != 0) e(13);
if (mkdir("/tmp/foo/bar", 0777) != 0) e(14);
if (rmdir("/tmp/foo/bar") != 0) e(15); /* make some dirs */
if (rmdir("/tmp/foo") != 0) e(16);
/* Check the mode arument for mkdir() */
for (mode = 0; mode <= 0777; mode++) {
if (mkdir("foo", mode) != 0) e(17); /* make foo */
if (stat("foo", &st) != 0) e(18);
if ((st.st_mode & 0777) != mode) e(19); /* check it's mode */
if (rmdir("foo") != 0) e(20); /* and remove it */
}
/* Check the stat */
time(&time1);
while (time1 >= time((time_t *)0))
;
if (mkdir("foo", 0765) != 0) e(21); /* make foo */
if (stat("foo", &st) != 0) e(22);
time(&time2);
while (time2 >= time((time_t *)0))
;
time(&time2);
if (st.st_nlink != 2) e(23);
if (st.st_uid != geteuid()) e(24);
if (st.st_gid != getegid()) e(25);
if (st.st_size < 0) e(26);
if ((st.st_mode & 0777) != 0765) e(27);
if (st.st_atime <= time1) e(28);
if (st.st_atime >= time2) e(29);
if (st.st_ctime <= time1) e(30);
if (st.st_ctime >= time2) e(31);
if (st.st_mtime <= time1) e(32);
if (st.st_mtime >= time2) e(33);
/* Check if parent is updated */
if (stat(".", &st) != 0) e(34);
time(&time2);
while (time2 >= time((time_t *)0))
;
time(&time2);
if (st.st_ctime <= time1) e(35);
if (st.st_ctime >= time2) e(36);
if (st.st_mtime <= time1) e(37);
if (st.st_mtime >= time2) e(38);
time(&time1);
while (time1 >= time((time_t *)0))
;
if (rmdir("foo") != 0) e(39);
if (stat(".", &st) != 0) e(40);
time(&time2);
while (time2 >= time((time_t *)0))
;
time(&time2);
if (st.st_ctime <= time1) e(41);
if (st.st_ctime >= time2) e(42);
if (st.st_mtime <= time1) e(43);
if (st.st_mtime >= time2) e(44);
}
void test28b()
{ /* Test critical values. */
struct stat st;
DIR *dirp;
struct dirent *dep;
int fd; /* file descriptor */
int other = 0, dot = 0, dotdot = 0; /* dirent counters */
int rmdir_result; /* tmp var */
nlink_t nlink;
static char bar[] = "foo/bar.xxxxx";
int stat_loc;
subtest = 2;
System("rm -rf ../DIR_28/*");
/* Check funny but valid path names */
if (mkdir("/../../..////.//../tmp/foo/", 0777) != 0) e(1);
if (mkdir("/tmp/foo//////..//foo//../foo/bar/", 0777) != 0) e(2);
if (rmdir("///tmp/..//tmp/foo/bar//../..//foo/bar") != 0) e(3);
if (mkdir("///tmp/foo/foobar//", 0777) != 0) e(4);
if (rmdir("/tmp/foo/foobar//") != 0) e(5);
if (rmdir("/.././/././/tmp/foo///////////////") != 0) e(6);
if (rmdir("/tmp/foo") != -1) e(7); /* try again */
if (LINK_MAX >= 99999) e(8); /* "xxxxx" in filename not long inough */
/* Test max path ed. */
if (mkdir(MaxName, 0777) != 0) e(9); /* make dir MaxName */
if (rmdir(MaxName) != 0) e(10); /* and remove it */
MaxPath[strlen(MaxPath) - 2] = '/'; /* convert MaxPath */
MaxPath[strlen(MaxPath) - 1] = 'a'; /* to ././.../a */
if (mkdir(MaxPath, 0777) != 0) e(11); /* it should be */
if (rmdir(MaxPath) != 0) e(12); /* ok */
/* Test too long path ed. */
if (mkdir(ToLongName, 0777) != 0) e(17); /* Try ToLongName */
if (rmdir(ToLongName) != 0) e(18); /* and remove it */
ToLongPath[strlen(ToLongPath) - 2] = '/'; /* make ToLongPath */
ToLongPath[strlen(ToLongPath) - 1] = 'a'; /* contain ././.../a */
if (mkdir(ToLongPath, 0777) != -1) e(19); /* it should */
if (errno != ENAMETOOLONG) e(20); /* not be ok */
if (rmdir(ToLongPath) != -1) e(21);
if (errno != ENAMETOOLONG) e(22);
/* Test what happens if the parent link count > LINK_MAX. */
if (mkdir("foo", 0777) != 0) e(23); /* make foo */
if (LINK_MAX > 127) {
printf("[skip] "); /* takes to many resources */
} else {
for (nlink = 2; nlink < LINK_MAX; nlink++) { /* make all */
bar[8] = (char) ((nlink / 10000) % 10) + '0';
bar[9] = (char) ((nlink / 1000) % 10) + '0';
bar[10] = (char) ((nlink / 100) % 10) + '0';
bar[11] = (char) ((nlink / 10) % 10) + '0';
bar[12] = (char) (nlink % 10) + '0';
if (mkdir(bar, 0777) != 0) {
printf("nlink=%u\n", nlink);
e(24);
}
}
if (stat("foo", &st) != 0) e(25); /* foo now */
if (st.st_nlink != LINK_MAX) e(26); /* is full */
if (mkdir("foo/nono", 0777) != -1) e(27); /* no more */
if (errno != EMLINK) e(28); /* entrys. */
System("rm -rf foo/nono"); /* Just in case. */
/* Test if rmdir removes only empty dirs */
if (rmdir("foo") != -1) e(29);/* not empty */
if (errno != EEXIST && errno != ENOTEMPTY) e(30);
}
/* Test if rmdir removes a dir with an empty file (it shouldn't.) */
System("rm -rf foo"); /* cleanup */
if (mkdir("foo", 0777) != 0) e(31);
System("> foo/empty"); /* > empty */
if (rmdir("foo") != -1) e(32);/* not empty */
if (errno != EEXIST && errno != ENOTEMPTY) e(33);
if (unlink("foo/empty") != 0) e(34); /* rm empty */
/* See what happens if foo is linked. */
if (superuser) {
if (link("foo", "footoo") != 0) e(35); /* foo still */
if (rmdir("footoo") != 0) e(36); /* exist */
if (chdir("footoo") != -1) e(37); /* footoo */
if (errno != ENOENT) e(38); /* is gone */
}
#ifdef _MINIX
/* Some implementations might allow users to link directories. */
if (!superuser) {
if (link("foo", "footoo") != -1) e(39);
if (errno != EPERM) e(40);
if (unlink("foo") != -1) e(41);
if (errno != EPERM) e(42);
}
#endif
/* See if ".." and "." are removed from the dir, and if it is
* unwriteable * Note, we can not remove any files in the PARENT
* process, because this * will make readdir unpredicatble. (see
* 1003.1 page 84 line 30.) However * removal of the directory is
* not specified in the standard.
*/
System("rm -rf /tmp/sema[12].07");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd = open("foo", O_RDONLY)) <= 2) e(43); /* open */
if ((dirp = opendir("foo")) == (DIR *) NULL) e(44); /* opendir */
/* UpA downB */
system(">/tmp/sema1.07; while test -f /tmp/sema1.07; do sleep 1;done");
while ((dep = readdir(dirp)) != DIRENT0) {
if (strcmp(dep->d_name, "..") == 0)
dotdot += 1;
else if (strcmp(dep->d_name, ".") == 0)
dot += 1;
else
other += 1;
}
if (dotdot != 0) e(45); /* no entrys */
if (dot != 0) e(46); /* shoul be */
if (other != 0) e(47); /* left or */
/* No new files (entrys) are allowed on foo */
if (creat("foo/nono", 0777) != -1) e(48); /* makeable */
if (closedir(dirp) != 0) e(49); /* close foo */
system("while test ! -f /tmp/sema2.07; do sleep 1; done"); /* downA */
System("rm -f /tmp/sema2.07"); /* clean up */
/* Foo still exist, so we should be able to get a fstat */
if (fstat(fd, &st) != 0) e(50);
if (st.st_nlink != (nlink_t) 0) e(51); /* 0 left */
if (close(fd) != 0) e(52); /* last one */
exit(0);
default:
system("while test ! -f /tmp/sema1.07; do sleep 1; done"); /* downA */
if (rmdir("foo") != 0) e(53); /* cleanerup */
System("rm -f /tmp/sema1.07"); /* upB */
if (chdir("foo") != -1) e(54); /* it should */
if (errno != ENOENT) e(55); /* be gone */
System("> /tmp/sema2.07"); /* upA */
if (wait(&stat_loc) == -1) e(56);
if (stat_loc != 0) e(57);
}
/* See if foo isn't accessible any more */
if (chdir("foo") != -1) e(58);
if (errno != ENOENT) e(59);
/* Let's see if we can get a EBUSSY..... */
if (mkdir("foo", 0777) != 0) e(60); /* mkdir foo */
System("rm -f /tmp/sema.07"); /* unness */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (chdir("foo") != 0) e(61); /* child goes */
System("> /tmp/sema.07"); /* upA */
system("while test -f /tmp/sema.07; do sleep 1; done"); /* downB */
sleep(1);
exit(0);
default:
system("while test ! -f /tmp/sema.07; do sleep 1; done"); /* downA */
rmdir_result = rmdir("foo"); /* try remove */
if (rmdir_result == -1) { /* if it failed */
if (errno != EBUSY) e(62); /* foo is busy */
} else {
if (rmdir_result != 0) e(63);
if (rmdir("foo") != -1) e(64); /* not removable */
if (errno != ENOENT) e(65); /* again. */
if (chdir("foo") != -1) e(66); /* we can't go */
if (errno != ENOENT) e(67); /* there any more */
if (mkdir("foo", 0777) != 0) e(68); /* we can remake foo */
}
System("rm -f /tmp/sema.07"); /* upB */
if (wait(&stat_loc) == -1) e(69);
if (stat_loc != 0) e(70);
}
if (rmdir("foo") != 0) e(71); /* clean up */
}
void test28c()
{ /* Test error handeling. */
subtest = 3;
System("rm -rf ../DIR_28/*");
System("rm -rf foo /tmp/foo");/* clean up junk */
/* Test common errors */
if (mkdir("foo", 0777) != 0) e(1); /* mkdir shouldn't fail */
if (mkdir("foo", 0777) != -1) e(2); /* should fail the 2d time */
if (errno != EEXIST) e(3); /* because it exists already */
if (rmdir("foo") != 0) e(4); /* rmdir shouldn't fail */
if (rmdir("foo") != -1) e(5); /* but it should now because */
if (errno != ENOENT) e(6); /* it's gone the 1st time */
/* Test on access etc. */
if (mkdir("foo", 0777) != 0) e(7);
if (mkdir("foo/bar", 0777) != 0) e(8);
if (!superuser) {
System("chmod 677 foo");/* make foo inaccesable */
if (mkdir("foo/foo", 0777) != -1) e(9);
if (errno != EACCES) e(10);
if (rmdir("foo/bar") != -1) e(11);
if (errno != EACCES) e(12);
System("chmod 577 foo");/* make foo unwritable */
if (mkdir("foo/foo", 0777) != -1) e(13);
if (errno != EACCES) e(14);
if (rmdir("foo/bar") != -1) e(15);
if (errno != EACCES) e(16);
System("chmod 777 foo");/* make foo full accessable */
}
if (rmdir("foo/bar") != 0) e(17); /* bar should be removable */
if (mkdir("foo/no/foo", 0777) != -1) e(18); /* Note: "no" doesn't exist */
if (errno != ENOENT) e(19);
if (mkdir("", 0777) != -1) e(20); /* empty string isn't ok */
if (errno != ENOENT) e(21);
if (rmdir("") != -1) e(22); /* empty string isn't ok */
if (errno != ENOENT) e(23);
System("> foo/no"); /* make a file "no" */
if (mkdir("foo/no/foo", 0777) != -1) e(24);
if (errno != ENOTDIR) e(25); /* note: "no" is not a a dir */
if (rmdir("foo/no/foo") != -1) e(26);
if (errno != ENOTDIR) e(27);
System("rm -rf foo"); /* clean up */
}
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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_28");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

750
test/test29.c Normal file
View File

@@ -0,0 +1,750 @@
/* Many of the tests require 1.6.n, n > 16, so we may as well assume that
* POSIX signals are implemented.
*/
#define SIGACTION
/* test29: read(), write() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 3
#define BUF_SIZE 1024
#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)
int errct = 0;
int subtest = 1;
int superuser;
int signumber = 0;
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test29a, (void));
_PROTOTYPE(void test29b, (void));
_PROTOTYPE(void test29c, (void));
_PROTOTYPE(void setsignumber, (int _signumber));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 29 ");
fflush(stdout);
System("rm -rf DIR_29; mkdir DIR_29");
Chdir("DIR_29");
superuser = (geteuid() == 0);
umask(0000);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test29a();
if (m & 0002) test29b();
if (m & 0004) test29c();
}
quit();
}
void test29a()
{ /* Try normal operation. */
int fd1;
struct stat st1, st2;
time_t time1;
char buf[BUF_SIZE];
int stat_loc;
int i, j;
int tube[2];
subtest = 1;
System("rm -rf ../DIR_29/*");
/* Let's open bar. */
if ((fd1 = open("bar", O_RDWR | O_CREAT, 0777)) != 3) e(1);
Stat("bar", &st1);
/* Writing nothing should not affect the file at all. */
if (write(fd1, "", 0) != 0) e(2);
Stat("bar", &st2);
if (st1.st_uid != st2.st_uid) e(3);
if (st1.st_gid != st2.st_gid) e(4); /* should be same */
if (st1.st_mode != st2.st_mode) e(5);
if (st1.st_size != st2.st_size) e(6);
if (st1.st_nlink != st2.st_nlink) e(7);
if (st1.st_mtime != st2.st_mtime) e(8);
if (st1.st_ctime != st2.st_ctime) e(9);
if (st1.st_atime != st2.st_atime) e(10);
/* A write should update some status fields. */
time(&time1);
while (time1 >= time((time_t *)0))
;
if (write(fd1, "foo", 4) != 4) e(11);
Stat("bar", &st2);
if (st1.st_mode != st2.st_mode) e(12);
if (st1.st_size >= st2.st_size) e(13);
if ((off_t) 4 != st2.st_size) e(14);
if (st1.st_nlink != st2.st_nlink) e(15);
if (st1.st_mtime >= st2.st_mtime) e(16);
if (st1.st_ctime >= st2.st_ctime) e(17);
if (st1.st_atime != st2.st_atime) e(18);
/* Lseeks should not change the file status. */
if (lseek(fd1, (off_t) - 2, SEEK_END) != 2) e(19);
Stat("bar", &st1);
if (st1.st_mode != st2.st_mode) e(20);
if (st1.st_size != st2.st_size) e(21);
if (st1.st_nlink != st2.st_nlink) e(22);
if (st1.st_mtime != st2.st_mtime) e(23);
if (st1.st_ctime != st2.st_ctime) e(24);
if (st1.st_atime != st2.st_atime) e(25);
/* Writing should start at the current (2) position. */
if (write(fd1, "foo", 4) != 4) e(26);
Stat("bar", &st2);
if (st1.st_mode != st2.st_mode) e(27);
if (st1.st_size >= st2.st_size) e(28);
if ((off_t) 6 != st2.st_size) e(29);
if (st1.st_nlink != st2.st_nlink) e(30);
if (st1.st_mtime > st2.st_mtime) e(31);
if (st1.st_ctime > st2.st_ctime) e(32);
if (st1.st_atime != st2.st_atime) e(33);
/* A read of zero bytes should not affect anything. */
if (read(fd1, buf, 0) != 0) e(34);
Stat("bar", &st1);
if (st1.st_uid != st2.st_uid) e(35);
if (st1.st_gid != st2.st_gid) e(36); /* should be same */
if (st1.st_mode != st2.st_mode) e(37);
if (st1.st_size != st2.st_size) e(38);
if (st1.st_nlink != st2.st_nlink) e(39);
if (st1.st_mtime != st2.st_mtime) e(40);
if (st1.st_ctime != st2.st_ctime) e(41);
if (st1.st_atime != st2.st_atime) e(42);
/* The file now should contain ``fofoo\0'' Let's check that. */
if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(43);
if (read(fd1, buf, BUF_SIZE) != 6) e(44);
if (strcmp(buf, "fofoo") != 0) e(45);
/* Only the Access Time should be updated. */
Stat("bar", &st2);
if (st1.st_mtime != st2.st_mtime) e(46);
if (st1.st_ctime != st2.st_ctime) e(47);
if (st1.st_atime >= st2.st_atime) e(48);
/* A read of zero bytes should do nothing even at the end of the file. */
time(&time1);
while (time1 >= time((time_t *)0))
;
if (read(fd1, buf, 0) != 0) e(49);
Stat("bar", &st1);
if (st1.st_size != st2.st_size) e(50);
if (st1.st_mtime != st2.st_mtime) e(51);
if (st1.st_ctime != st2.st_ctime) e(52);
if (st1.st_atime != st2.st_atime) e(53);
/* Reading should be done from the current offset. */
if (read(fd1, buf, BUF_SIZE) != 0) e(54);
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(55);
if (read(fd1, buf, BUF_SIZE) != 4) e(56);
if (strcmp(buf, "foo") != 0) e(57);
/* Reading should effect the current file position. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(58);
if (read(fd1, buf, 1) != 1) e(59);
if (*buf != 'f') e(60);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 3) e(61);
if (read(fd1, buf, 1) != 1) e(62);
if (*buf != 'o') e(63);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(64);
if (read(fd1, buf, 1) != 1) e(65);
if (*buf != 'o') e(66);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 5) e(67);
if (read(fd1, buf, 1) != 1) e(68);
if (*buf != '\0') e(69);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(70);
/* Read's at EOF should return 0. */
if (read(fd1, buf, BUF_SIZE) != 0) e(71);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(72);
if (read(fd1, buf, BUF_SIZE) != 0) e(73);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(74);
if (read(fd1, buf, BUF_SIZE) != 0) e(75);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(76);
if (read(fd1, buf, BUF_SIZE) != 0) e(77);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(78);
if (read(fd1, buf, BUF_SIZE) != 0) e(79);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(80);
/* Writing should not always change the file size. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(81);
if (write(fd1, "ba", 2) != 2) e(82);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(83);
Stat("bar", &st1);
if (st1.st_size != 6) e(84);
/* Kill the \0 at the end. */
if (lseek(fd1, (off_t) 5, SEEK_SET) != 5) e(85);
if (write(fd1, "x", 1) != 1) e(86);
/* And close the bar. */
if (close(fd1) != 0) e(87);
/* Try some stuff with O_APPEND. Bar contains ``fobaox'' */
if ((fd1 = open("bar", O_RDWR | O_APPEND)) != 3) e(88);
/* No matter what the file position is. Writes should append. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(89);
if (write(fd1, "y", 1) != 1) e(90);
Stat("bar", &st1);
if (st1.st_size != (off_t) 7) e(91);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 7) e(92);
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(93);
if (write(fd1, "z", 2) != 2) e(94);
/* The file should contain ``fobaoxyz\0'' == 9 chars long. */
Stat("bar", &st1);
if (st1.st_size != (off_t) 9) e(95);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(96);
/* Reading on a O_APPEND flag should be from the current offset. */
if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(97);
if (read(fd1, buf, BUF_SIZE) != 9) e(98);
if (strcmp(buf, "fobaoxyz") != 0) e(99);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(100);
if (close(fd1) != 0) e(101);
/* Let's test fifo writes. First blocking. */
if (mkfifo("fifo", 0777) != 0) e(102);
/* Read from fifo but no writer. */
System("rm -rf /tmp/sema.29a");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(103);
system("> /tmp/sema.29a");
system("while test -f /tmp/sema.29a; do sleep 1; done");
errno =0;
if (read(fd1, buf, BUF_SIZE) != 0) e(104);
if (read(fd1, buf, BUF_SIZE) != 0) e(105);
if (read(fd1, buf, BUF_SIZE) != 0) e(106);
if (close(fd1) != 0) e(107);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(108);
while (stat("/tmp/sema.29a", &st1) != 0) sleep(1);
if (close(fd1) != 0) e(109);
unlink("/tmp/sema.29a");
if (wait(&stat_loc) == -1) e(110);
if (stat_loc != 0) e(111); /* Alarm? */
}
/* Read from fifo should wait for writer. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(112);
if (read(fd1, buf, BUF_SIZE) != 10) e(113);
if (strcmp(buf, "Hi reader") != 0) e(114);
if (close(fd1) != 0) e(115);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(116);
sleep(1);
if (write(fd1, "Hi reader", 10) != 10) e(117);
if (close(fd1) != 0) e(118);
if (wait(&stat_loc) == -1) e(119);
if (stat_loc != 0) e(120); /* Alarm? */
}
/* Read from fifo should wait for all writers to close. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(121);
if (close(fd1) != 0) e(122);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(123);
sleep(1);
if (close(fd1) != 0) e(124);
if (wait(&stat_loc) == -1) e(125);
if (stat_loc != 0) e(126); /* Alarm? */
}
exit(stat_loc);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(127);
if (read(fd1, buf, BUF_SIZE) != 0) e(128);
if (close(fd1) != 0) e(129);
if (wait(&stat_loc) == -1) e(130);
if (stat_loc != 0) e(131); /* Alarm? */
}
/* PIPE_BUF has to have a nice value. */
if (PIPE_BUF < 5) e(132);
if (BUF_SIZE < 1000) e(133);
/* Writes of blocks smaller than PIPE_BUF should be atomic. */
System("rm -rf /tmp/sema.29b;> /tmp/sema.29b");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(134);
for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
system("while test -f /tmp/sema.29b; do sleep 1; done");
if (close(fd1) != 0) e(135);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(136);
for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
while (stat("/tmp/sema.29b", &st1) == 0) sleep(1);
if (close(fd1) != 0) e(137);
if (wait(&stat_loc) == -1) e(138);
if (stat_loc != 0) e(139); /* Alarm? */
}
exit(stat_loc);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(140);
i = 0;
memset(buf, '\0', BUF_SIZE);
/* Read buffer full or till EOF. */
do {
j = read(fd1, buf + i, BUF_SIZE - i);
if (j > 0) {
if (j % 5 != 0) e(141);
i += j;
}
} while (j > 0 && i < 1000);
/* Signal the children to close write ends. This should not be */
/* Necessary. But due to a bug in 1.16.6 this is necessary. */
unlink("/tmp/sema.29b");
if (j < 0) e(142);
if (i != 1000) e(143);
if (wait(&stat_loc) == -1) e(144);
if (stat_loc != 0) e(145); /* Alarm? */
/* Check 200 times 1234. */
for (i = 0; i < 200; i++)
if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
if (i != 200) e(146);
if (buf[1000] != '\0') e(147);
if (buf[1005] != '\0') e(148);
if (buf[1010] != '\0') e(149);
if (read(fd1, buf, BUF_SIZE) != 0) e(150);
if (close(fd1) != 0) e(151);
}
/* Read from pipe should wait for writer. */
if (pipe(tube) != 0) e(152);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[1]) != 0) e(153);
if (read(tube[0], buf, BUF_SIZE) != 10) e(154);
if (strcmp(buf, "Hi reader") != 0) e(155);
if (close(tube[0]) != 0) e(156);
exit(0);
default:
if (close(tube[0]) != 0) e(157);
sleep(1);
if (write(tube[1], "Hi reader", 10) != 10) e(158);
if (close(tube[1]) != 0) e(159);
if (wait(&stat_loc) == -1) e(160);
if (stat_loc != 0) e(161); /* Alarm? */
}
/* Read from pipe should wait for all writers to close. */
if (pipe(tube) != 0) e(162);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[0]) != 0) e(163);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[1]) != 0) e(164);
exit(0);
default:
sleep(1);
if (close(tube[1]) != 0) e(165);
if (wait(&stat_loc) == -1) e(166);
if (stat_loc != 0) e(167); /* Alarm? */
}
exit(stat_loc);
default:
if (close(tube[1]) != 0) e(168);
if (read(tube[0], buf, BUF_SIZE) != 0) e(169);
if (close(tube[0]) != 0) e(170);
if (wait(&stat_loc) == -1) e(171);
if (stat_loc != 0) e(172); /* Alarm? */
}
/* Writes of blocks smaller than PIPE_BUF should be atomic. */
System("rm -rf /tmp/sema.29c;> /tmp/sema.29c");
if (pipe(tube) != 0) e(173);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[0]) != 0) e(174);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
system("while test -f /tmp/sema.29c; do sleep 1; done");
if (close(tube[1]) != 0) e(175);
exit(0);
default:
for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
while (stat("/tmp/sema.29c", &st1) == 0) sleep(1);
if (close(tube[1]) != 0) e(176);
if (wait(&stat_loc) == -1) e(177);
if (stat_loc != 0) e(178); /* Alarm? */
}
exit(stat_loc);
default:
i = 0;
if (close(tube[1]) != 0) e(179);
memset(buf, '\0', BUF_SIZE);
do {
j = read(tube[0], buf + i, BUF_SIZE - i);
if (j > 0) {
if (j % 5 != 0) e(180);
i += j;
} else
break; /* EOF seen. */
} while (i < 1000);
unlink("/tmp/sema.29c");
if (j < 0) e(181);
if (i != 1000) e(182);
if (close(tube[0]) != 0) e(183);
if (wait(&stat_loc) == -1) e(184);
if (stat_loc != 0) e(185); /* Alarm? */
/* Check 200 times 1234. */
for (i = 0; i < 200; i++)
if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
if (i != 200) e(186);
}
}
void test29b()
{
int i, fd, stat_loc;
char buf[BUF_SIZE];
char buf2[BUF_SIZE];
struct stat st;
subtest = 2;
System("rm -rf ../DIR_29/*");
/* Lets try sequential writes. */
system("rm -rf /tmp/sema.29d");
System("> testing");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(1);
if (write(fd, "one ", 4) != 4) e(2);
if (close(fd) != 0) e(3);
system("> /tmp/sema.29d");
system("while test -f /tmp/sema.29d; do sleep 1; done");
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(4);
if (write(fd, "three ", 6) != 6) e(5);
if (close(fd) != 0) e(6);
system("> /tmp/sema.29d");
exit(0);
default:
while (stat("/tmp/sema.29d", &st) != 0) sleep(1);
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(7);
if (write(fd, "two ", 4) != 4) e(8);
if (close(fd) != 0) e(9);
unlink("/tmp/sema.29d");
while (stat("/tmp/sema.29d", &st) != 0) sleep(1);
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(10);
if (write(fd, "four", 5) != 5) e(11);
if (close(fd) != 0) e(12);
if (wait(&stat_loc) == -1) e(13);
if (stat_loc != 0) e(14); /* The alarm went off? */
unlink("/tmp/sema.29d");
}
if ((fd = open("testing", O_RDONLY)) != 3) e(15);
if (read(fd, buf, BUF_SIZE) != 19) e(16);
if (strcmp(buf, "one two three four") != 0) e(17);
if (close(fd) != 0) e(18);
/* Non written bytes in regular files should be zero. */
memset(buf2, '\0', BUF_SIZE);
if ((fd = open("bigfile", O_RDWR | O_CREAT, 0644)) != 3) e(19);
if (lseek(fd, (off_t) 102400, SEEK_SET) != (off_t) 102400L) e(20);
if (read(fd, buf, BUF_SIZE) != 0) e(21);
if (write(fd, ".", 1) != 1) e(22);
Stat("bigfile", &st);
if (st.st_size != (off_t) 102401) e(23);
if (lseek(fd, (off_t) 0, SEEK_SET) != 0) e(24);
for (i = 0; i < 102400 / BUF_SIZE; i++) {
if (read(fd, buf, BUF_SIZE) != BUF_SIZE) e(25);
if (memcmp(buf, buf2, BUF_SIZE) != 0) e(26);
}
if (close(fd) != 0) e(27);
}
void test29c()
{ /* Test correct error behavior. */
char buf[BUF_SIZE];
int fd, tube[2], stat_loc;
struct stat st;
pid_t pid;
#ifdef SIGACTION
struct sigaction act, oact;
#else
#if _ANSI
void (*oldfunc) (int);
#else
void (*oldfunc) ();
#endif
#endif
subtest = 3;
System("rm -rf ../DIR_29/*");
/* To test if writing processes on closed pipes are signumbered. */
#ifdef SIGACTION
act.sa_handler = setsignumber;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGPIPE, &act, &oact) != 0) e(1);
#else
oldfunc = signal(SIGPIPE, setsignumber);
#endif
/* Non valid file descriptors should be an error. */
for (fd = -111; fd < 0; fd++) {
errno = 0;
if (read(fd, buf, BUF_SIZE) != -1) e(2);
if (errno != EBADF) e(3);
}
for (fd = 3; fd < 111; fd++) {
errno = 0;
if (read(fd, buf, BUF_SIZE) != -1) e(4);
if (errno != EBADF) e(5);
}
for (fd = -111; fd < 0; fd++) {
errno = 0;
if (write(fd, buf, BUF_SIZE) != -1) e(6);
if (errno != EBADF) e(7);
}
for (fd = 3; fd < 111; fd++) {
errno = 0;
if (write(fd, buf, BUF_SIZE) != -1) e(8);
if (errno != EBADF) e(9);
}
/* Writing a pipe with no readers should trigger SIGPIPE. */
if (pipe(tube) != 0) e(10);
close(tube[0]);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
signumber = 0;
if (write(tube[1], buf, BUF_SIZE) != -1) e(11);
if (errno != EPIPE) e(12);
if (signumber != SIGPIPE) e(13);
if (close(tube[1]) != 0) e(14);
exit(0);
default:
close(tube[1]);
if (wait(&stat_loc) == -1) e(15);
if (stat_loc != 0) e(16); /* Alarm? */
}
/* Writing a fifo with no readers should trigger SIGPIPE. */
System("> /tmp/sema.29e");
if (mkfifo("fifo", 0666) != 0) e(17);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd = open("fifo", O_WRONLY)) != 3) e(18);
system("while test -f /tmp/sema.29e; do sleep 1; done");
signumber = 0;
if (write(fd, buf, BUF_SIZE) != -1) e(19);
if (errno != EPIPE) e(20);
if (signumber != SIGPIPE) e(21);
if (close(fd) != 0) e(22);
exit(0);
default:
if ((fd = open("fifo", O_RDONLY)) != 3) e(23);
if (close(fd) != 0) e(24);
unlink("/tmp/sema.29e");
if (wait(&stat_loc) == -1) e(25);
if (stat_loc != 0) e(26); /* Alarm? */
}
#ifdef SIGACTION
/* Restore normal (re)action to SIGPIPE. */
if (sigaction(SIGPIPE, &oact, NULL) != 0) e(27);
#else
signal(SIGPIPE, oldfunc);
#endif
/* Read from fifo should return -1 and set errno to EAGAIN. */
System("rm -rf /tmp/sema.29[fgh]");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
system("while test ! -f /tmp/sema.29f; do sleep 1; done");
System("rm -rf /tmp/sema.29f");
if ((fd = open("fifo", O_WRONLY | O_NONBLOCK)) != 3) e(28);
close(creat("/tmp/sema.29g", 0666));
system("while test ! -f /tmp/sema.29h; do sleep 1; done");
if (close(fd) != 0) e(29);
System("rm -rf /tmp/sema.29h");
exit(0);
default:
if ((fd = open("fifo", O_RDONLY | O_NONBLOCK)) != 3) e(30);
close(creat("/tmp/sema.29f", 0666));
system("while test ! -f /tmp/sema.29g; do sleep 1; done");
System("rm -rf /tmp/sema.29g");
if (read(fd, buf, BUF_SIZE) != -1) e(31);
if (errno != EAGAIN) e(32);
if (read(fd, buf, BUF_SIZE) != -1) e(33);
if (errno != EAGAIN) e(34);
if (read(fd, buf, BUF_SIZE) != -1) e(35);
if (errno != EAGAIN) e(36);
close(creat("/tmp/sema.29h", 0666));
while (stat("/tmp/sema.29h", &st) == 0) sleep(1);
if (read(fd, buf, BUF_SIZE) != 0) e(37);
if (close(fd) != 0) e(38);
if (wait(&stat_loc) == -1) e(39);
if (stat_loc != 0) e(40); /* Alarm? */
}
System("rm -rf fifo");
/* If a read is interrupted by a SIGNAL. */
if (pipe(tube) != 0) e(41);
switch (pid = fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
#ifdef SIGACTION
act.sa_handler = setsignumber;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGUSR1, &act, &oact) != 0) e(42);
#else
oldfunc = signal(SIGUSR1, setsignumber);
#endif
if (read(tube[0], buf, BUF_SIZE) != -1) e(43);
if (errno != EINTR) e(44);
if (signumber != SIGUSR1) e(45);
#ifdef SIGACTION
/* Restore normal (re)action to SIGPIPE. */
if (sigaction(SIGUSR1, &oact, NULL) != 0) e(46);
#else
signal(SIGUSR1, oldfunc);
#endif
close(tube[0]);
close(tube[1]);
exit(0);
default:
/* The sleep 1 should give the child time to start the read. */
sleep(1);
close(tube[0]);
kill(pid, SIGUSR1);
wait(&stat_loc);
if (stat_loc != 0) e(47); /* Alarm? */
close(tube[1]);
}
}
void setsignumber(signum)
int signum;
{
signumber = signum;
}
void e(n)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_29");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

256
test/test3.c Normal file
View File

@@ -0,0 +1,256 @@
/* test 3 - library routines rather than system calls */
#include <sys/types.h>
#include <sys/utsname.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define ITERATIONS 10
#define MAX_ERROR 4
#define SIZE 64
int errct, subtest;
char el_weirdo[] = "\n\t\\\e@@!!##\e\e\n\n";
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test3a, (void));
_PROTOTYPE(void test3b, (void));
_PROTOTYPE(void test3c, (void));
_PROTOTYPE(void test3d, (void));
_PROTOTYPE(void test3e, (void));
_PROTOTYPE(void quit, (void));
_PROTOTYPE(void e, (int n));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (geteuid() == 0 || getuid() == 0) {
printf("Test 3 cannot run as root; test aborted\n");
exit(1);
}
if (argc == 2) m = atoi(argv[1]);
printf("Test 3 ");
fflush(stdout); /* have to flush for child's benefit */
system("rm -rf DIR_03; mkdir DIR_03");
chdir("DIR_03");
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test3a();
if (m & 0002) test3b();
if (m & 0004) test3c();
if (m & 0010) test3d();
if (m & 0020) test3e();
}
quit();
return(-1); /* impossible */
}
void test3a()
{
/* Signal set manipulation. */
sigset_t s, s1;
subtest = 1;
errno = -1000; /* None of these calls set errno. */
if (sigemptyset(&s) != 0) e(1);
if (sigemptyset(&s1) != 0) e(2);
if (sigaddset(&s, SIGABRT) != 0) e(3);
if (sigaddset(&s, SIGALRM) != 0) e(4);
if (sigaddset(&s, SIGFPE ) != 0) e(5);
if (sigaddset(&s, SIGHUP ) != 0) e(6);
if (sigaddset(&s, SIGILL ) != 0) e(7);
if (sigaddset(&s, SIGINT ) != 0) e(8);
if (sigaddset(&s, SIGKILL) != 0) e(9);
if (sigaddset(&s, SIGPIPE) != 0) e(10);
if (sigaddset(&s, SIGQUIT) != 0) e(11);
if (sigaddset(&s, SIGSEGV) != 0) e(12);
if (sigaddset(&s, SIGTERM) != 0) e(13);
if (sigaddset(&s, SIGUSR1) != 0) e(14);
if (sigaddset(&s, SIGUSR2) != 0) e(15);
if (sigismember(&s, SIGABRT) != 1) e(16);
if (sigismember(&s, SIGALRM) != 1) e(17);
if (sigismember(&s, SIGFPE ) != 1) e(18);
if (sigismember(&s, SIGHUP ) != 1) e(19);
if (sigismember(&s, SIGILL ) != 1) e(20);
if (sigismember(&s, SIGINT ) != 1) e(21);
if (sigismember(&s, SIGKILL) != 1) e(22);
if (sigismember(&s, SIGPIPE) != 1) e(23);
if (sigismember(&s, SIGQUIT) != 1) e(24);
if (sigismember(&s, SIGSEGV) != 1) e(25);
if (sigismember(&s, SIGTERM) != 1) e(26);
if (sigismember(&s, SIGUSR1) != 1) e(27);
if (sigismember(&s, SIGUSR2) != 1) e(28);
if (sigdelset(&s, SIGABRT) != 0) e(29);
if (sigdelset(&s, SIGALRM) != 0) e(30);
if (sigdelset(&s, SIGFPE ) != 0) e(31);
if (sigdelset(&s, SIGHUP ) != 0) e(32);
if (sigdelset(&s, SIGILL ) != 0) e(33);
if (sigdelset(&s, SIGINT ) != 0) e(34);
if (sigdelset(&s, SIGKILL) != 0) e(35);
if (sigdelset(&s, SIGPIPE) != 0) e(36);
if (sigdelset(&s, SIGQUIT) != 0) e(37);
if (sigdelset(&s, SIGSEGV) != 0) e(38);
if (sigdelset(&s, SIGTERM) != 0) e(39);
if (sigdelset(&s, SIGUSR1) != 0) e(40);
if (sigdelset(&s, SIGUSR2) != 0) e(41);
if (s != s1) e(42);
if (sigaddset(&s, SIGILL) != 0) e(43);
if (s == s1) e(44);
if (sigfillset(&s) != 0) e(45);
if (sigismember(&s, SIGABRT) != 1) e(46);
if (sigismember(&s, SIGALRM) != 1) e(47);
if (sigismember(&s, SIGFPE ) != 1) e(48);
if (sigismember(&s, SIGHUP ) != 1) e(49);
if (sigismember(&s, SIGILL ) != 1) e(50);
if (sigismember(&s, SIGINT ) != 1) e(51);
if (sigismember(&s, SIGKILL) != 1) e(52);
if (sigismember(&s, SIGPIPE) != 1) e(53);
if (sigismember(&s, SIGQUIT) != 1) e(54);
if (sigismember(&s, SIGSEGV) != 1) e(55);
if (sigismember(&s, SIGTERM) != 1) e(56);
if (sigismember(&s, SIGUSR1) != 1) e(57);
if (sigismember(&s, SIGUSR2) != 1) e(58);
/* Test error returns. */
if (sigaddset(&s, -1) != -1) e(59);
if (sigaddset(&s, -1) != -1) e(60);
if (sigismember(&s, -1) != -1) e(61);
if (sigaddset(&s, 10000) != -1) e(62);
if (sigaddset(&s, 10000) != -1) e(63);
if (sigismember(&s, 10000) != -1) e(64);
}
void test3b()
{
/* Test uname. */
struct utsname u; /* contains all kinds of system ids */
subtest = 2;
#if 0
errno = -2000; /* None of these calls set errno. */
if (uname(&u) != 0) e(1);
if (strcmp(u.sysname, "MINIX") != 0
&& strcmp(u.sysname, "Minix") != 0) e(2); /* only one defined */
#endif
}
void test3c()
{
/* Test getenv. Asume HOME, PATH, and LOGNAME exist (not strictly required).*/
char *p, name[SIZE];
subtest = 3;
errno = -3000; /* None of these calls set errno. */
if ( (p = getenv("HOME")) == NULL) e(1);
if (*p != '/') e(2); /* path must be absolute */
if ( (p = getenv("PATH")) == NULL) e(3);
if ( (p = getenv("LOGNAME")) == NULL) e(5);
strcpy(name, p); /* save it, since getlogin might wipe it out */
p = getlogin();
if (strcmp(p, name) != 0) e(6);
/* The following test could fail in a legal POSIX system. However, if it
* does, you deserve it to fail.
*/
if (getenv(el_weirdo) != NULL) e(7);
}
void test3d()
{
/* Test ctermid, ttyname, and isatty. */
int fd;
char *p, name[L_ctermid];
subtest = 4;
errno = -4000; /* None of these calls set errno. */
/* Test ctermid first. */
if ( (p = ctermid(name)) == NULL) e(1);
if (strcmp(p, name) != 0) e(2);
if (strncmp(p, "/dev/tty", 8) != 0) e(3); /* MINIX convention */
if ( (p = ttyname(0)) == NULL) e(4);
if (strncmp(p, "/dev/tty", 8) != 0 && strcmp(p, "/dev/console") != 0) e(5);
if ( (p = ttyname(3)) != NULL) e(6);
if (ttyname(5000) != NULL) e(7);
if ( (fd = creat("T3a", 0777)) < 0) e(8);
if (ttyname(fd) != NULL) e(9);
if (isatty(0) != 1) e(10);
if (isatty(3) != 0) e(11);
if (isatty(fd) != 0) e(12);
if (close(fd) != 0) e(13);
if (ttyname(fd) != NULL) e(14);
}
void test3e()
{
/* Test ctermid, ttyname, and isatty. */
subtest = 5;
errno = -5000; /* None of these calls set errno. */
if (sysconf(_SC_ARG_MAX) < _POSIX_ARG_MAX) e(1);
if (sysconf(_SC_CHILD_MAX) < _POSIX_CHILD_MAX) e(2);
if (sysconf(_SC_NGROUPS_MAX) < 0) e(3);
if (sysconf(_SC_OPEN_MAX) < _POSIX_OPEN_MAX) e(4);
/* The rest are MINIX specific */
if (sysconf(_SC_JOB_CONTROL) >= 0) e(5); /* no job control! */
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(4);
}
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Test aborted. Too many errors: ");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}

348
test/test30.c Normal file
View File

@@ -0,0 +1,348 @@
/* test30: creat() (p) Jan-Mark Wams. email: jms@cs.vu.nl */
/*
** Creat() should be equivalent to:
** open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
** Since we can not look in the source, we can not assume creat() is
** a mere sysnonym (= a systemcall synonym).
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.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)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test30a, (void));
_PROTOTYPE(void test30b, (void));
_PROTOTYPE(void test30c, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 30 ");
fflush(stdout);
System("rm -rf DIR_30; mkdir DIR_30");
Chdir("DIR_30");
makelongnames();
superuser = (geteuid() == 0);
umask(0000);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test30a();
if (m & 0002) test30b();
if (m & 0004) test30c();
}
quit();
}
void test30a()
{ /* Test normal operation. */
#define BUF_SIZE 1024
int fd1, fd2;
char buf[BUF_SIZE];
struct stat st, dirst;
time_t time1, time2;
int stat_loc, cnt;
subtest = 1;
System("rm -rf ../DIR_30/*");
/* Check if processes have independent new fds */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = creat("myfile", 0644)) != 3) e(1);
if (close(fd1) != 0) e(2);
exit(0);
default:
if ((fd1 = creat("myfile", 0644)) != 3) e(3);
if (close(fd1) != 0) e(4);
if (wait(&stat_loc) == -1) e(5);
if (stat_loc != 0) e(6);
}
/* Save the dir status. */
Stat(".", &dirst);
time(&time1);
while (time1 == time((time_t *)0))
;
/* Check if the file status information is updated correctly */
cnt = 0;
System("rm -rf myfile");
do {
time(&time1);
if ((fd1 = creat("myfile", 0644)) != 3) e(7);
Stat("myfile", &st);
time(&time2);
} while (time1 != time2 && cnt++ < 100);
if (cnt >= 100) e(8);
if (st.st_uid != geteuid()) e(9); /* Uid should be set. */
#if defined(NGROUPS_MAX) && NGROUPS_MAX == 0
if (st.st_gid != getegid()) e(10);
#endif /* defined(NGROUPS_MAX) && NGROUPS_MAX == 0 */
if (!S_ISREG(st.st_mode)) e(11);
if (st.st_mode & 0777 != 0644) e(12);
if (st.st_nlink != 1) e(13);
if (st.st_ctime != time1) e(14); /* All time fields should be updated */
if (st.st_atime != time1) e(15);
if (st.st_mtime != time1) e(16);
if (st.st_size != 0) e(17); /* File should be trunked. */
/* Check if c and mtime for "." is updated. */
Stat(".", &st);
if (st.st_ctime <= dirst.st_ctime) e(18);
if (st.st_mtime <= dirst.st_mtime) e(19);
/* Let's see if cread fds are write only. */
if (read(fd1, buf, 7) != -1) e(20); /* we can't read */
if (errno != EBADF) e(21); /* a write only fd */
if (write(fd1, "HELLO", 6) != 6) e(22); /* but we can write */
/* No O_APPEND flag should have been used. */
if (lseek(fd1, (off_t) 1, SEEK_SET) != 1) e(23);
if (write(fd1, "ello", 5) != 5) e(24);
Stat("myfile", &st);
if (st.st_size != 6) e(25);
if (st.st_size == 11) e(26); /* O_APPEND should make it 11. */
if (close(fd1) != 0) e(27);
/* A creat should set the file offset to 0. */
if ((fd1 = creat("myfile", 0644)) != 3) e(28);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 0) e(29);
if (close(fd1) != 0) e(30);
/* Test if file permission bits and the file ownership are unchanged. */
/* So we will see if creat() is just an open() if the file exists. */
if (superuser) {
System("echo > bar; chmod 073 bar"); /* Make bar 073 */
if (chown("bar", 1, 1) != 0) e(1137);
fd1 = creat("bar", 0777); /* knock knock */
if (fd1 == -1) e(31);
Stat("bar", &st);
if (st.st_size != (size_t) 0) e(32); /* empty file. */
if (write(fd1, "foo", 3) != 3) e(33); /* rewrite bar */
if (close(fd1) != 0) e(34);
Stat("bar", &st);
if (st.st_uid != 1) e(35);
if (st.st_gid != 1) e(36);
if ((st.st_mode & 0777) != 073) e(37); /* mode still is 077 */
if (st.st_size != (size_t) 3) e(38);
}
/* Fifo's should be openable with creat(). */
if (mkfifo("fifo", 0644) != 0) e(39);
/* Creat() should have no effect on FIFO files. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20); /* Give child 20 seconds to live. */
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(40);
if (write(fd1, "I did see Elvis.\n", 18) != 18) e(41);
if ((fd2 = creat("fifo", 0644)) != 4) e(42);
if (write(fd2, "I DID.\n", 8) != 8) e(43);
if (close(fd2) != 0) e(44);
if (close(fd1) != 0) e(45);
exit(0);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(46);
if (read(fd1, buf, 18) != 18) e(47);
if (strcmp(buf, "I did see Elvis.\n") != 0) e(48);
if (strcmp(buf, "I DID.\n") == 0) e(49);
if (read(fd1, buf, BUF_SIZE) != 8) e(50);
if (strcmp(buf, "I DID.\n") != 0) e(51);
if (close(fd1) != 0) e(52);
if (wait(&stat_loc) == -1) e(53);
if (stat_loc != 0) e(54); /* The alarm went off? */
}
/* Creat() should have no effect on directroys. */
System("mkdir dir; touch dir/f1 dir/f2 dir/f3");
if ((fd1 = creat("dir", 0644)) != -1) e(55);
if (errno != EISDIR) e(56);
close(fd1);
/* The path should contain only dirs in the prefix. */
if ((fd1 = creat("dir/f1/nono", 0644)) != -1) e(57);
if (errno != ENOTDIR) e(58);
close(fd1);
/* The path should contain only dirs in the prefix. */
if ((fd1 = creat("", 0644)) != -1) e(59);
if (errno != ENOENT) e(60);
close(fd1);
if ((fd1 = creat("dir/noso/nono", 0644)) != -1) e(61);
if (errno != ENOENT) e(62);
close(fd1);
}
void test30b()
{
int fd;
subtest = 2;
System("rm -rf ../DIR_30/*");
/* Test maximal file name length. */
if ((fd = creat(MaxName, 0777)) != 3) e(1);
if (close(fd) != 0) e(2);
MaxPath[strlen(MaxPath) - 2] = '/';
MaxPath[strlen(MaxPath) - 1] = 'a'; /* make ././.../a */
if ((fd = creat(MaxPath, 0777)) != 3) e(3);
if (close(fd) != 0) e(4);
MaxPath[strlen(MaxPath) - 1] = '/'; /* make ././.../a */
}
void test30c()
{
int fd;
subtest = 3;
System("rm -rf ../DIR_30/*");
if (!superuser) {
/* Test if creat is not usable to open files with the wrong mode */
System("> nono; chmod 177 nono");
fd = creat("nono", 0777);
if (fd != -1) e(1);
if (errno != EACCES) e(2);
}
if (mkdir("bar", 0777) != 0) e(3); /* make bar */
/* Check if no access on part of path generates the correct error. */
System("chmod 577 bar"); /* r-xrwxrwx */
if (!superuser) {
/* Normal users can't creat without write permision. */
if (creat("bar/nono", 0666) != -1) e(4);
if (errno != EACCES) e(5);
if (creat("bar/../nono", 0666) != -1) e(6);
if (errno != EACCES) e(7);
}
if (superuser) {
/* Super user can still creat stuff. */
if ((fd = creat("bar/nono", 0666)) != 3) e(8);
if (close(fd) != 0) e(9);
if (unlink("bar/nono") != 0) e(10);
}
/* Clean up bar. */
System("rm -rf bar");
/* Test ToLongName and ToLongPath */
#ifdef _POSIX_NO_TRUNC
# if _POSIX_NO_TRUNC - 0 != -1
if ((fd = creat(ToLongName, 0777)) != -1) e(11);
if (errno != ENAMETOOLONG) e(12);
close(fd); /* Just in case. */
# else
if ((fd = creat(ToLongName, 0777)) != 3) e(13);
if (close(fd) != 0) e(14);
# endif
#else
# include "error, this case requires dynamic checks and is not handled"
#endif
ToLongPath[PATH_MAX - 2] = '/';
ToLongPath[PATH_MAX - 1] = 'a';
if ((fd = creat(ToLongPath, 0777)) != -1) e(15);
if (errno != ENAMETOOLONG) e(16);
if (close(fd) != -1) e(17);
ToLongPath[PATH_MAX - 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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_30");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

275
test/test31.c Normal file
View File

@@ -0,0 +1,275 @@
/* test31: mkfifo() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.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)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test31a, (void));
_PROTOTYPE(void test31b, (void));
_PROTOTYPE(void test31c, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 31 ");
fflush(stdout);
System("rm -rf DIR_31; mkdir DIR_31");
Chdir("DIR_31");
makelongnames();
superuser = (geteuid() == 0);
umask(0000);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test31a();
if (m & 0002) test31b();
if (m & 0004) test31c();
}
quit();
}
void test31a()
{ /* Test normal operation. */
#define BUF_SIZE 1024
int fd;
char buf[BUF_SIZE];
struct stat st, dirst;
time_t time1, time2;
int stat_loc, cnt;
subtest = 1;
System("rm -rf ../DIR_31/*");
/* Check if the file status information is updated correctly */
System("rm -rf fifo");
cnt = 0;
Stat(".", &dirst);
time(&time1);
while (time1 == time((time_t *)0))
;
do {
time(&time1);
if (mkfifo("fifo", 0644) != 0) e(1);
Stat("fifo", &st);
time(&time2);
} while (time1 != time2 && cnt++ < 100);
if (cnt >= 100) e(2);
if (st.st_uid != geteuid()) e(3); /* Uid should be set. */
#if defined(NGROUPS_MAX) && NGROUPS_MAX == 0
if (st.st_gid != getegid()) e(4);
#endif /* defined(NGROUPS_MAX) && NGROUPS_MAX == 0 */
if (!S_ISFIFO(st.st_mode)) e(5);
if (st.st_mode & 0777 != 0644) e(6);
if (st.st_nlink != 1) e(7);
if (st.st_ctime != time1) e(8);
if (st.st_atime != time1) e(9);
if (st.st_mtime != time1) e(10);
if (st.st_size != 0) e(11); /* File should be empty. */
/* Check if status for "." is updated. */
Stat(".", &st);
if (st.st_ctime <= dirst.st_ctime) e(12);
if (st.st_mtime <= dirst.st_mtime) e(13);
/* Basic checking if a fifo file created with mkfifo() is a pipe. */
alarm(10); /* in case fifo hangs */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
if ((fd = open("fifo", O_RDONLY)) != 3) e(14);
if (read(fd, buf, BUF_SIZE) != 7) e(15);
if (strcmp(buf, "banana") != 0) e(16);
if (close(fd) != 0) e(17);
if ((fd = open("fifo", O_WRONLY)) != 3) e(18);
if (write(fd, "thanks", 7) != 7) e(19);
if (close(fd) != 0) e(20);
exit(0);
default:
if ((fd = open("fifo", O_WRONLY)) != 3) e(21);
if (write(fd, "banana", 7) != 7) e(22);
if (close(fd) != 0) e(23);
if ((fd = open("fifo", O_RDONLY)) != 3) e(24);
if (read(fd, buf, BUF_SIZE) != 7) e(25);
if (strcmp(buf, "thanks") != 0) e(26);
if (close(fd) != 0) e(27);
wait(&stat_loc);
if (stat_loc != 0) e(28); /* Alarm? */
}
alarm(0);
}
void test31b()
{
subtest = 2;
System("rm -rf ../DIR_31/*");
/* Test maximal file name length. */
if (mkfifo(MaxName, 0777) != 0) e(1);
if (unlink(MaxName) != 0) e(2);
MaxPath[strlen(MaxPath) - 2] = '/';
MaxPath[strlen(MaxPath) - 1] = 'a'; /* make ././.../a */
if (mkfifo(MaxPath, 0777) != 0) e(3);
if (unlink(MaxPath) != 0) e(4);
MaxPath[strlen(MaxPath) - 1] = '/'; /* make ././.../a */
}
void test31c()
{
subtest = 3;
System("rm -rf ../DIR_31/*");
/* Check if mkfifo() removes, files, fifos, dirs. */
if (mkfifo("fifo", 0777) != 0) e(1);
System("mkdir dir; > file");
if (mkfifo("fifo", 0777) != -1) e(2);
if (errno != EEXIST) e(3);
if (mkfifo("dir", 0777) != -1) e(4);
if (errno != EEXIST) e(5);
if (mkfifo("file", 0777) != -1) e(6);
if (errno != EEXIST) e(7);
/* Test empty path. */
if (mkfifo("", 0777) != -1) e(8);
if (errno != ENOENT) e(9);
if (mkfifo("/tmp/noway/out", 0777) != -1) e(10);
if (errno != ENOENT) e(11);
/* Test if path prefix is a directory. */
if (mkfifo("/etc/passwd/nono", 0777) != -1) e(12);
if (errno != ENOTDIR) e(13);
mkdir("bar", 0777); /* make bar */
/* Check if no access on part of path generates the correct error. */
System("chmod 577 bar"); /* r-xrwxrwx */
if (!superuser) {
if (mkfifo("bar/nono", 0666) != -1) e(14);
if (errno != EACCES) e(15);
}
if (superuser) {
if (mkfifo("bar/nono", 0666) != 0) e(14);
if (unlink("bar/nono") != 0) e(666);
}
System("chmod 677 bar"); /* rw-rwxrwx */
if (!superuser) {
if (mkfifo("bar/../nono", 0666) != -1) e(16);
if (errno != EACCES) e(17);
}
if (unlink("nono") != -1) e(18);
/* Clean up bar. */
System("rm -rf bar");
/* Test ToLongName and ToLongPath */
#ifdef _POSIX_NO_TRUNC
# if _POSIX_NO_TRUNC - 0 != -1
if (mkfifo(ToLongName, 0777) != -1) e(19);
if (errno != ENAMETOOLONG) e(20);
# else
if (mkfifo(ToLongName, 0777) != 0) e(21);
# endif
#else
# include "error, this case requires dynamic checks and is not handled"
#endif
ToLongPath[PATH_MAX - 2] = '/';
ToLongPath[PATH_MAX - 1] = 'a';
if (mkfifo(ToLongPath, 0777) != -1) e(22);
if (errno != ENAMETOOLONG) e(23);
ToLongPath[PATH_MAX - 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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_31");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

370
test/test32.c Normal file
View File

@@ -0,0 +1,370 @@
/* test32: rename() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 2
#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 Creat(f) if (close(creat(f,0777))!=0) printf("Can't creat %s\n",f)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test32a, (void));
_PROTOTYPE(void test32b, (void));
_PROTOTYPE(void test32c, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 32 ");
fflush(stdout);
System("rm -rf DIR_32; mkdir DIR_32");
Chdir("DIR_32");
makelongnames();
superuser = (geteuid() == 0);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test32a();
if (m & 0002) test32b();
if (m & 0004) test32c();
}
quit();
}
#define BUF_SIZE 1024
void test32a()
{ /* Test normal operation. */
struct stat st1, st2;
int fd1, fd2;
time_t time1, time2, time3;
char buf[BUF_SIZE];
subtest = 1;
System("rm -rf ../DIR_32/*");
/* Test normal file renamal. */
System("echo haha > old");
Stat("old", &st1);
if (rename("old", "new") != 0) e(1);
Stat("new", &st2);
/* The status of new should be the same as old. */
if (st1.st_dev != st2.st_dev) e(2);
if (st1.st_ino != st2.st_ino) e(3);
if (st1.st_mode != st2.st_mode) e(4);
if (st1.st_nlink != st2.st_nlink) e(5);
if (st1.st_uid != st2.st_uid) e(6);
if (st1.st_gid != st2.st_gid) e(7);
if (st1.st_rdev != st2.st_rdev) e(8);
if (st1.st_size != st2.st_size) e(9);
if (st1.st_atime != st2.st_atime) e(10);
if (st1.st_mtime != st2.st_mtime) e(11);
if (st1.st_ctime != st2.st_ctime) e(12);
/* If new exists, it should be removed. */
System("ln new new2");
System("echo foobar > old");
Stat("old", &st1);
if (rename("old", "new") != 0) e(13);
Stat("new", &st2);
/* The status of new should be the same as old. */
if (st1.st_dev != st2.st_dev) e(14);
if (st1.st_ino != st2.st_ino) e(15);
if (st1.st_mode != st2.st_mode) e(16);
if (st1.st_nlink != st2.st_nlink) e(17);
if (st1.st_uid != st2.st_uid) e(18);
if (st1.st_gid != st2.st_gid) e(19);
if (st1.st_rdev != st2.st_rdev) e(20);
if (st1.st_size != st2.st_size) e(21);
if (st1.st_atime != st2.st_atime) e(22);
if (st1.st_mtime != st2.st_mtime) e(23);
if (st1.st_ctime != st2.st_ctime) e(24);
/* The link count on new2 should be one since the old new is removed. */
Stat("new2", &st1);
if (st1.st_nlink != 1) e(25);
/* Check if status for "." is updated. */
System("> OLD");
Stat(".", &st1);
time(&time1);
while (time1 == time((time_t *)0))
;
time(&time2);
rename("OLD", "NEW");
Stat(".", &st2);
time(&time3);
while (time3 == time((time_t *)0))
;
time(&time3);
if (st1.st_ctime >= st2.st_ctime) e(26);
if (st1.st_mtime >= st2.st_mtime) e(27);
if (st1.st_ctime > time1) e(28);
if (st1.st_mtime > time1) e(29);
if (st1.st_ctime >= time2) e(30);
if (st1.st_mtime >= time2) e(31);
if (st2.st_ctime < time2) e(32);
if (st2.st_mtime < time2) e(33);
if (st2.st_ctime >= time3) e(34);
if (st2.st_mtime >= time3) e(35);
/* If the new file is removed while it's open it should still be
* readable. */
System("rm -rf new NEW old OLD");
if ((fd1 = creat("new", 0644)) != 3) e(36);
if (write(fd1, "Hi there! I am Sammy the string", 33) != 33) e(37);
if (close(fd1) != 0) e(38);
if ((fd1 = creat("old", 0644)) != 3) e(39);
if (write(fd1, "I need a new name", 18) != 18) e(40);
if (close(fd1) != 0) e(41);
if ((fd1 = open("new", O_RDONLY)) != 3) e(42);
if ((fd2 = open("new", O_RDONLY)) != 4) e(43);
if (rename("old", "new") != 0) e(44);
if (stat("old", &st1) == 0) e(45);
if (close(fd1) != 0) e(46);
if ((fd1 = open("new", O_RDONLY)) != 3) e(47);
if (read(fd2, buf, BUF_SIZE) != 33) e(48);
if (strcmp(buf, "Hi there! I am Sammy the string") != 0) e(49);
if (read(fd1, buf, BUF_SIZE) != 18) e(50);
if (strcmp(buf, "I need a new name") != 0) e(51);
if (close(fd1) != 0) e(52);
if (close(fd2) != 0) e(53);
}
void test32b()
{
char MaxPath2[PATH_MAX]; /* Same for path */
char MaxName2[NAME_MAX + 1]; /* Name of maximum length */
int fd, i;
int stat_loc;
struct stat st;
subtest = 2;
System("rm -rf ../DIR_32/*");
/* Test maximal file name length. */
if ((fd = creat(MaxName, 0777)) != 3) e(1);
if (close(fd) != 0) e(2);
strcpy(MaxName2, MaxName);
MaxName2[strlen(MaxName2) - 1] ^= 1;
if (rename(MaxName, MaxName2) != 0) e(3);
if (rename(MaxName2, MaxName) != 0) e(4);
MaxName2[strlen(MaxName2) - 1] ^= 2;
if (rename(MaxName, MaxName2) != 0) e(5);
MaxPath[strlen(MaxPath) - 2] = '/';
MaxPath[strlen(MaxPath) - 1] = 'a'; /* make ././.../a */
if ((fd = creat(MaxPath, 0777)) != 3) e(6);
if (close(fd) != 0) e(7);
strcpy(MaxPath2, MaxPath);
MaxPath2[strlen(MaxPath2) - 1] ^= 1;
if (rename(MaxPath, MaxPath2) != 0) e(8);
if (rename(MaxPath2, MaxPath) != 0) e(9);
MaxPath2[strlen(MaxPath2) - 1] ^= 2;
if (rename(MaxPath, MaxPath2) != 0) e(10);
MaxPath[strlen(MaxPath) - 1] = '/'; /* make ././.../a */
/* Test if linked files are renamable. */
System("> foo; ln foo bar");
if (rename("foo", "bar") != 0) e(11);
if (rename("bar", "foo") != 0) e(12);
System("ln foo foobar");
if (rename("foo", "foobar") != 0) e(13);
if (rename("bar", "foobar") != 0) e(14);
/* Since the same files have the same links.... */
if (rename("bar", "bar") != 0) e(15);
if (rename("foo", "foo") != 0) e(16);
if (rename("foobar", "foobar") != 0) e(17);
/* In ``rename(old, new)'' with new existing, there is always an new
* entry. */
for (i = 0; i < 5; i++) {
System("echo old > old");
System("echo news > new");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
sleep(1);
rename("old", "new");
exit(0);
default:
while (stat("old", &st) != 0)
if (stat("new", &st) != 0) e(18);
wait(&stat_loc);
if (stat_loc != 0) e(19); /* Alarm? */
}
}
}
void test32c()
{ /* Test behavior under error contitions. */
struct stat st1;
int stat_loc;
subtest = 3;
System("rm -rf ../DIR_32/*");
/* Test if we have access. */
system("chmod 777 noacc nowrite > /dev/null 2>/dev/null");
system("rm -rf noacc nowrite");
System("mkdir noacc nowrite");
System("> noacc/file");
System("> nowrite/file");
System("> file");
System("chmod 677 noacc");
System("chmod 577 nowrite");
if (!superuser) {
if (rename("noacc/file", "nono") != -1) e(1);
if (errno != EACCES) e(2);
if (rename("nowrite/file", "nono") != -1) e(3);
if (errno != EACCES) e(4);
if (rename("file", "noacc/file") != -1) e(5);
if (errno != EACCES) e(6);
if (rename("file", "nowrite/file") != -1) e(7);
if (errno != EACCES) e(8);
}
if (superuser) {
/* Super user heeft access. */
if (rename("noacc/file", "noacc/yes") != 0) e(9);
if (rename("nowrite/file", "nowrite/yes") != 0) e(10);
if (rename("file", "yes") != 0) e(11);
if (rename("noacc/yes", "noacc/file") != 0) e(12);
if (rename("nowrite/yes", "nowrite/file") != 0) e(13);
if (rename("yes", "file") != 0) e(14);
}
System("chmod 777 noacc nowrite");
/* If rmdir() doesn't remove a directory, rename() shouldn't eighter. */
System("mkdir newdir olddir");
System("rm -rf /tmp/sema.11[ab]");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
/* Child A. */
alarm(20);
if (chdir("newdir") != 0) e(15);
Creat("/tmp/sema.11a");
while (stat("/tmp/sema.11a", &st1) == -1) sleep(1);
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(16); /* Alarm? */
}
/* Child B. */
if (chdir("olddir") != 0) e(17);
Creat("/tmp/sema.11b");
while (stat("/tmp/sema.11b", &st1) == -1) sleep(1);
exit(0);
default:
/* Wait for child A. It will keep ``newdir'' bussy. */
while (stat("/tmp/sema.11a", &st1) == -1) sleep(1);
if (rmdir("newdir") == -1) {
if (rename("olddir", "newdir") != -1) e(18);
if (errno != EBUSY) e(19);
}
(void) unlink("/tmp/sema.11a");
/* Wait for child B. It will keep ``olddir'' bussy. */
while (stat("/tmp/sema.11b", &st1) == -1) sleep(1);
if (rmdir("olddir") == -1) {
if (rename("olddir", "newdir") != -1) e(20);
if (errno != EBUSY) e(21);
}
(void) unlink("/tmp/sema.11b");
wait(&stat_loc);
if (stat_loc != 0) e(22); /* Alarm? */
}
}
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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_32");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

658
test/test33.c Normal file
View File

@@ -0,0 +1,658 @@
/* test33: access() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <stdio.h>
#define MAX_ERROR 1
#define ITERATIONS 2
#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 Chmod(a,b) if (chmod(a,b) != 0) printf("Can't chmod %s\n", a)
#define Mkfifo(f) if (mkfifo(f,0777)!=0) printf("Can't make fifo %s\n", f)
int errct = 0;
int subtest = 1;
int superuser; /* nonzero if uid == euid (euid == 0 always) */
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test33a, (void));
_PROTOTYPE(void test33b, (void));
_PROTOTYPE(void test33c, (void));
_PROTOTYPE(void test33d, (void));
_PROTOTYPE(void test_access, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 33 ");
fflush(stdout);
if (geteuid() != 0) {
printf("must be setuid root; test aborted\n");
exit(1);
}
if (getuid() == 0) {
printf("must be setuid root logged in as someone else; test aborted\n");
exit(1);
}
umask(0000);
System("rm -rf DIR_33; mkdir DIR_33");
Chdir("DIR_33");
makelongnames();
superuser = (getuid() == 0);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test33a();
if (m & 0002) test33b();
if (m & 0004) test33c();
if (m & 0010) test33d();
}
quit();
}
void test33a()
{ /* Test normal operation. */
int stat_loc; /* For the wait(&stat_loc) call. */
subtest = 1;
System("rm -rf ../DIR_33/*");
/* To test normal access first make some files for real uid. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
setuid(getuid()); /* (Re)set the effective ids to the
* real ids. */
setgid(getgid());
System("> rwx; chmod 700 rwx");
System("> rw_; chmod 600 rw_");
System("> r_x; chmod 500 r_x");
System("> r__; chmod 400 r__");
System("> _wx; chmod 300 _wx");
System("> _w_; chmod 200 _w_");
System("> __x; chmod 100 __x");
System("> ___; chmod 000 ___");
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(1);/* Alarm? */
}
test_access();
/* Let's test access() on directorys. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
setuid(getuid()); /* (Re)set the effective ids to the
* real ids. */
setgid(getgid());
System("rm -rf [_r][_w][_x]");
System("mkdir rwx; chmod 700 rwx");
System("mkdir rw_; chmod 600 rw_");
System("mkdir r_x; chmod 500 r_x");
System("mkdir r__; chmod 400 r__");
System("mkdir _wx; chmod 300 _wx");
System("mkdir _w_; chmod 200 _w_");
System("mkdir __x; chmod 100 __x");
System("mkdir ___; chmod 000 ___");
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(2);/* Alarm? */
}
test_access();
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
setuid(getuid()); /* (Re)set the effective ids to the
* real ids. */
setgid(getgid());
System("rmdir [_r][_w][_x]");
Mkfifo("rwx");
System("chmod 700 rwx");
Mkfifo("rw_");
System("chmod 600 rw_");
Mkfifo("r_x");
System("chmod 500 r_x");
Mkfifo("r__");
System("chmod 400 r__");
Mkfifo("_wx");
System("chmod 300 _wx");
Mkfifo("_w_");
System("chmod 200 _w_");
Mkfifo("__x");
System("chmod 100 __x");
Mkfifo("___");
System("chmod 000 ___");
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(3);/* Alarm? */
}
test_access();
/* Remove all the fifos. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
setuid(getuid());
setgid(getgid());
System("rm -rf [_r][_w][_x]");
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(4);/* Alarm? */
}
}
void test33b()
{
int stat_loc; /* For the wait(&stat_loc) call. */
subtest = 2;
System("rm -rf ../DIR_33/*");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
/* (Re)set the effective ids to the real ids. */
setuid(getuid());
setgid(getgid());
System("> ______rwx; chmod 007 ______rwx");
System("> ________x; chmod 001 ________x");
System("> _________; chmod 000 _________");
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(1);/* Alarm? */
}
/* If we are superuser, we have access to all. */
/* Well, almost, execution access might need at least one X bit. */
if (superuser) {
if (access("_________", R_OK) != 0) e(2);
if (access("_________", W_OK) != 0) e(3);
if (access("________x", R_OK) != 0) e(4);
if (access("________x", W_OK) != 0) e(5);
if (access("________x", X_OK) != 0) e(6);
if (access("______rwx", R_OK) != 0) e(7);
if (access("______rwx", W_OK) != 0) e(8);
if (access("______rwx", X_OK) != 0) e(9);
}
if (!superuser) {
if (access("_________", R_OK) != -1) e(10);
if (errno != EACCES) e(11);
if (access("_________", W_OK) != -1) e(12);
if (errno != EACCES) e(13);
if (access("_________", X_OK) != -1) e(14);
if (errno != EACCES) e(15);
if (access("________x", R_OK) != -1) e(16);
if (errno != EACCES) e(17);
if (access("________x", W_OK) != -1) e(18);
if (errno != EACCES) e(19);
if (access("________x", X_OK) != -1) e(20);
if (errno != EACCES) e(21);
if (access("______rwx", R_OK) != -1) e(22);
if (errno != EACCES) e(23);
if (access("______rwx", W_OK) != -1) e(24);
if (errno != EACCES) e(25);
if (access("______rwx", X_OK) != -1) e(26);
if (errno != EACCES) e(27);
}
/* If the real uid != effective uid. */
if (!superuser) {
System("rm -rf [_r][_w][_x]");
System("> rwx");
Chmod("rwx", 0700);
System("> rw_");
Chmod("rw_", 0600);
System("> r_x");
Chmod("r_x", 0500);
System("> r__");
Chmod("r__", 0400);
System("> _wx");
Chmod("_wx", 0300);
System("> _w_");
Chmod("_w_", 0200);
System("> __x");
Chmod("__x", 0100);
System("> ___");
Chmod("___", 0000);
if (access("rwx", F_OK) != 0) e(28);
if (access("rwx", R_OK) != -1) e(29);
if (errno != EACCES) e(30);
if (access("rwx", W_OK) != -1) e(31);
if (errno != EACCES) e(32);
if (access("rwx", X_OK) != -1) e(33);
if (errno != EACCES) e(34);
if (access("rw_", F_OK) != 0) e(35);
if (access("rw_", R_OK) != -1) e(36);
if (errno != EACCES) e(37);
if (access("rw_", W_OK) != -1) e(38);
if (errno != EACCES) e(39);
if (access("rw_", X_OK) != -1) e(40);
if (errno != EACCES) e(41);
if (access("r_x", F_OK) != 0) e(42);
if (access("r_x", R_OK) != -1) e(43);
if (errno != EACCES) e(44);
if (access("r_x", W_OK) != -1) e(45);
if (errno != EACCES) e(46);
if (access("r_x", X_OK) != -1) e(47);
if (errno != EACCES) e(48);
if (access("r__", F_OK) != 0) e(49);
if (access("r__", R_OK) != -1) e(50);
if (errno != EACCES) e(51);
if (access("r__", W_OK) != -1) e(52);
if (errno != EACCES) e(53);
if (access("r__", X_OK) != -1) e(54);
if (errno != EACCES) e(55);
if (access("_wx", F_OK) != 0) e(56);
if (access("_wx", R_OK) != -1) e(57);
if (errno != EACCES) e(58);
if (access("_wx", W_OK) != -1) e(59);
if (errno != EACCES) e(60);
if (access("_wx", X_OK) != -1) e(61);
if (errno != EACCES) e(62);
if (access("_w_", F_OK) != 0) e(63);
if (access("_w_", R_OK) != -1) e(64);
if (errno != EACCES) e(65);
if (access("_w_", W_OK) != -1) e(66);
if (errno != EACCES) e(67);
if (access("_w_", X_OK) != -1) e(68);
if (errno != EACCES) e(69);
if (access("__x", F_OK) != 0) e(70);
if (access("__x", R_OK) != -1) e(71);
if (errno != EACCES) e(72);
if (access("__x", W_OK) != -1) e(73);
if (errno != EACCES) e(74);
if (access("__x", X_OK) != -1) e(75);
if (errno != EACCES) e(76);
if (access("___", F_OK) != 0) e(77);
if (access("___", R_OK) != -1) e(78);
if (errno != EACCES) e(79);
if (access("___", W_OK) != -1) e(80);
if (errno != EACCES) e(81);
if (access("___", X_OK) != -1) e(82);
if (errno != EACCES) e(83);
System("rm -rf [_r][_w][_x]");
}
}
void test33c()
{ /* Test errors returned. */
int i;
subtest = 3;
System("rm -rf ../DIR_33/*");
/* Test what access() does with non existing files. */
System("rm -rf nonexist");
if (access("noexist", F_OK) != -1) e(1);
if (errno != ENOENT) e(2);
if (access("noexist", R_OK) != -1) e(3);
if (errno != ENOENT) e(4);
if (access("noexist", W_OK) != -1) e(5);
if (errno != ENOENT) e(6);
if (access("noexist", X_OK) != -1) e(7);
if (errno != ENOENT) e(8);
if (access("noexist", R_OK | W_OK) != -1) e(9);
if (errno != ENOENT) e(10);
if (access("noexist", R_OK | X_OK) != -1) e(11);
if (errno != ENOENT) e(12);
if (access("noexist", W_OK | X_OK) != -1) e(13);
if (errno != ENOENT) e(14);
if (access("noexist", R_OK | W_OK | X_OK) != -1) e(15);
if (errno != ENOENT) e(16);
/* Test access on a nonsearchable path. */
if (mkdir("nosearch", 0777) != 0) e(1000);
if ( (i = creat("nosearch/file", 0666)) < 0) e(1001);
if (close(i) < 0) e(1002);
if ( (i = creat("file", 0666) < 0)) e(1003);
if (close(i) < 0) e(1004);
if (chmod("nosearch/file", 05777) < 0) e(1005);
if (chmod("file", 05777) < 0) e(1006);
if (chmod("nosearch", 0677) != 0) e(1007);
if (access("nosearch/file", F_OK) != 0) e(17);
/* Test ToLongName and ToLongPath */
#ifdef _POSIX_NO_TRUNC
# if _POSIX_NO_TRUNC - 0 != -1
if (access(ToLongName, F_OK) != -1) e(23);
if (errno != ENAMETOOLONG) e(24);
# else
if (close(creat(ToLongName, 0777)) != 0) e(25);
if (access(ToLongName, F_OK) != 0) e(26);
# endif
#else
# include "error, this case requires dynamic checks and is not handled"
#endif
ToLongPath[PATH_MAX - 2] = '/';
ToLongPath[PATH_MAX - 1] = 'a';
if (access(ToLongPath, F_OK) != -1) e(27);
if (errno != ENAMETOOLONG) e(28);
ToLongPath[PATH_MAX - 1] = '/';
/* Test empty strings. */
if (access("", F_OK) != -1) e(29);
if (errno != ENOENT) e(30);
System("rm -rf idonotexist");
if (access("idonotexist", F_OK) != -1) e(31);
if (errno != ENOENT) e(32);
/* Test non directorys in prefix of path. */
if (access("/etc/passwd/dir/foo", F_OK) != -1) e(33);
if (errno != ENOTDIR) e(34);
System("rm -rf nodir; > nodir");
if (access("nodir/foo", F_OK) != -1) e(35);
if (errno != ENOTDIR) e(36);
/* Test if invalid amode arguments are signaled. */
System("> allmod");
Chmod("allmod", 05777);
for (i = -1025; i < 1025; i++) {
if ((mode_t) i != F_OK && ((mode_t) i & ~(R_OK | W_OK | X_OK)) != 0) {
if (access("allmod", (mode_t) i) != -1) e(37);
if (errno != EINVAL) e(38);
} else
if (access("allmod", (mode_t) i) != 0) e(39);
}
}
void test33d()
{ /* Test access() flags. */
#define EXCLUDE(a,b) (((a)^(b)) == ((a)|(b)))
subtest = 4;
System("rm -rf ../DIR_33/*");
/* The test are rather strong, stronger that POSIX specifies. */
/* The should be OR able, this test tests if all the 1 bits */
/* Are in diferent places. This should be what one wants. */
if (!EXCLUDE(R_OK, W_OK | X_OK)) e(1);
if (!EXCLUDE(W_OK, R_OK | X_OK)) e(2);
if (!EXCLUDE(X_OK, R_OK | W_OK)) e(3);
if (F_OK == R_OK) e(4);
if (F_OK == W_OK) e(5);
if (F_OK == X_OK) e(6);
if (F_OK == (R_OK | W_OK)) e(7);
if (F_OK == (W_OK | X_OK)) e(8);
if (F_OK == (R_OK | X_OK)) e(9);
if (F_OK == (R_OK | W_OK | X_OK)) e(10);
}
void test_access()
{ /* Test all [_r][_w][_x] files. */
if (!superuser) {
/* Test normal access. */
if (access("rwx", F_OK) != 0) e(11);
if (access("rwx", R_OK) != 0) e(12);
if (access("rwx", W_OK) != 0) e(13);
if (access("rwx", X_OK) != 0) e(14);
if (access("rwx", R_OK | W_OK) != 0) e(15);
if (access("rwx", R_OK | X_OK) != 0) e(16);
if (access("rwx", W_OK | X_OK) != 0) e(17);
if (access("rwx", R_OK | W_OK | X_OK) != 0) e(18);
if (access("rw_", F_OK) != 0) e(19);
if (access("rw_", R_OK) != 0) e(20);
if (access("rw_", W_OK) != 0) e(21);
if (access("rw_", X_OK) != -1) e(22);
if (errno != EACCES) e(23);
if (access("rw_", R_OK | W_OK) != 0) e(24);
if (access("rw_", R_OK | X_OK) != -1) e(25);
if (errno != EACCES) e(26);
if (access("rw_", W_OK | X_OK) != -1) e(27);
if (errno != EACCES) e(28);
if (access("rw_", R_OK | W_OK | X_OK) != -1) e(29);
if (errno != EACCES) e(30);
if (access("r_x", F_OK) != 0) e(31);
if (access("r_x", R_OK) != 0) e(32);
if (access("r_x", W_OK) != -1) e(33);
if (errno != EACCES) e(34);
if (access("r_x", X_OK) != 0) e(35);
if (access("r_x", R_OK | W_OK) != -1) e(36);
if (errno != EACCES) e(37);
if (access("r_x", R_OK | X_OK) != 0) e(38);
if (access("r_x", W_OK | X_OK) != -1) e(39);
if (errno != EACCES) e(40);
if (access("r_x", R_OK | W_OK | X_OK) != -1) e(41);
if (errno != EACCES) e(42);
if (access("r__", F_OK) != 0) e(43);
if (access("r__", R_OK) != 0) e(44);
if (access("r__", W_OK) != -1) e(45);
if (errno != EACCES) e(46);
if (access("r__", X_OK) != -1) e(47);
if (errno != EACCES) e(48);
if (access("r__", R_OK | W_OK) != -1) e(49);
if (errno != EACCES) e(50);
if (access("r__", R_OK | X_OK) != -1) e(51);
if (errno != EACCES) e(52);
if (access("r__", W_OK | X_OK) != -1) e(53);
if (errno != EACCES) e(54);
if (access("r__", R_OK | W_OK | X_OK) != -1) e(55);
if (errno != EACCES) e(56);
if (access("_wx", F_OK) != 0) e(57);
if (access("_wx", R_OK) != -1) e(58);
if (errno != EACCES) e(59);
if (access("_wx", W_OK) != 0) e(60);
if (access("_wx", X_OK) != 0) e(61);
if (access("_wx", R_OK | W_OK) != -1) e(62);
if (errno != EACCES) e(63);
if (access("_wx", R_OK | X_OK) != -1) e(64);
if (errno != EACCES) e(65);
if (access("_wx", W_OK | X_OK) != 0) e(66);
if (access("_wx", R_OK | W_OK | X_OK) != -1) e(67);
if (errno != EACCES) e(68);
if (access("_w_", F_OK) != 0) e(69);
if (access("_w_", R_OK) != -1) e(70);
if (errno != EACCES) e(71);
if (access("_w_", W_OK) != 0) e(72);
if (access("_w_", X_OK) != -1) e(73);
if (errno != EACCES) e(74);
if (access("_w_", R_OK | W_OK) != -1) e(75);
if (errno != EACCES) e(76);
if (access("_w_", R_OK | X_OK) != -1) e(77);
if (errno != EACCES) e(78);
if (access("_w_", W_OK | X_OK) != -1) e(79);
if (errno != EACCES) e(80);
if (access("_w_", R_OK | W_OK | X_OK) != -1) e(81);
if (errno != EACCES) e(82);
if (access("__x", F_OK) != 0) e(83);
if (access("__x", R_OK) != -1) e(84);
if (errno != EACCES) e(85);
if (access("__x", W_OK) != -1) e(86);
if (errno != EACCES) e(87);
if (access("__x", X_OK) != 0) e(88);
if (access("__x", R_OK | W_OK) != -1) e(89);
if (errno != EACCES) e(90);
if (access("__x", R_OK | X_OK) != -1) e(91);
if (errno != EACCES) e(92);
if (access("__x", W_OK | X_OK) != -1) e(93);
if (errno != EACCES) e(94);
if (access("__x", R_OK | W_OK | X_OK) != -1) e(95);
if (errno != EACCES) e(96);
if (access("___", F_OK) != 0) e(97);
if (access("___", R_OK) != -1) e(98);
if (errno != EACCES) e(99);
if (access("___", W_OK) != -1) e(100);
if (errno != EACCES) e(101);
if (access("___", X_OK) != -1) e(102);
if (errno != EACCES) e(103);
if (access("___", R_OK | W_OK) != -1) e(104);
if (errno != EACCES) e(105);
if (access("___", R_OK | X_OK) != -1) e(106);
if (errno != EACCES) e(107);
if (access("___", W_OK | X_OK) != -1) e(108);
if (errno != EACCES) e(109);
if (access("___", R_OK | W_OK | X_OK) != -1) e(110);
if (errno != EACCES) e(111);
}
if (superuser) {
/* Test root access don't test X_OK on [_r][_w]_ files. */
if (access("rwx", F_OK) != 0) e(112);
if (access("rwx", R_OK) != 0) e(113);
if (access("rwx", W_OK) != 0) e(114);
if (access("rwx", X_OK) != 0) e(115);
if (access("rwx", R_OK | W_OK) != 0) e(116);
if (access("rwx", R_OK | X_OK) != 0) e(117);
if (access("rwx", W_OK | X_OK) != 0) e(118);
if (access("rwx", R_OK | W_OK | X_OK) != 0) e(119);
if (access("rw_", F_OK) != 0) e(120);
if (access("rw_", R_OK) != 0) e(121);
if (access("rw_", W_OK) != 0) e(122);
if (access("rw_", R_OK | W_OK) != 0) e(123);
if (access("r_x", F_OK) != 0) e(124);
if (access("r_x", R_OK) != 0) e(125);
if (access("r_x", W_OK) != 0) e(126);
if (access("r_x", X_OK) != 0) e(127);
if (access("r_x", R_OK | W_OK) != 0) e(128);
if (access("r_x", R_OK | X_OK) != 0) e(129);
if (access("r_x", W_OK | X_OK) != 0) e(130);
if (access("r_x", R_OK | W_OK | X_OK) != 0) e(131);
if (access("r__", F_OK) != 0) e(132);
if (access("r__", R_OK) != 0) e(133);
if (access("r__", W_OK) != 0) e(134);
if (access("r__", R_OK | W_OK) != 0) e(135);
if (access("_wx", F_OK) != 0) e(136);
if (access("_wx", R_OK) != 0) e(137);
if (access("_wx", W_OK) != 0) e(138);
if (access("_wx", X_OK) != 0) e(139);
if (access("_wx", R_OK | W_OK) != 0) e(140);
if (access("_wx", R_OK | X_OK) != 0) e(141);
if (access("_wx", W_OK | X_OK) != 0) e(142);
if (access("_wx", R_OK | W_OK | X_OK) != 0) e(143);
if (access("_w_", F_OK) != 0) e(144);
if (access("_w_", R_OK) != 0) e(145);
if (access("_w_", W_OK) != 0) e(146);
if (access("_w_", R_OK | W_OK) != 0) e(147);
if (access("__x", F_OK) != 0) e(148);
if (access("__x", R_OK) != 0) e(149);
if (access("__x", W_OK) != 0) e(150);
if (access("__x", X_OK) != 0) e(151);
if (access("__x", R_OK | W_OK) != 0) e(152);
if (access("__x", R_OK | X_OK) != 0) e(153);
if (access("__x", W_OK | X_OK) != 0) e(154);
if (access("__x", R_OK | W_OK | X_OK) != 0) e(155);
if (access("___", F_OK) != 0) e(156);
if (access("___", R_OK) != 0) e(157);
if (access("___", W_OK) != 0) e(158);
if (access("___", R_OK | W_OK) != 0) e(159);
}
}
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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_33");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

668
test/test34.c Normal file
View File

@@ -0,0 +1,668 @@
/* test34: chmod() chown() Author: Jan-Mark Wams (jms@cs.vu.nl) */
/* There is a problem getting valid uids and gids, so we use the passwd
** file (ie. /etc/passwd). I don't like this, but I see no other way.
** The read-only-device-error (EROFS) is not checked!
** Supplementary group IDs are ignored.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 4
#define N 100
#define ALL_RWXB (S_IRWXU | S_IRWXG | S_IRWXO)
#define ALL_SETB (S_ISUID | S_ISGID)
#define ALL_BITS (ALL_RWXB | ALL_SETB)
#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)
#define Mkdir(f) if (mkdir(f,0777)!=0) printf("Can't make dir %s\n", f)
#define Creat(f) if (close(creat(f,0777))!=0) printf("Can't creat %s\n",f)
/* This program uses /etc/passwd and assumes things about it's contents. */
#define PASSWD_FILE "/etc/passwd"
int errct = 0;
int subtest = 1;
int superuser;
int I_can_chown;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char NameTooLong[NAME_MAX + 2]; /* Name of maximum +1 length */
char PathTooLong[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test34a, (void));
_PROTOTYPE(void test34b, (void));
_PROTOTYPE(void test34c, (void));
_PROTOTYPE(mode_t mode, (char *file_name));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
_PROTOTYPE(void getids, (uid_t * uid, gid_t * gid));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 34 ");
fflush(stdout);
(void) system("chmod 777 DIR_34/* > /dev/null 2> /dev/null");
System("rm -rf DIR_34; mkdir DIR_34");
if (chdir("DIR_34") != 0) {
fprintf(stderr, "Can't go to DIR_34\n");
system("rm -rf DIR_34");
exit(1);
}
makelongnames();
superuser = (geteuid() == (uid_t) 0);
#ifdef _POSIX_CHOWN_RESTRICTED
I_can_chown = superuser;
#else
I_can_chown = 1;
#endif
umask(0000);
for (i = 1; i < ITERATIONS; i++) {
if (m & 0001) test34a();
if (m & 0002) test34b();
if (m & 0004) test34c();
}
quit();
}
void test34a()
{ /* Test normal operation. */
time_t time1, time2;
mode_t mod;
struct stat st1, st2;
int cnt;
uid_t uid, uid2;
gid_t gid, gid2;
int stat_loc;
subtest = 1;
/* Make scratch file. */
Creat("foo");
for (mod = 0; mod <= ALL_BITS; mod++) {
if ((mod & ALL_BITS) != mod) /* If not a valid mod next. */
continue;
Stat("foo", &st1);
if (time(&time1) == (time_t) - 1) e(1);
if (chmod("foo", mod) != 0) e(2);
Stat("foo", &st2);
if (time(&time2) == (time_t) - 1) e(3);
if (superuser)
if ((st2.st_mode & ALL_BITS) != mod) e(4);
if (!superuser)
if ((st2.st_mode & ALL_RWXB) != (mod & ALL_RWXB)) e(5);
/* Test the C time feald. */
if (st1.st_ctime > st2.st_ctime) e(6);
if (st1.st_ctime > time1) e(7);
if (st1.st_ctime > time2) e(8);
#ifndef V1_FILESYSTEM
if (st2.st_ctime < time1) e(9);
#endif
if (st2.st_ctime > time2) e(10);
if (st1.st_atime != st2.st_atime) e(11);
if (st1.st_mtime != st2.st_mtime) e(12);
} /* End for loop. */
/* Check if chown(file, geteuid(), getegid()) works. */
for (cnt = 0; cnt < 20; cnt++) {
/* Set all rights on foo, including the set .id bits. */
if (chmod("foo", ALL_BITS) != 0) e(13);
Stat("foo", &st1);
if (time(&time1) == (time_t) -1) e(14);
if (chown("foo", geteuid(), getegid()) != 0) e(15);
Stat("foo", &st2);
if (time(&time2) == (time_t) -1) e(16);
/* Check ``chown()'' killed the set .id bits. */
if (!superuser) {
if ((st1.st_mode & ALL_RWXB) != ALL_RWXB) e(17);
if ((st2.st_mode & ALL_BITS) != ALL_RWXB) e(18);
}
if (superuser) {
if ((st1.st_mode & ALL_BITS) != ALL_BITS) e(19);
if ((st1.st_mode & ALL_RWXB) != ALL_RWXB) e(20);
}
/* Check the timing. */
if (st1.st_ctime > st2.st_ctime) e(21);
if (st1.st_ctime > time1) e(22);
if (st1.st_ctime > time2) e(23);
#ifndef V1_FILESYSTEM
if (st2.st_ctime < time1) e(24);
#endif
if (st2.st_ctime > time2) e(25);
if (st1.st_atime != st2.st_atime) e(26);
if (st1.st_mtime != st2.st_mtime) e(27);
} /* End for loop. */
/* Make scratch file. */
if (chmod("foo", ALL_RWXB) != 0) e(28);
if (I_can_chown) {
/* Do a 20 tests on a gid and uid. */
for (cnt = 0; cnt < 20; cnt++) {
/* Get a uid and a gid, test chown. */
getids(&uid, &gid);
Stat("foo", &st1);
if (time(&time1) == (time_t) -1) e(29);
if (chown("foo", (uid_t) 0, (gid_t) 0) != 0) e(30);
Stat("foo", &st2);
if (time(&time2) == (time_t) -1) e(31);
/* Test the C time field. */
if (st1.st_ctime > st2.st_ctime) e(32);
if (st1.st_ctime > time1) e(33);
if (st1.st_ctime > time2) e(34);
if (st2.st_ctime < time1) e(35);
if (st2.st_ctime > time2) e(36);
if (st1.st_atime != st2.st_atime) e(37);
if (st1.st_mtime != st2.st_mtime) e(38);
/* Do aditional tests. */
if (chown("foo", (uid_t) 0, gid) != 0) e(39);
if (chown("foo", uid, (gid_t) 0) != 0) e(40);
if (chown("foo", uid, gid) != 0) e(41);
}
}
if (superuser) {
/* Check if a non-superuser can change a files gid to gid2 *
* if gid2 is the current process gid. */
for (cnt = 0; cnt < 5; cnt++) {
switch (fork()) {
case -1:
printf("Can't fork\n");
break;
case 0:
alarm(20);
getids(&uid, &gid);
if (uid == 0) {
getids(&uid, &gid);
if (uid == 0) e(42);
}
getids(&uid2, &gid2);
if (gid == gid2) e(43);
/* Creat boo and bar for user uid of group gid. */
Creat("boo");
if (chown("boo", uid, gid) != 0) e(44);
if (chmod("boo", ALL_BITS) != 0) e(45);
Creat("bar");
if (chown("bar", uid, gid) != 0) e(46);
if (chmod("bar", ALL_BITS) != 0) e(47);
/* We now become user uid of group gid2. */
setgid(gid2);
setuid(uid);
Stat("bar", &st1);
if (time(&time1) == (time_t) -1) e(48);
if (chown("bar", uid, gid2) != 0) e(49);
Stat("bar", &st2);
if (time(&time2) == (time_t) -1) e(50);
/* Check if the SET_BITS are cleared. */
if ((st1.st_mode & ALL_BITS) != ALL_BITS) e(51);
if ((st2.st_mode & ALL_BITS) != ALL_RWXB) e(52);
/* Check the st_times. */
if (st1.st_ctime > st2.st_ctime) e(53);
if (st1.st_ctime > time1) e(54);
if (st1.st_ctime > time2) e(55);
if (st2.st_ctime < time1) e(56);
if (st2.st_ctime > time2) e(57);
if (st1.st_atime != st2.st_atime) e(58);
if (st1.st_mtime != st2.st_mtime) e(59);
Stat("boo", &st1);
if (chmod("boo", ALL_BITS) != 0) e(60);
Stat("boo", &st2);
/* Check if the set gid bit is cleared. */
if ((st1.st_mode & ALL_RWXB) != ALL_RWXB) e(61);
if ((st2.st_mode & S_ISGID) != 0) e(62);
if (chown("boo", uid, gid2) != 0) e(63);
Stat("boo", &st1);
/* Check if the set uid bit is cleared. */
if ((st1.st_mode & S_ISUID) != 0) e(64);
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(65); /* Alarm? */
}
} /* end for loop. */
} /* end if (superuser). */
if (chmod("foo", ALL_BITS) != 0) e(66);
Stat("foo", &st1);
if (chown("foo", geteuid(), getegid()) != 0) e(67);
Stat("foo", &st2);
if ((st1.st_mode & ALL_BITS) != ALL_BITS) e(68); /* See intro! */
if (superuser)
if ((st2.st_mode & ALL_RWXB) != ALL_RWXB) e(69);
if (!superuser)
if ((st2.st_mode & ALL_BITS) != ALL_RWXB) e(70);
(void) system("chmod 777 ../DIR_34/* > /dev/null 2> /dev/null");
System("rm -rf ../DIR_34/*");
}
void test34b()
{
time_t time1, time2;
mode_t mod;
struct stat st1, st2;
subtest = 2;
/* Test chmod() and chown() on non regular files and on MaxName and
* MaxPath. * Funny, but dirs should also have S_IS.ID bits.
*/
Mkfifo("fifo");
Mkdir("dir");
Creat(MaxName);
MaxPath[strlen(MaxPath) - 2] = '/';
MaxPath[strlen(MaxPath) - 1] = 'a'; /* make ././.../a */
Creat(MaxPath);
for (mod = 1; mod <= ALL_BITS; mod <<= 1) {
if ((mod & ALL_BITS) != mod) continue; /* bad mod */
Stat("dir", &st1);
if (time(&time1) == (time_t) -1) e(1);
if (chmod("dir", mod) != 0) e(2);
Stat("dir", &st2);
if (time(&time2) == (time_t) -1) e(3);
if (superuser)
if ((st2.st_mode & ALL_BITS) != mod) e(4);
if (!superuser)
if ((st2.st_mode & ALL_RWXB) != (mod & ALL_RWXB)) e(5);
/* Test the C time field. */
if (st1.st_ctime > st2.st_ctime) e(6);
if (st1.st_ctime > time1) e(7);
if (st1.st_ctime > time2) e(8);
#ifndef V1_FILESYSTEM
if (st2.st_ctime < time1) e(9);
#endif
if (st2.st_ctime > time2) e(10);
if (st1.st_atime != st2.st_atime) e(11);
if (st1.st_mtime != st2.st_mtime) e(12);
Stat("fifo", &st1);
if (time(&time1) == (time_t) -1) e(13);
if (chmod("fifo", mod) != 0) e(14);
Stat("fifo", &st2);
if (time(&time2) == (time_t) -1) e(15);
if (superuser)
if ((st2.st_mode & ALL_BITS) != mod) e(16);
if (!superuser)
if ((st2.st_mode & ALL_RWXB) != (mod & ALL_RWXB)) e(17);
/* Test the C time field. */
if (st1.st_ctime > st2.st_ctime) e(18);
if (st1.st_ctime > time1) e(19);
if (st1.st_ctime > time2) e(20);
#ifndef V1_FILESYSTEM
if (st2.st_ctime < time1) e(21);
#endif
if (st2.st_ctime > time2) e(22);
if (st1.st_atime != st2.st_atime) e(23);
if (st1.st_mtime != st2.st_mtime) e(24);
Stat(MaxName, &st1);
if (time(&time1) == (time_t) -1) e(25);
if (chmod(MaxName, mod) != 0) e(26);
Stat(MaxName, &st2);
if (time(&time2) == (time_t) -1) e(27);
if (superuser)
if ((st2.st_mode & ALL_BITS) != mod) e(28);
if (!superuser)
if ((st2.st_mode & ALL_RWXB) != (mod & ALL_RWXB)) e(29);
/* Test the C time field. */
if (st1.st_ctime > st2.st_ctime) e(30);
if (st1.st_ctime > time1) e(31);
if (st1.st_ctime > time2) e(32);
#ifndef V1_FILESYSTEM
if (st2.st_ctime < time1) e(33);
#endif
if (st2.st_ctime > time2) e(34);
if (st1.st_atime != st2.st_atime) e(35);
if (st1.st_mtime != st2.st_mtime) e(36);
Stat(MaxPath, &st1);
if (time(&time1) == (time_t) -1) e(37);
if (chmod(MaxPath, mod) != 0) e(38);
Stat(MaxPath, &st2);
if (time(&time2) == (time_t) -1) e(39);
if (superuser)
if ((st2.st_mode & ALL_BITS) != mod) e(40);
if (!superuser)
if ((st2.st_mode & ALL_RWXB) != (mod & ALL_RWXB)) e(41);
/* Test the C time field. */
if (st1.st_ctime > st2.st_ctime) e(42);
if (st1.st_ctime > time1) e(43);
if (st1.st_ctime > time2) e(44);
#ifndef V1_FILESYSTEM
if (st2.st_ctime < time1) e(45);
#endif
if (st2.st_ctime > time2) e(46);
if (st1.st_atime != st2.st_atime) e(47);
if (st1.st_mtime != st2.st_mtime) e(48);
}
if (chmod("dir", 0777) != 0) e(49);
if (chmod("fifo", 0777) != 0) e(50);
if (chmod(MaxName, 0777) != 0) e(51);
if (chmod(MaxPath, 0777) != 0) e(52);
(void) system("chmod 777 ../DIR_34/* > /dev/null 2> /dev/null");
System("rm -rf ../DIR_34/*");
}
void test34c()
{
struct stat st;
uid_t uid, uid2;
gid_t gid, gid2;
int stat_loc;
subtest = 3;
Mkdir("dir");
Creat("dir/try_me");
/* Disalow search permission and see if chmod() and chown() return
* EACCES.
*/
if (chmod("dir", ALL_BITS & ~S_IXUSR) != 0) e(1);
if (!superuser) {
if (chmod("dir/try_me", 0) != -1) e(2);
if (errno != EACCES) e(3);
if (I_can_chown) {
if (chown("dir/try_me", geteuid(), getegid()) != -1) e(4);
if (errno != EACCES) e(5);
}
}
/* Check ENOTDIR. */
Mkfifo("fifo");
if (chmod("fifo/try_me", 0) != -1) e(6);
if (errno != ENOTDIR) e(7);
if (chown("fifo/try_me", geteuid(), getegid()) != -1) e(8);
if (errno != ENOTDIR) e(9);
Creat("file");
if (chmod("file/try_me", 0) != -1) e(10);
if (errno != ENOTDIR) e(11);
if (chown("file/try_me", geteuid(), getegid()) != -1) e(12);
if (errno != ENOTDIR) e(13);
/* Check empty path. */
if (chmod("", 0) != -1) e(14);
if (errno != ENOENT) e(15);
if (chown("", geteuid(), getegid()) != -1) e(16);
if (errno != ENOENT) e(17);
/* Check non existing file name. */
if (chmod("non_exist", 0) != -1) e(18);
if (errno != ENOENT) e(19);
if (chown("non_exist", geteuid(), getegid()) != -1) e(20);
if (errno != ENOENT) e(21);
/* Check what we get if we do not have permisson. */
if (!superuser) {
Stat("/", &st);
if (st.st_uid == geteuid()) e(22);
/* First I had 0, I changed it to st.st_mode 8-). */
if (chmod("/", st.st_mode) != -1) e(23);
if (errno != EPERM) e(24);
}
if (!I_can_chown) {
Stat("/", &st);
if (st.st_uid == geteuid()) e(25);
if (chown("/", geteuid(), getegid()) != -1) e(26);
if (errno != EPERM) e(27);
}
/* If we are superuser, we can test all id combinations. */
if (superuser) {
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
getids(&uid, &gid);
if (uid == 0) {
getids(&uid, &gid);
if (uid == 0) e(28);
}
getids(&uid2, &gid2);
if (gid == gid2) e(29);
if (uid == uid2) e(30);
/* Creat boo, owned by root. */
Creat("boo");
if (chmod("boo", ALL_BITS) != 0) e(31);
/* Creat boo for user uid2 of group gid2. */
Creat("bar");
if (chown("bar", uid2, gid2) != 0) e(32);
if (chmod("bar", ALL_BITS) != 0) e(33);
/* Creat my_gid for user uid2 of group gid. */
Creat("my_gid");
if (chown("my_gid", uid2, gid) != 0) e(34);
if (chmod("my_gid", ALL_BITS) != 0) e(35);
/* Creat my_uid for user uid of uid gid. */
Creat("my_uid");
if (chown("my_uid", uid, gid) != 0) e(36);
if (chmod("my_uid", ALL_BITS) != 0) e(37);
/* We now become user uid of uid gid. */
setgid(gid);
setuid(uid);
if (chown("boo", uid, gid) != -1) e(38);
if (errno != EPERM) e(39);
if (chown("bar", uid, gid) != -1) e(40);
if (errno != EPERM) e(41);
if (chown("my_gid", uid, gid) != -1) e(42);
if (errno != EPERM) e(43);
if (chown("my_uid", uid, gid2) != -1) e(44);
/* The EPERM is not strict POSIX. */
if (errno != EPERM) e(45);
if (chmod("boo", 0) != -1) e(46);
if (errno != EPERM) e(47);
if (chmod("bar", 0) != -1) e(48);
if (errno != EPERM) e(49);
if (chmod("my_gid", 0) != -1) e(50);
if (errno != EPERM) e(51);
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(52); /* Alarm? */
}
}
/* Check too long path ed. */
Creat(NameTooLong);
if (chmod(NameTooLong, 0777) != 0) e(57);
if (chown(NameTooLong, geteuid(), getegid()) != 0) e(58);
/* Make PathTooLong contain ././.../a */
PathTooLong[strlen(PathTooLong) - 2] = '/';
PathTooLong[strlen(PathTooLong) - 1] = 'a';
Creat("a");
if (chmod(PathTooLong, 0777) != -1) e(59);
if (errno != ENAMETOOLONG) e(60);
if (chown(PathTooLong, geteuid(), getegid()) != -1) e(61);
if (errno != ENAMETOOLONG) e(62);
(void) system("chmod 777 ../DIR_34/* > /dev/null 2> /dev/null");
System("rm -rf ../DIR_34/*");
}
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(NameTooLong, MaxName); /* copy them Max to TooLong */
strcpy(PathTooLong, MaxPath);
NameTooLong[NAME_MAX] = 'a';
NameTooLong[NAME_MAX + 1] = '\0'; /* extend NameTooLong by one too many*/
PathTooLong[PATH_MAX - 1] = '/';
PathTooLong[PATH_MAX] = '\0'; /* inc PathTooLong by one */
}
void e(n)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
system("rm -rf DIR_34");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
(void) system("chmod 777 DIR_34/* > /dev/null 2> /dev/null");
System("rm -rf DIR_34");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}
/* Getids returns a valid uid and gid. Is used PASSWD FILE.
* It assumes the following format for a passwd file line:
* <user_name>:<passwd>:<uid>:<gid>:<other_stuff>
* If no uids and gids can be found, it will only return 0 ids.
*/
void getids(r_uid, r_gid)
uid_t * r_uid;
gid_t * r_gid;
{
char line[N];
char *p;
uid_t uid;
gid_t gid;
FILE *fp;
int i;
static uid_t a_uid[N]; /* Array for uids. */
static gid_t a_gid[N]; /* Array for gids. */
static int nuid = 0, ngid = 0;/* The number of user & group ids. */
static int cuid = 0, cgid = 0;/* The current id index. */
/* If we don't have any uids go read some from the passwd file. */
if (nuid == 0) {
a_uid[nuid++] = 0; /* Root uid and gid. */
a_gid[ngid++] = 0;
if ((fp = fopen(PASSWD_FILE, "r")) == NULL) {
printf("Can't open ");
perror(PASSWD_FILE);
}
while (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
p = strchr(line, ':');
if (p != NULL) p = strchr(p + 1, ':');
if (p != NULL) {
p++;
uid = 0;
while (isdigit(*p)) {
uid *= 10;
uid += (uid_t) (*p - '0');
p++;
}
if (*p != ':') continue;
p++;
gid = 0;
while (isdigit(*p)) {
gid *= 10;
gid += (gid_t) (*p - '0');
p++;
}
if (*p != ':') continue;
if (nuid < N) {
for (i = 0; i < nuid; i++)
if (a_uid[i] == uid) break;
if (i == nuid) a_uid[nuid++] = uid;
}
if (ngid < N) {
for (i = 0; i < ngid; i++)
if (a_gid[i] == gid) break;
if (i == ngid) a_gid[ngid++] = gid;
}
if (nuid >= N && ngid >= N) break;
}
}
if (fp != NULL) fclose(fp);
}
/* We now have uids and gids in a_uid and a_gid. */
if (cuid >= nuid) cuid = 0;
if (cgid >= ngid) cgid = 0;
*r_uid = a_uid[cuid++];
*r_gid = a_gid[cgid++];
}

422
test/test35.c Normal file
View File

@@ -0,0 +1,422 @@
/* test35: utime() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <utime.h>
#include <errno.h>
#include <time.h>
#include <ctype.h>
#include <stdio.h>
#define MAX_ERROR 1
#define ITERATIONS 10
#define N 100
#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)
#define Mkdir(f) if (mkdir(f,0777)!=0) printf("Can't make dir %s\n", f)
#define Creat(f) if (close(creat(f,0777))!=0) printf("Can't creat %s\n",f)
#define Time(t) if (time(t) == (time_t)-1) printf("Time error\n")
#define Chown(f,u,g) if (chown(f,u,g) != 0) printf("Can't chown %s\n", f)
#define Chmod(f,m) if (chmod(f,m) != 0) printf("Can't chmod %s\n", f)
#define PASSWD_FILE "/etc/passwd"
int errct = 0;
int subtest = 1;
int I_can_chown;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char NameTooLong[NAME_MAX + 2]; /* Name of maximum +1 length */
char PathTooLong[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test35a, (void));
_PROTOTYPE(void test35b, (void));
_PROTOTYPE(void test35c, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
_PROTOTYPE(void getids, (uid_t * uid, gid_t * gid));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 35 ");
fflush(stdout);
System("rm -rf DIR_35; mkdir DIR_35");
Chdir("DIR_35");
makelongnames();
superuser = (geteuid() == 0);
#ifdef _POSIX_CHOWN_RESTRICTED
# if _POSIX_CHOWN_RESTRICTED - 0 != -1
I_can_chown = superuser;
# else
I_can_chown = 1;
# endif
#else
# include "error, this case requires dynamic checks and is not handled"
#endif
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test35a();
if (m & 0002) test35b();
if (m & 0004) test35c();
}
quit();
}
void test35a()
{ /* Test normal operation. */
struct stat st;
struct utimbuf ub;
time_t time1, time2;
int cnt;
subtest = 1;
/* Creat scratch file. */
Creat("foo");
/* Set file times back two seconds. */
Stat("foo", &st);
ub.actime = st.st_atime - 2;
ub.modtime = st.st_mtime - 2;
Time(&time1);
utime("foo", &ub);
Time(&time2);
Stat("foo", &st);
if (ub.actime != st.st_atime) e(1);
if (ub.modtime != st.st_mtime) e(2);
/* The status changed time sould be changed. */
#ifndef V1_FILESYSTEM
if (st.st_ctime < time1) e(3);
#endif
if (st.st_ctime > time2) e(4);
/* Add twenty seconds. */
Stat("foo", &st);
ub.actime = st.st_atime + 20;
ub.modtime = st.st_mtime + 20;
Time(&time1);
utime("foo", &ub);
Time(&time2);
Stat("foo", &st);
if (ub.actime != st.st_atime) e(5);
if (ub.modtime != st.st_mtime) e(6);
if (st.st_ctime < time1) e(7);
#ifndef V1_FILESYSTEM
if (st.st_ctime > time2) e(8);
#endif
/* Try 100 times to do utime in less than one second. */
cnt = 0;
do {
Time(&time1);
utime("foo", (struct utimbuf *) NULL);
Time(&time2);
} while (time1 != time2 && cnt++ < 100);
if (time1 == time2) {
Stat("foo", &st);
Time(&time2);
if (st.st_atime != time1) e(9);
if (st.st_mtime != time1) e(10);
} else {
Stat("foo", &st);
if (st.st_atime > time2) e(11);
if (st.st_mtime > time2) e(12);
Time(&time2);
if (st.st_atime < time1) e(13);
if (st.st_mtime < time1) e(14);
}
if (st.st_ctime < time1) e(15);
if (st.st_ctime > time2) e(16);
System("rm -rf ../DIR_35/*");
}
void test35b()
{
subtest = 2;
/* MaxPath and MaxName checkup. */
Creat(MaxName);
MaxPath[strlen(MaxPath) - 2] = '/';
MaxPath[strlen(MaxPath) - 1] = 'a'; /* make ././.../a */
Creat(MaxPath);
if (utime(MaxName, NULL) != 0) e(1);
if (utime(MaxPath, NULL) != 0) e(2);
/* The owner doesn't need write permisson to set times. */
Creat("foo");
if (chmod("foo", 0) != 0) e(3);
if (utime("foo", NULL) != 0) e(4);
if (chmod("foo", 0777) != 0) e(5);
if (utime("foo", NULL) != 0) e(6);
System("rm -rf ../DIR_35/*");
}
void test35c()
{
gid_t gid, gid2;
uid_t uid, uid2;
struct utimbuf ub;
int stat_loc;
subtest = 3;
/* Access problems. */
Mkdir("bar");
Creat("bar/tryme");
if (superuser) {
Chmod("bar", 0000); /* No search permisson at all. */
if (utime("bar/tryme", NULL) != 0) e(1);
}
if (!superuser) {
Chmod("bar", 0677); /* No search permisson. */
if (utime("bar/tryme", NULL) != -1) e(2);
if (errno != EACCES) e(3);
}
Chmod("bar", 0777);
if (I_can_chown) {
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
/* Get two differend non root uids. */
if (superuser) {
getids(&uid, &gid);
if (uid == 0) getids(&uid, &gid);
if (uid == 0) e(4);
}
if (!superuser) {
uid = geteuid();
gid = getegid();
}
getids(&uid2, &gid);
if (uid == uid2) getids(&uid2, &gid2);
if (uid == uid2) e(5);
/* Creat a number of files for root, user and user2. */
Creat("rootfile"); /* Owned by root. */
Chmod("rootfile", 0600);
Chown("rootfile", 0, 0);
Creat("user2file"); /* Owned by user 2, writeable. */
Chmod("user2file", 0020);
Chown("user2file", uid2, gid);
Creat("user2private"); /* Owned by user 2, privately. */
Chmod("user2private", 0600);
Chown("user2private", uid2, gid);
if (superuser) {
setgid(gid);
setuid(uid);
}
/* We now are user ``uid'' from group ``gid''. */
ub.actime = (time_t) 12345L;
ub.modtime = (time_t) 12345L;
if (utime("rootfile", NULL) != -1) e(6);
if (errno != EACCES) e(7);
if (utime("rootfile", &ub) != -1) e(8);
if (errno != EPERM) e(9);
if (utime("user2file", NULL) != 0) e(10);
if (utime("user2file", &ub) != -1) e(11);
if (errno != EPERM) e(12);
if (utime("user2private", NULL) != -1) e(13);
if (errno != EACCES) e(14);
if (utime("user2private", &ub) != -1) e(15);
if (errno != EPERM) e(16);
exit(errct ? 1 : 0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(17); /* Alarm? */
}
}
/* Test names that are too long. */
#ifdef _POSIX_NO_TRUNC
# if _POSIX_NO_TRUNC - 0 != -1
/* Not exist might also be a propper response? */
if (utime(NameTooLong, NULL) != -1) e(18);
if (errno != ENAMETOOLONG) e(19);
# else
Creat(NameTooLong);
if (utime(NameTooLong, NULL) != 0) e(20);
# endif
#else
# include "error, this case requires dynamic checks and is not handled"
#endif
/* Make PathTooLong contain ././.../a */
PathTooLong[strlen(PathTooLong) - 2] = '/';
PathTooLong[strlen(PathTooLong) - 1] = 'a';
Creat("a");
if (utime(PathTooLong, NULL) != -1) e(21);
if (errno != ENAMETOOLONG) e(22);
/* Non existing file name. */
if (utime("nonexist", NULL) != -1) e(23);
if (errno != ENOENT) e(24);
/* Empty file name. */
if (utime("", NULL) != -1) e(25);
if (errno != ENOENT) e(26);
System("rm -rf ../DIR_35/*");
}
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(NameTooLong, MaxName); /* copy them Max to TooLong */
strcpy(PathTooLong, MaxPath);
NameTooLong[NAME_MAX] = 'a';
NameTooLong[NAME_MAX + 1] = '\0'; /* extend NameTooLong by one too many*/
PathTooLong[PATH_MAX - 1] = '/';
PathTooLong[PATH_MAX] = '\0'; /* inc PathTooLong by one */
}
void e(n)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR* > /dev/null 2>/dev/null");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_35");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}
/* Getids returns a valid uid and gid. Is used PASSWD FILE.
** It assumes the following format for a passwd file line:
** <user_name>:<passwd>:<uid>:<gid>:<other_stuff>
** If no uids and gids can be found, it will only return 0 ids.
*/
void getids(r_uid, r_gid)
uid_t *r_uid;
gid_t *r_gid;
{
char line[N];
char *p;
uid_t uid;
gid_t gid;
FILE *fp;
int i;
static uid_t a_uid[N]; /* Array for uids. */
static gid_t a_gid[N]; /* Array for gids. */
static int nuid = 0, ngid = 0;/* The number of user & group ids. */
static int cuid = 0, cgid = 0;/* The current id index. */
/* If we don't have any uids go read some from the passwd file. */
if (nuid == 0) {
a_uid[nuid++] = 0; /* Root uid and gid. */
a_gid[ngid++] = 0;
if ((fp = fopen(PASSWD_FILE, "r")) == NULL) {
printf("Can't open ");
perror(PASSWD_FILE);
}
while (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
p = strchr(line, ':');
if (p != NULL) p = strchr(p + 1, ':');
if (p != NULL) {
p++;
uid = 0;
while (isdigit(*p)) {
uid *= 10;
uid += (uid_t) (*p - '0');
p++;
}
if (*p != ':') continue;
p++;
gid = 0;
while (isdigit(*p)) {
gid *= 10;
gid += (gid_t) (*p - '0');
p++;
}
if (*p != ':') continue;
if (nuid < N) {
for (i = 0; i < nuid; i++)
if (a_uid[i] == uid) break;
if (i == nuid) a_uid[nuid++] = uid;
}
if (ngid < N) {
for (i = 0; i < ngid; i++)
if (a_gid[i] == gid) break;
if (i == ngid) a_gid[ngid++] = gid;
}
if (nuid >= N && ngid >= N) break;
}
}
if (fp != NULL) fclose(fp);
}
/* We now have uids and gids in a_uid and a_gid. */
if (cuid >= nuid) cuid = 0;
if (cgid >= ngid) cgid = 0;
*r_uid = a_uid[cuid++];
*r_gid = a_gid[cgid++];
}

251
test/test36.c Normal file
View File

@@ -0,0 +1,251 @@
/* test36: pathconf() fpathconf() Author: Jan-mark Wams */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.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)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test36a, (void));
_PROTOTYPE(void test36b, (void));
_PROTOTYPE(void test36c, (void));
_PROTOTYPE(void test36d, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
_PROTOTYPE(int not_provided_option, (int _option));
_PROTOTYPE(int provided_option, (int _option, int _minimum_value));
_PROTOTYPE(int variating_option, (int _option, int _minimum_value));
char *testdirs[] = {
"/",
"/etc",
"/tmp",
"/usr",
"/usr/bin",
".",
NULL
};
char *testfiles[] = {
"/",
"/etc",
"/etc/passwd",
"/tmp",
"/dev/tty",
"/usr",
"/usr/bin",
".",
NULL
};
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 36 ");
fflush(stdout);
System("rm -rf DIR_36; mkdir DIR_36");
Chdir("DIR_36");
makelongnames();
superuser = (geteuid() == 0);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test36a();
if (m & 0002) test36b();
if (m & 0004) test36c();
if (m & 0010) test36d();
}
quit();
}
void test36a()
{ /* Test normal operation. */
subtest = 1;
System("rm -rf ../DIR_36/*");
#ifdef _POSIX_CHOWN_RESTRICTED
# if _POSIX_CHOWN_RESTRICTED - 0 == -1
if (not_provided_option(_PC_CHOWN_RESTRICTED) != 0) e(1);
# else
if (provided_option(_PC_CHOWN_RESTRICTED, 0) != 0) e(2);
# endif
#else
if (variating_option(_PC_CHOWN_RESTRICTED, 0) != 0) e(3);
#endif
#ifdef _POSIX_NO_TRUNC
# if _POSIX_NO_TRUNC - 0 == -1
if (not_provided_option(_PC_NO_TRUNC) != 0) e(4);
# else
if (provided_option(_PC_NO_TRUNC, 0) != 0) e(5);
# endif
#else
if (variating_option(_PC_NO_TRUNC, 0) != 0) e(6);
#endif
#ifdef _POSIX_VDISABLE
# if _POSIX_VDISABLE - 0 == -1
if (not_provided_option(_PC_VDISABLE) != 0) e(7);
# else
if (provided_option(_PC_VDISABLE, 0) != 0) e(8);
# endif
#else
if (variating_option(_PC_VDISABLE, 0) != 0) e(9);
#endif
}
void test36b()
{
subtest = 2;
System("rm -rf ../DIR_36/*");
}
void test36c()
{
subtest = 3;
System("rm -rf ../DIR_36/*");
}
void test36d()
{
subtest = 4;
System("rm -rf ../DIR_36/*");
}
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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_36");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}
int not_provided_option(option)
int option;
{
char **p;
for (p = testfiles; *p != (char *) NULL; p++) {
if (pathconf(*p, option) != -1) return printf("*p == %s\n", *p), 1;
}
return 0;
}
int provided_option(option, minimum)
int option, minimum;
{
char **p;
/* These three options are only defined on directorys. */
if (option == _PC_NO_TRUNC
|| option == _PC_NAME_MAX
|| option == _PC_PATH_MAX)
p = testdirs;
else
p = testfiles;
for (; *p != NULL; p++) {
if (pathconf(*p, option) < minimum)
return printf("*p == %s\n", *p), 1;
}
return 0;
}
int variating_option(option, minimum)
int option, minimum;
{
char **p;
/* These three options are only defined on directorys. */
if (option == _PC_NO_TRUNC
|| option == _PC_NAME_MAX
|| option == _PC_PATH_MAX)
p = testdirs;
else
p = testfiles;
for (; *p != NULL; p++) {
if (pathconf(*p, option) < minimum)
return printf("*p == %s\n", *p), 1;
}
return 0;
}

268
test/test37.c Normal file
View File

@@ -0,0 +1,268 @@
/* test37: pipe() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 60
#define Fstat(a,b) if (fstat(a,b) != 0) printf("Can't fstat %d\n", a)
#define Time(t) if (time(t) == (time_t)-1) printf("Time error\n")
int errct = 0;
int subtest = 1;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test37a, (void));
_PROTOTYPE(void test37b, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 37 ");
fflush(stdout);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test37a();
if (m & 0002) test37b();
}
quit();
}
void test37a()
{ /* Test fcntl flags. */
int tube[2], t1[2], t2[2], t3[2];
time_t time1, time2;
char buf[128];
struct stat st1, st2;
int stat_loc, flags;
subtest = 1;
/* Check if lowest fds are returned. */
if (pipe(tube) != 0) e(1);
if (tube[0] != 3 && tube[1] != 3) e(2);
if (tube[1] != 4 && tube[0] != 4) e(3);
if (tube[1] == tube[0]) e(4);
if (pipe(t1) != 0) e(5);
if (t1[0] != 5 && t1[1] != 5) e(6);
if (t1[1] != 6 && t1[0] != 6) e(7);
if (t1[1] == t1[0]) e(8);
if (close(t1[0]) != 0) e(9);
if (close(tube[0]) != 0) e(10);
if (pipe(t2) != 0) e(11);
if (t2[0] != tube[0] && t2[1] != tube[0]) e(12);
if (t2[1] != t1[0] && t2[0] != t1[0]) e(13);
if (t2[1] == t2[0]) e(14);
if (pipe(t3) != 0) e(15);
if (t3[0] != 7 && t3[1] != 7) e(16);
if (t3[1] != 8 && t3[0] != 8) e(17);
if (t3[1] == t3[0]) e(18);
if (close(tube[1]) != 0) e(19);
if (close(t1[1]) != 0) e(20);
if (close(t2[0]) != 0) e(21);
if (close(t2[1]) != 0) e(22);
if (close(t3[0]) != 0) e(23);
if (close(t3[1]) != 0) e(24);
/* All time fields should be marked for update. */
Time(&time1);
if (pipe(tube) != 0) e(25);
Fstat(tube[0], &st1);
Fstat(tube[1], &st2);
Time(&time2);
if (st1.st_atime < time1) e(26);
if (st1.st_ctime < time1) e(27);
if (st1.st_mtime < time1) e(28);
if (st1.st_atime > time2) e(29);
if (st1.st_ctime > time2) e(30);
if (st1.st_mtime > time2) e(31);
if (st2.st_atime < time1) e(32);
if (st2.st_ctime < time1) e(33);
if (st2.st_mtime < time1) e(34);
if (st2.st_atime > time2) e(35);
if (st2.st_ctime > time2) e(36);
if (st2.st_mtime > time2) e(37);
/* Check the file characteristics. */
if ((flags = fcntl(tube[0], F_GETFD)) != 0) e(38);
if ((flags & FD_CLOEXEC) != 0) e(39);
if ((flags = fcntl(tube[0], F_GETFL)) != 0) e(40);
if ((flags & O_RDONLY) != O_RDONLY) e(41);
if ((flags & O_NONBLOCK) != 0) e(42);
if ((flags & O_RDWR) != 0) e(43);
if ((flags & O_WRONLY) != 0) e(44);
if ((flags = fcntl(tube[1], F_GETFD)) != 0) e(45);
if ((flags & FD_CLOEXEC) != 0) e(46);
if ((flags = fcntl(tube[1], F_GETFL)) == -1) e(47);
if ((flags & O_WRONLY) != O_WRONLY) e(48);
if ((flags & O_NONBLOCK) != 0) e(49);
if ((flags & O_RDWR) != 0) e(50);
if ((flags & O_RDONLY) != 0) e(51);
/* Check if we can read and write. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[0]) != 0) e(52);
if (write(tube[1], "Hello", 6) != 6) e(53);
if (close(tube[1]) != 0) e(54);
exit(0);
default:
if (read(tube[0], buf, sizeof(buf)) != 6) e(55);
if (strncmp(buf, "Hello", 6) != 0) e(56);
wait(&stat_loc);
if (stat_loc != 0) e(57); /* Alarm? */
}
if (close(tube[0]) != 0) e(58);
if (close(tube[1]) != 0) e(59);
}
void test37b()
{
int tube[2], child2parent[2], parent2child[2];
int i, nchild = 0, nopen = 3, stat_loc;
int fd;
int forkfailed = 0;
char c;
subtest = 2;
/* Take all the pipes we can get. */
while (nopen < OPEN_MAX - 2) {
if (pipe(tube) != 0) {
/* We have not reached OPEN_MAX yet, so we have ENFILE. */
if (errno != ENFILE) e(1);
sleep(2); /* Wait for others to (maybe) closefiles. */
break;
}
nopen += 2;
}
if (nopen < OPEN_MAX - 2) {
if (pipe(tube) != -1) e(2);
switch (errno) {
case EMFILE: /* Errno value is ok. */
break;
case ENFILE: /* No process can open files any more. */
switch (fork()) {
case -1:
printf("Can't fork\n");
break;
case 0:
alarm(20);
if (open("/", O_RDONLY) != -1) e(3);
if (errno != ENFILE) e(4);
exit(0);
default:
wait(&stat_loc);
if (stat_loc != 0) e(5); /* Alarm? */
}
break;
default: /* Wrong value for errno. */
e(6);
}
}
/* Close all but stdin,out,err. */
for (i = 3; i < OPEN_MAX; i++) (void) close(i);
/* ENFILE test. Have children each grab OPEN_MAX fds. */
if (pipe(child2parent) != 0) e(7);
if (pipe(parent2child) != 0) e(8);
while (!forkfailed && (fd = open("/", O_RDONLY)) != -1) {
close(fd);
switch (fork()) {
case -1:
forkfailed = 1;
break;
case 0:
alarm(60);
/* Grab all the fds. */
while (pipe(tube) != -1);
while (open("/", O_RDONLY) != -1);
/* Signal parent OPEN_MAX fds gone. */
if (write(child2parent[1], "*", 1) != 1) e(9);
/* Wait for parent befor freeing all the fds. */
if (read(parent2child[0], &c, 1) != 1) e(10);
exit(0);
default:
/* Wait for child to grab OPEN_MAX fds. */
if (read(child2parent[0], &c, 1) != 1) e(11);
nchild++;
break;
}
}
if (!forkfailed) {
if (pipe(tube) != -1) e(12);
if (errno != ENFILE) e(13);
}
/* Signal children to die and wait for it. */
while (nchild-- > 0) {
if (write(parent2child[1], "*", 1) != 1) e(14);
wait(&stat_loc);
if (stat_loc != 0) e(15); /* Alarm? */
}
/* Close all but stdin,out,err. */
for (i = 3; i < OPEN_MAX; i++) (void) close(i);
}
void e(n)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

250
test/test38.c Normal file
View File

@@ -0,0 +1,250 @@
/* test38: dup() dup2() Author: Jan-Mark Wams (jms@cs.vu.nl) */
/* The definition of ``dup2()'' is realy a big mess! For:
**
** (1) if fildes2 is less than zero or greater than {OPEN_MAX}
** errno has to set to [EBADF]. But if fildes2 equals {OPEN_MAX}
** errno has to be set to [EINVAL]. And ``fcntl(F_DUPFD...)'' always
** returns [EINVAL] if fildes2 is out of range!
**
** (2) if the number of file descriptors would exceed {OPEN_MAX}, or no
** file descriptors above fildes2 are available, errno has to be set
** to [EMFILE]. But this can never occur!
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.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 IS_CLOEXEC(fd) ((fcntl(fd, F_GETFD) & FD_CLOEXEC) == FD_CLOEXEC)
#define SET_CLOEXEC(fd) fcntl(fd, F_SETFD, FD_CLOEXEC)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test38a, (void));
_PROTOTYPE(void test38b, (void));
_PROTOTYPE(void test38c, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 38 ");
fflush(stdout);
System("rm -rf DIR_38; mkdir DIR_38");
Chdir("DIR_38");
superuser = (geteuid() == 0);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test38a();
if (m & 0002) test38b();
if (m & 0004) test38c();
}
quit();
}
void test38a()
{
int fd1, fd2, fd3, fd4, fd5;
struct flock flock;
subtest = 1;
/* Basic checking. */
if ((fd1 = dup(0)) != 3) e(1);
if ((fd2 = dup(0)) != 4) e(2);
if ((fd3 = dup(0)) != 5) e(3);
if ((fd4 = dup(0)) != 6) e(4);
if ((fd5 = dup(0)) != 7) e(5);
if (close(fd2) != 0) e(6);
if (close(fd4) != 0) e(7);
if ((fd2 = dup(0)) != 4) e(8);
if ((fd4 = dup(0)) != 6) e(9);
if (close(fd1) != 0) e(10);
if (close(fd3) != 0) e(11);
if (close(fd5) != 0) e(12);
if ((fd1 = dup(0)) != 3) e(13);
if ((fd3 = dup(0)) != 5) e(14);
if ((fd5 = dup(0)) != 7) e(15);
if (close(fd1) != 0) e(16);
if (close(fd2) != 0) e(17);
if (close(fd3) != 0) e(18);
if (close(fd4) != 0) e(19);
if (close(fd5) != 0) e(20);
/* FD_CLOEXEC should be cleared. */
if ((fd1 = dup(0)) != 3) e(21);
if (SET_CLOEXEC(fd1) == -1) e(22);
if (!IS_CLOEXEC(fd1)) e(23);
if ((fd2 = dup(fd1)) != 4) e(24);
if ((fd3 = dup(fd2)) != 5) e(25);
if (IS_CLOEXEC(fd2)) e(26);
if (IS_CLOEXEC(fd3)) e(27);
if (SET_CLOEXEC(fd2) == -1) e(28);
if (!IS_CLOEXEC(fd2)) e(29);
if (IS_CLOEXEC(fd3)) e(30);
if (close(fd1) != 0) e(31);
if (close(fd2) != 0) e(32);
if (close(fd3) != 0) e(33);
/* Locks should be shared, so we can lock again. */
System("echo 'Hallo' > file");
if ((fd1 = open("file", O_RDWR)) != 3) e(34);
flock.l_whence = SEEK_SET;
flock.l_start = 0;
flock.l_len = 10;
flock.l_type = F_WRLCK;
if (fcntl(fd1, F_SETLK, &flock) == -1) e(35);
if (fcntl(fd1, F_SETLK, &flock) == -1) e(36);
if ((fd2 = dup(fd1)) != 4) e(37);
if (fcntl(fd1, F_SETLK, &flock) == -1) e(38);
if (fcntl(fd1, F_GETLK, &flock) == -1) e(39);
#if 0 /* XXX - see test7.c */
if (flock.l_type != F_WRLCK) e(40);
if (flock.l_pid != getpid()) e(41);
#endif /* 0 */
flock.l_type = F_WRLCK;
if (fcntl(fd2, F_GETLK, &flock) == -1) e(42);
#if 0 /* XXX - see test7.c */
if (flock.l_type != F_WRLCK) e(43);
if (flock.l_pid != getpid()) e(44);
#endif /* 0 */
if (close(fd1) != 0) e(45);
if (close(fd2) != 0) e(46);
System("rm -rf ../DIR_38/*");
}
void test38b()
{
int fd;
char buf[32];
subtest = 2;
/* Test file called ``file''. */
System("echo 'Hallo!' > file");
/* Check dup2() call with the same fds. Should have no effect. */
if ((fd = open("file", O_RDONLY)) != 3) e(1);
if (read(fd, buf, 2) != 2) e(2);
if (strncmp(buf, "Ha", 2) != 0) e(3);
if (dup2(fd, fd) != fd) e(4);
if (read(fd, buf, 2) != 2) e(5);
if (strncmp(buf, "ll", 2) != 0) e(6);
if (dup2(fd, fd) != fd) e(7);
if (read(fd, buf, 2) != 2) e(8);
if (strncmp(buf, "o!", 2) != 0) e(9);
if (close(fd) != 0) e(10);
/* If dup2() call fails, the fildes2 argument has to stay open. */
if ((fd = open("file", O_RDONLY)) != 3) e(11);
if (read(fd, buf, 2) != 2) e(12);
if (strncmp(buf, "Ha", 2) != 0) e(13);
if (dup2(OPEN_MAX + 3, fd) != -1) e(14);
if (errno != EBADF) e(15);
if (read(fd, buf, 2) != 2) e(16);
if (strncmp(buf, "ll", 2) != 0) e(17);
if (dup2(-4, fd) != -1) e(18);
if (errno != EBADF) e(19);
if (read(fd, buf, 2) != 2) e(20);
if (strncmp(buf, "o!", 2) != 0) e(21);
if (close(fd) != 0) e(22);
System("rm -rf ../DIR_38/*");
}
void test38c()
{
int i;
subtest = 3;
/* Check bad arguments to dup() and dup2(). */
for (i = -OPEN_MAX; i < OPEN_MAX * 2; i++) {
/* ``i'' is a valid and open fd. */
if (i >= 0 && i < 3) continue;
/* If ``i'' is a valid fd it is not open. */
if (dup(i) != -1) e(1);
if (errno != EBADF) e(2);
/* ``i'' Is OPEN_MAX. */
if (i == OPEN_MAX) {
if (dup2(0, i) != -1) e(3);
if (errno != EINVAL) e(4);
}
/* ``i'' Is out of range. */
if (i < 0 || i > OPEN_MAX) {
if (dup2(0, i) != -1) e(5);
if (errno != EBADF) e(6);
}
}
System("rm -rf ../DIR_38/*");
}
void e(n)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_38");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

403
test/test39.c Normal file
View File

@@ -0,0 +1,403 @@
/* test39: fcntl() Author: Jan-Mark Wams (jms@cs.vu.nl) */
/* Some things have to be checked for ``exec()'' call's. Therefor
** there is a check routine called ``do_check()'' that will be
** called if the first argument (``argv[0]'') equals ``DO CHECK.''
** Note that there is no way the shell (``/bin/sh'') will set
** ``argv[0]'' to this funny value. (Unless we rename ``test39''
** to ``DO CHECK'' ;-)
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.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)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test39a, (void));
_PROTOTYPE(void test39b, (void));
_PROTOTYPE(void test39c, (void));
_PROTOTYPE(void test39d, (void));
_PROTOTYPE(int do_check, (void));
_PROTOTYPE(void makelongnames, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
char executable[1024];
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
/* If we have to check things, call do_check(). */
if (strcmp(argv[0], "DO CHECK") == 0) exit(do_check());
/* Get the path of the executable. */
strcpy(executable, "../");
strcat(executable, argv[0]);
printf("Test 39 ");
fflush(stdout);
System("rm -rf DIR_39; mkdir DIR_39");
Chdir("DIR_39");
makelongnames();
superuser = (geteuid() == 0);
for (i = 0; i < ITERATIONS; i++) {
test39a();
test39b();
test39c();
test39d();
}
quit();
}
void test39a()
{ /* Test normal operation. */
subtest = 1;
System("rm -rf ../DIR_39/*");
}
void test39b()
{
subtest = 2;
System("rm -rf ../DIR_39/*");
}
void test39c()
{
subtest = 3;
System("rm -rf ../DIR_39/*");
}
/* Open fds 3, 4, 5 and 6. Set FD_CLOEXEC on 5 and 6. Exclusively lock the
** first 10 bytes of fd no. 3. Shared lock fd no. 7. Lock fd no. 8 after
** the fork. Do a ``exec()'' call with a funny argv[0] and check the return
** value.
*/
void test39d()
{ /* Test locks with ``fork()'' and ``exec().'' */
int fd3, fd4, fd5, fd6, fd7, fd8;
int stat_loc;
int do_check_retval;
char *argv[2];
struct flock fl;
subtest = 4;
argv[0] = "DO CHECK";
argv[1] = (char *) NULL;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 10;
/* Make a dummy files and open them. */
System("echo 'Great Balls Of Fire!' > file3");
System("echo 'Great Balls Of Fire!' > file4");
System("echo 'Great Balls Of Fire!' > file7");
System("echo 'Great Balls Of Fire!' > file8");
System("echo 'Great Balls Of Fire!' > file");
if ((fd3 = open("file3", O_RDWR)) != 3) e(1);
if ((fd4 = open("file4", O_RDWR)) != 4) e(2);
if ((fd5 = open("file", O_RDWR)) != 5) e(3);
if ((fd6 = open("file", O_RDWR)) != 6) e(4);
if ((fd7 = open("file7", O_RDWR)) != 7) e(5);
if ((fd8 = open("file8", O_RDWR)) != 8) e(6);
/* Set FD_CLOEXEC flags on fd5 and fd6. */
if (fcntl(fd5, F_SETFD, FD_CLOEXEC) == -1) e(7);
if (fcntl(fd6, F_SETFD, FD_CLOEXEC) == -1) e(8);
/* Lock the first ten bytes from fd3 (for writing). */
fl.l_type = F_WRLCK;
if (fcntl(fd3, F_SETLK, &fl) == -1) e(9);
/* Lock (for reading) fd7. */
fl.l_type = F_RDLCK;
if (fcntl(fd7, F_SETLK, &fl) == -1) e(10);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
/* Lock fd8. */
fl.l_type = F_WRLCK;
if (fcntl(fd8, F_SETLK, &fl) == -1) e(11);
/* Check the lock on fd3 and fd7. */
fl.l_type = F_WRLCK;
if (fcntl(fd3, F_GETLK, &fl) == -1) e(12);
if (fl.l_type != F_WRLCK) e(13);
if (fl.l_pid != getppid()) e(14);
fl.l_type = F_WRLCK;
if (fcntl(fd7, F_GETLK, &fl) == -1) e(15);
if (fl.l_type != F_RDLCK) e(16);
if (fl.l_pid != getppid()) e(17);
/* Check FD_CLOEXEC flags. */
if ((fcntl(fd3, F_GETFD) & FD_CLOEXEC) != 0) e(18);
if ((fcntl(fd4, F_GETFD) & FD_CLOEXEC) != 0) e(19);
if ((fcntl(fd5, F_GETFD) & FD_CLOEXEC) != FD_CLOEXEC) e(20);
if ((fcntl(fd6, F_GETFD) & FD_CLOEXEC) != FD_CLOEXEC) e(21);
if ((fcntl(fd7, F_GETFD) & FD_CLOEXEC) != 0) e(22);
if ((fcntl(fd8, F_GETFD) & FD_CLOEXEC) != 0) e(23);
execlp(executable + 3, "DO CHECK", (char *) NULL);
execlp(executable, "DO CHECK", (char *) NULL);
printf("Can't exec %s or %s\n", executable + 3, executable);
exit(0);
default:
wait(&stat_loc);
if (WIFSIGNALED(stat_loc)) e(24); /* Alarm? */
if (WIFEXITED(stat_loc) == 0) {
errct=10000;
quit();
}
}
/* Check the return value of do_check(). */
do_check_retval = WEXITSTATUS(stat_loc);
if ((do_check_retval & 0x11) == 0x11) e(25);
if ((do_check_retval & 0x12) == 0x12) e(26);
if ((do_check_retval & 0x14) == 0x14) e(27);
if ((do_check_retval & 0x18) == 0x18) e(28);
if ((do_check_retval & 0x21) == 0x21) e(29);
if ((do_check_retval & 0x22) == 0x22) e(30);
if ((do_check_retval & 0x24) == 0x24) e(31);
if ((do_check_retval & 0x28) == 0x28) e(32);
if ((do_check_retval & 0x41) == 0x41) e(33);
if ((do_check_retval & 0x42) == 0x42) e(34);
if ((do_check_retval & 0x44) == 0x44) e(35);
if ((do_check_retval & 0x48) == 0x48) e(36);
if ((do_check_retval & 0x81) == 0x81) e(37);
if ((do_check_retval & 0x82) == 0x82) e(38);
if ((do_check_retval & 0x84) == 0x84) e(39);
if ((do_check_retval & 0x88) == 0x88) e(40);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
/* Lock fd8. */
fl.l_type = F_WRLCK;
if (fcntl(fd8, F_SETLK, &fl) == -1) e(41);
execvp(executable + 3, argv);
execvp(executable, argv);
printf("Can't exec %s or %s\n", executable + 3, executable);
exit(0);
default:
wait(&stat_loc);
if (WIFSIGNALED(stat_loc)) e(48); /* Alarm? */
}
/* Check the return value of do_check(). */
do_check_retval = WEXITSTATUS(stat_loc);
if ((do_check_retval & 0x11) == 0x11) e(49);
if ((do_check_retval & 0x12) == 0x12) e(50);
if ((do_check_retval & 0x14) == 0x14) e(51);
if ((do_check_retval & 0x18) == 0x18) e(52);
if ((do_check_retval & 0x21) == 0x21) e(53);
if ((do_check_retval & 0x22) == 0x22) e(54);
if ((do_check_retval & 0x24) == 0x24) e(55);
if ((do_check_retval & 0x28) == 0x28) e(56);
if ((do_check_retval & 0x41) == 0x41) e(57);
if ((do_check_retval & 0x42) == 0x42) e(58);
if ((do_check_retval & 0x44) == 0x44) e(59);
if ((do_check_retval & 0x48) == 0x48) e(60);
if ((do_check_retval & 0x81) == 0x81) e(61);
if ((do_check_retval & 0x82) == 0x82) e(62);
if ((do_check_retval & 0x84) == 0x84) e(63);
if ((do_check_retval & 0x88) == 0x88) e(64);
fl.l_type = F_UNLCK;
if (fcntl(fd3, F_SETLK, &fl) == -1) e(65);
if (fcntl(fd7, F_SETLK, &fl) == -1) e(66);
if (close(fd3) != 0) e(67);
if (close(fd4) != 0) e(68);
if (close(fd5) != 0) e(69);
if (close(fd6) != 0) e(70);
if (close(fd7) != 0) e(71);
if (close(fd8) != 0) e(72);
System("rm -f ../DIR_39/*\n");
}
/* This routine checks that fds 0 through 4, 7 and 8 are open and the rest
** is closed. It also checks if we can lock the first 10 bytes on fd no. 3
** and 4. It should not be possible to lock fd no. 3, but it should be
** possible to lock fd no. 4. See ``test39d()'' for usage of this routine.
*/
int do_check()
{
int i;
int retval = 0;
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 10;
/* All std.. are open. */
if (fcntl(0, F_GETFD) == -1) retval |= 0x11;
if (fcntl(1, F_GETFD) == -1) retval |= 0x11;
if (fcntl(2, F_GETFD) == -1) retval |= 0x11;
/* Fd no. 3, 4, 7 and 8 are open. */
if (fcntl(3, F_GETFD) == -1) retval |= 0x12;
if (fcntl(4, F_GETFD) == -1) retval |= 0x12;
if (fcntl(7, F_GETFD) == -1) retval |= 0x12;
/* Fd no. 5, 6 and 9 trough OPEN_MAX are closed. */
if (fcntl(5, F_GETFD) != -1) retval |= 0x14;
if (fcntl(6, F_GETFD) != -1) retval |= 0x14;
for (i = 9; i < OPEN_MAX; i++)
if (fcntl(i, F_GETFD) != -1) retval |= 0x18;
#if 0
/* Fd no. 3 is WRLCKed. */
fl.l_type = F_WRLCK;
if (fcntl(3, F_SETLK, &fl) != -1) retval |= 0x21;
if (errno != EACCES && errno != EAGAIN) retval |= 0x22;
fl.l_type = F_RDLCK;
if (fcntl(3, F_SETLK, &fl) != -1) retval |= 0x24;
if (errno != EACCES && errno != EAGAIN) retval |= 0x22;
fl.l_type = F_RDLCK;
if (fcntl(3, F_GETLK, &fl) == -1) retval |= 0x28;
if (fl.l_type != F_WRLCK) retval |= 0x28;
if (fl.l_pid != getpid()) retval |= 0x28;
fl.l_type = F_WRLCK;
if (fcntl(3, F_GETLK, &fl) == -1) retval |= 0x28;
if (fl.l_type != F_WRLCK) retval |= 0x28;
if (fl.l_pid != getpid()) retval |= 0x28;
#endif
/* Fd no. 4 is not locked. */
fl.l_type = F_WRLCK;
if (fcntl(4, F_SETLK, &fl) == -1) retval |= 0x41;
if (fcntl(4, F_GETLK, &fl) == -1) retval |= 0x42;
#if 0 /* XXX - see test7.c */
if (fl.l_type != F_WRLCK) retval |= 0x42;
if (fl.l_pid != getpid()) retval |= 0x42;
#endif /* 0 */
/* Fd no. 8 is locked after the fork, it is ours. */
fl.l_type = F_WRLCK;
if (fcntl(8, F_SETLK, &fl) == -1) retval |= 0x44;
if (fcntl(8, F_GETLK, &fl) == -1) retval |= 0x48;
#if 0 /* XXX - see test7.c */
if (fl.l_type != F_WRLCK) retval |= 0x48;
if (fl.l_pid != getpid()) retval |= 0x48;
#endif /* 0 */
#if 0
/* Fd no. 7 is RDLCKed. */
fl.l_type = F_WRLCK;
if (fcntl(7, F_SETLK, &fl) != -1) retval |= 0x81;
if (errno != EACCES && errno != EAGAIN) retval |= 0x82;
fl.l_type = F_RDLCK;
if (fcntl(7, F_SETLK, &fl) == -1) retval |= 0x84;
fl.l_type = F_RDLCK;
if (fcntl(7, F_GETLK, &fl) == -1) retval |= 0x88;
if (fl.l_type != F_UNLCK) retval |= 0x88;
fl.l_type = F_WRLCK;
if (fcntl(7, F_GETLK, &fl) == -1) retval |= 0x88;
if (fl.l_type != F_RDLCK) retval |= 0x88;
if (fl.l_pid != getppid()) retval |= 0x88;
#endif
return retval;
}
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)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_39");
if (errct == 0) {
printf("ok\n");
exit(0);
} else if (errct < 10000) {
printf("%d errors\n", errct);
exit(1);
} else {
printf("errors\n");
exit(2);
}
}

104
test/test4.c Normal file
View File

@@ -0,0 +1,104 @@
/* test 4 */
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
pid_t pid0, pid1, pid2, pid3;
int s, i, fd, nextb, errct = 0;
char *tempfile = "test4.temp";
char buf[1024];
extern int errno;
_PROTOTYPE(int main, (void));
_PROTOTYPE(void subr, (void));
_PROTOTYPE(void nofork, (void));
_PROTOTYPE(void quit, (void));
int main()
{
int k;
printf("Test 4 ");
fflush(stdout); /* have to flush for child's benefit */
system("rm -rf DIR_04; mkdir DIR_04");
chdir("DIR_04");
creat(tempfile, 0777);
for (k = 0; k < 20; k++) {
subr();
}
unlink(tempfile);
quit();
return(-1); /* impossible */
}
void subr()
{
if ( (pid0 = fork()) != 0) {
/* Parent 0 */
if (pid0 < 0) nofork();
if ( (pid1 = fork()) != 0) {
/* Parent 1 */
if (pid1 < 0) nofork();
if ( (pid2 = fork()) != 0) {
/* Parent 2 */
if (pid2 < 0) nofork();
if ( (pid3 = fork()) != 0) {
/* Parent 3 */
if (pid3 < 0) nofork();
for (i = 0; i < 10000; i++);
kill(pid2, 9);
kill(pid1, 9);
kill(pid0, 9);
wait(&s);
wait(&s);
wait(&s);
wait(&s);
} else {
fd = open(tempfile, O_RDONLY);
lseek(fd, 20480L * nextb, 0);
for (i = 0; i < 10; i++) read(fd, buf, 1024);
nextb++;
close(fd);
exit(0);
}
} else {
while (1) getpid();
}
} else {
while (1) getpid();
}
} else {
while (1) getpid();
}
}
void nofork()
{
int e = errno;
printf("Fork failed: %s (%d)\n",strerror(e),e);
exit(1);
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

279
test/test40.c Normal file
View File

@@ -0,0 +1,279 @@
/* test40: lseek() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <time.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 subtest = 1;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test40a, (void));
_PROTOTYPE(void test40b, (void));
_PROTOTYPE(void test40c, (void));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
void main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 40 ");
fflush(stdout);
System("rm -rf DIR_40; mkdir DIR_40");
Chdir("DIR_40");
for (i = 0; i < 10; i++) {
if (m & 0001) test40a();
if (m & 0002) test40b();
if (m & 0004) test40c();
}
quit();
}
void test40a()
{ /* Test normal operation. */
int fd;
char buf[20];
int i, j;
struct stat st;
subtest = 1;
System("rm -rf ../DIR_40/*");
System("echo -n hihaho > hihaho");
if ((fd = open("hihaho", O_RDONLY)) != 3) e(1);
if (lseek(fd, (off_t) 3, SEEK_SET) != (off_t) 3) e(2);
if (read(fd, buf, 1) != 1) e(3);
if (buf[0] != 'a') e(4);
if (lseek(fd, (off_t) - 1, SEEK_END) != 5) e(5);
if (read(fd, buf, 1) != 1) e(6);
if (buf[0] != 'o') e(7);
/* Seek past end of file. */
if (lseek(fd, (off_t) 1000, SEEK_END) != 1006) e(8);
if (read(fd, buf, 1) != 0) e(9);
/* Lseek() should not extend the file. */
if (fstat(fd, &st) != 0) e(10);
if (st.st_size != (off_t) 6) e(11);
if (close(fd) != 0) e(12);
/* Probeer lseek met write. */
if ((fd = open("hihaho", O_WRONLY)) != 3) e(13);
if (lseek(fd, (off_t) 3, SEEK_SET) != (off_t) 3) e(14);
if (write(fd, "e", 1) != 1) e(15);
if (lseek(fd, (off_t) 1000, SEEK_END) != 1006) e(16);
/* Lseek() should not extend the file. */
if (fstat(fd, &st) != 0) e(17);
if (st.st_size != (off_t) 6) e(18);
if (write(fd, "e", 1) != 1) e(19);
/* Lseek() and a subsequent write should! */
if (fstat(fd, &st) != 0) e(20);
if (st.st_size != (off_t) 1007) e(21);
if (close(fd) != 0) e(22);
/* Check the file, it should start with hiheho. */
if ((fd = open("hihaho", O_RDONLY)) != 3) e(23);
if (read(fd, buf, 6) != 6) e(24);
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 test40b()
{
int fd1, fd2, fd3;
int stat_loc;
subtest = 2;
System("rm -rf ../DIR_40/*");
/* See if childs lseek() is effecting the parent. * See also if
* lseeking() on same file messes things up. */
/* Creat a file of 11 bytes. */
if ((fd1 = open("santa", O_WRONLY | O_CREAT, 0777)) != 3) e(1);
if (write(fd1, "ho ho ho ho", 11) != 11) e(2);
if (close(fd1) != 0) e(3);
/* 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 the new offsets are correct. */
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 3) e(14);
if (lseek(fd2, (off_t) 0, SEEK_CUR) != 5) e(15);
if (lseek(fd3, (off_t) 0, SEEK_CUR) != 7) e(16);
/* Close the file. */
if (close(fd1) != 0) e(17);
if (close(fd2) != 0) e(18);
if (close(fd3) != 0) e(19);
}
void test40c()
{ /* Test error returns. */
int fd;
int tube[2];
int i, stat_loc;
subtest = 3;
System("rm -rf ../DIR_40/*");
/* Fifo's can't be lseeked(). */
Mkfifo("fifo");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(3); /* Try for max 3 secs. */
if ((fd = open("fifo", O_RDONLY)) != 3) e(1);
if (lseek(fd, (off_t) 0, SEEK_SET) != (off_t) - 1) e(2);
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);
}
/* Pipes can't be lseeked() eigther. */
if (pipe(tube) != 0) e(8);
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? */
}
/* Close the pipe. */
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);
/* EBADF for bad fides. */
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);
}
}
void e(n)
int n;
{
int err_num = errno; /* Save in case printf clobbers it. */
printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
errno = err_num;
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
errno = 0;
}
void quit()
{
Chdir("..");
System("rm -rf DIR_40");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

413
test/test5.c Normal file
View File

@@ -0,0 +1,413 @@
/* test 5 */
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#define ITERATIONS 2
#define MAX_ERROR 4
int errct;
int subtest;
int zero[1024];
int sigmap[5] = {9, 10, 11};
_PROTOTYPE(int main, (int argc, char *argv[]));
_PROTOTYPE(void test5a, (void));
_PROTOTYPE(void parent, (int childpid));
_PROTOTYPE(void child, (int parpid));
_PROTOTYPE(void func1, (int s));
_PROTOTYPE(void func8, (int s));
_PROTOTYPE(void func10, (int s));
_PROTOTYPE(void func11, (int s));
_PROTOTYPE(void test5b, (void));
_PROTOTYPE(void test5c, (void));
_PROTOTYPE(void test5d, (void));
_PROTOTYPE(void test5e, (void));
_PROTOTYPE(void test5f, (void));
_PROTOTYPE(void test5g, (void));
_PROTOTYPE(void funcalrm, (int s));
_PROTOTYPE(void test5h, (void));
_PROTOTYPE(void test5i, (void));
_PROTOTYPE(void ex, (void));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
#ifdef _ANSI
void (*Signal(int _sig, void (*_func)(int)))(int);
#define SIG_ZERO ((void (*)(int))0) /* default signal handling */
#else
sighandler_t Signal();
/* void (*Signal()) (); */
#define SIG_ZERO ((void (*)())0) /* default signal handling */
#endif
_VOLATILE int childsigs, parsigs, alarms;
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0x7777;
printf("Test 5 ");
fflush(stdout); /* have to flush for child's benefit */
system("rm -rf DIR_05; mkdir DIR_05");
chdir("DIR_05");
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test5a();
if (m & 0002) test5b();
if (m & 0004) test5c();
if (m & 0010) test5d();
if (m & 0020) test5e();
if (m & 0040) test5f();
if (m & 0100) test5g();
if (m & 0200) test5h();
if (m & 0400) test5i();
}
quit();
return(-1); /* impossible */
}
void test5a()
{
int parpid, childpid, flag, *zp;
subtest = 0;
flag = 0;
for (zp = &zero[0]; zp < &zero[1024]; zp++)
if (*zp != 0) flag = 1;
if (flag) e(0); /* check if bss is cleared to 0 */
if (Signal(1, func1) == SIG_ERR) e(1);
if (Signal(10, func10) < SIG_ZERO) e(2);
parpid = getpid();
if (childpid = fork()) {
if (childpid < 0) ex();
parent(childpid);
} else {
child(parpid);
}
if (Signal(1, SIG_DFL) < SIG_ZERO) e(4);
if (Signal(10, SIG_DFL) < SIG_ZERO) e(5);
}
void parent(childpid)
int childpid;
{
int i, pid;
for (i = 0; i < 3; i++) {
if (kill(childpid, 1) < 0) e(6);
while (parsigs == 0);
parsigs--;
}
if ( (pid = wait(&i)) < 0) e(7);
if (i != 256 * 6) e(8);
}
void child(parpid)
int parpid;
{
int i;
for (i = 0; i < 3; i++) {
while (childsigs == 0);
childsigs--;
if (kill(parpid, 10) < 0) e(9);
}
exit(6);
}
void func1(s)
int s; /* for ANSI */
{
if (Signal(1, func1) < SIG_ZERO) e(10);
childsigs++;
}
void func8(s)
int s;
{
}
void func10(s)
int s; /* for ANSI */
{
if (Signal(10, func10) < SIG_ZERO) e(11);
parsigs++;
}
void func11(s)
int s; /* for ANSI */
{
e(38);
}
void test5b()
{
int cpid, n, pid;
subtest = 1;
if ((pid = fork())) {
if (pid < 0) ex();
if ((pid = fork())) {
if (pid < 0) ex();
if (cpid = fork()) {
if (cpid < 0) ex();
if (kill(cpid, 9) < 0) e(12);
if (wait(&n) < 0) e(13);
if (wait(&n) < 0) e(14);
if (wait(&n) < 0) e(15);
} else {
pause();
while (1);
}
} else {
exit(0);
}
} else {
exit(0);
}
}
void test5c()
{
int n, i, pid, wpid;
/* Test exit status codes for processes killed by signals. */
subtest = 3;
for (i = 0; i < 2; i++) {
if (pid = fork()) {
if (pid < 0) ex();
sleep(2); /* wait for child to pause */
if (kill(pid, sigmap[i]) < 0) {
e(20);
exit(1);
}
if ((wpid = wait(&n)) < 0) e(21);
if ((n & 077) != sigmap[i]) e(22);
if (pid != wpid) e(23);
} else {
pause();
exit(0);
}
}
}
void test5d()
{
/* Test alarm */
int i;
subtest = 4;
alarms = 0;
for (i = 0; i < 8; i++) {
Signal(SIGALRM, funcalrm);
alarm(1);
pause();
if (alarms != i + 1) e(24);
}
}
void test5e()
{
/* When a signal knocks a processes out of WAIT or PAUSE, it is supposed to
* get EINTR as error status. Check that.
*/
int n, j;
subtest = 5;
if (Signal(8, func8) < SIG_ZERO) e(25);
if (n = fork()) {
/* Parent must delay to give child a chance to pause. */
if (n < 0) ex();
sleep(1);
if (kill(n, 8) < 0) e(26);
if (wait(&n) < 0) e(27);
if (Signal(8, SIG_DFL) < SIG_ZERO) e(28);
} else {
j = pause();
if (errno != EINTR && -errno != EINTR) e(29);
exit(0);
}
}
void test5f()
{
int i, j, k, n;
subtest = 6;
if (getuid() != 0) return;
n = fork();
if (n < 0) ex();
if (n) {
wait(&i);
i = (i >> 8) & 0377;
if (i != (n & 0377)) e(30);
} else {
i = getgid();
j = getegid();
k = (i + j + 7) & 0377;
if (setgid(k) < 0) e(31);
if (getgid() != k) e(32);
if (getegid() != k) e(33);
i = getuid();
j = geteuid();
k = (i + j + 1) & 0377;
if (setuid(k) < 0) e(34);
if (getuid() != k) e(35);
if (geteuid() != k) e(36);
i = getpid() & 0377;
if (wait(&j) != -1) e(37);
exit(i);
}
}
void test5g()
{
int n;
subtest = 7;
Signal(11, func11);
Signal(11, SIG_IGN);
n = getpid();
if (kill(n, 11) != 0) e(1);
Signal(11, SIG_DFL);
}
void funcalrm(s)
int s; /* for ANSI */
{
alarms++;
}
void test5h()
{
/* When a signal knocks a processes out of PIPE, it is supposed to
* get EINTR as error status. Check that.
*/
int n, j, fd[2];
subtest = 8;
unlink("XXX.test5");
if (Signal(8, func8) < SIG_ZERO) e(1);
pipe(fd);
if (n = fork()) {
/* Parent must delay to give child a chance to pause. */
if (n < 0) ex();
while (access("XXX.test5", 0) != 0) /* just wait */ ;
sleep(1);
unlink("XXX.test5");
if (kill(n, 8) < 0) e(2);
if (wait(&n) < 0) e(3);
if (Signal(8, SIG_DFL) < SIG_ZERO) e(4);
if (close(fd[0]) != 0) e(5);
if (close(fd[1]) != 0) e(6);
} else {
if (creat("XXX.test5", 0777) < 0) e(7);
j = read(fd[0], (char *) &n, 1);
if (errno != EINTR) e(8);
exit(0);
}
}
void test5i()
{
int fd[2], pid, buf[10], n;
subtest = 9;
pipe(fd);
unlink("XXXxxxXXX");
if ( (pid = fork())) {
/* Parent */
/* Wait until child has started and has created the XXXxxxXXX file. */
while (access("XXXxxxXXX", 0) != 0) /* loop */ ;
sleep(1);
if (kill(pid, SIGKILL) != 0) e(1);
if (wait(&n) < 0) e(2);
if (close(fd[0]) != 0) e(3);
if (close(fd[1]) != 0) e(4);
} else {
if (creat("XXXxxxXXX", 0777) < 0) e(5);
read(fd[0], (char *) buf, 1);
e(5); /* should be killed by signal and not get here */
}
unlink("XXXxxxXXX");
}
void ex()
{
int e = errno;
printf("Fork failed: %s (%d)\n", strerror(e), e);
exit(1);
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}
#ifdef _ANSI
void (*Signal(int a, void (*b)(int)))(int)
#else
sighandler_t Signal(a, b)
int a;
void (*b)();
#endif
{
if (signal(a, (void (*) ()) b) == (void (*)()) -1)
return(SIG_ERR);
else
return(SIG_ZERO);
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

218
test/test6.c Normal file
View File

@@ -0,0 +1,218 @@
/* test 6 */
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define MAX_ERROR 4
int errct;
int subtest = 1;
int zilch[5000];
char curdir[PATH_MAX];
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test6a, (void));
_PROTOTYPE(void test6b, (void));
_PROTOTYPE(void test6c, (void));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (geteuid() == 0 || getuid() == 0) {
printf("Test 6 cannot run as root; test aborted\n");
exit(1);
}
if (argc == 2) m = atoi(argv[1]);
printf("Test 6 ");
fflush(stdout);
getcwd(curdir, PATH_MAX);
system("rm -rf DIR_06; mkdir DIR_06");
chdir("DIR_06");
for (i = 0; i < 70; i++) {
if (m & 00001) test6a();
if (m & 00002) test6b();
if (m & 00004) test6c();
}
quit();
return(-1); /* impossible */
}
void test6a()
{
/* Test sbrk() and brk(). */
char *addr, *addr2, *addr3;
int i, del, click, click2;
subtest = 1;
addr = sbrk(0);
addr = sbrk(0); /* force break to a click boundary */
for (i = 0; i < 10; i++) sbrk(7 * i);
for (i = 0; i < 10; i++) sbrk(-7 * i);
if (sbrk(0) != addr) e(1);
sbrk(30);
if (brk(addr) != 0) e(2);
if (sbrk(0) != addr) e(3);
del = 0;
do {
del++;
brk(addr + del);
addr2 = sbrk(0);
} while (addr2 == addr);
click = addr2 - addr;
sbrk(-1);
if (sbrk(0) != addr) e(4);
brk(addr);
if (sbrk(0) != addr) e(5);
del = 0;
do {
del++;
brk(addr - del);
addr3 = sbrk(0);
} while (addr3 == addr);
click2 = addr - addr3;
sbrk(1);
if (sbrk(0) != addr) e(6);
brk(addr);
if (sbrk(0) != addr) e(8);
if (click != click2) e(9);
brk(addr + 2 * click);
if (sbrk(0) != addr + 2 * click) e(10);
sbrk(3 * click);
if (sbrk(0) != addr + 5 * click) e(11);
sbrk(-5 * click);
if (sbrk(0) != addr) e(12);
}
void test6b()
{
int i, err;
subtest = 2;
signal(SIGQUIT, SIG_IGN);
err = 0;
for (i = 0; i < 5000; i++)
if (zilch[i] != 0) err++;
if (err > 0) e(1);
kill(getpid(), SIGQUIT);
}
void test6c()
{
/* Test mknod, chdir, chmod, chown, access. */
int i, j;
struct stat s;
subtest = 3;
if (getuid() != 0) return;
for (j = 0; j < 2; j++) {
umask(0);
if (chdir("/") < 0) e(1);
if (mknod("dir", 040700, 0) < 0) e(2);
if (link("/", "/dir/..") < 0) e(3);
if (mknod("T3a", 0777, 0) < 0) e(4);
if (mknod("/dir/T3b", 0777, 0) < 0) e(5);
if (mknod("dir/T3c", 0777, 0) < 0) e(6);
if ((i = open("/dir/T3b", 0)) < 0) e(7);
if (close(i) < 0) e(8);
if ((i = open("dir/T3c", O_RDONLY)) < 0) e(9);
if (close(i) < 0) e(10);
if (chdir("dir") < 0) e(11);
if ((i = open("T3b", 0)) < 0) e(12);
if (close(i) < 0) e(13);
if ((i = open("../T3a", O_RDONLY)) < 0) e(14);
if (close(i) < 0) e(15);
if ((i = open("../dir/../dir/../dir/../dir/../dir/T3c", O_RDONLY)) < 0)
e(16);
if (close(i) < 0) e(17);
if (chmod("../dir/../dir/../dir/../dir/../T3a", 0123) < 0) e(18);
if (stat("../dir/../dir/../dir/../T3a", &s) < 0) e(19);
if ((s.st_mode & 077777) != 0123) e(20);
if (chmod("../dir/../dir/../T3a", 0456) < 0) e(21);
if (stat("../T3a", &s) < 0) e(22);
if ((s.st_mode & 077777) != 0456) e(23);
if (chown("../dir/../dir/../T3a", 20, 30) < 0) e(24);
if (stat("../T3a", &s) < 0) e(25);
if (s.st_uid != 20) e(26);
if (s.st_gid != 30) e(27);
if ((i = open("/T3c", O_RDONLY)) >= 0) e(28);
if ((i = open("/T3a", O_RDONLY)) < 0) e(29);
if (close(i) < 0) e(30);
if (access("/T3a", 4) < 0) e(31);
if (access("/dir/T3b", 4) < 0) e(32);
if (access("/dir/T3d", 4) >= 0) e(33);
if (unlink("T3b") < 0) e(34);
if (unlink("T3c") < 0) e(35);
if (unlink("..") < 0) e(36);
if (chdir("/") < 0) e(37);
if (unlink("dir") < 0) e(38);
if (unlink("/T3a") < 0) e(39);
}
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
chdir(curdir);
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

705
test/test7.c Normal file
View File

@@ -0,0 +1,705 @@
/* POSIX test program (7). Author: Andy Tanenbaum */
/* The following POSIX calls are tested:
* pipe(), mkfifo(), fcntl()
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define ITERATIONS 4
#define MAX_ERROR 4
#define ITEMS 32
#define READ 10
#define WRITE 20
#define UNLOCK 30
#define U 70
#define L 80
char buf[ITEMS] = {0,1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9};
int subtest, errct, xfd;
int whence = SEEK_SET, func_code = F_SETLK;
extern char **environ;
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test7a, (void));
_PROTOTYPE(void test7b, (void));
_PROTOTYPE(void test7c, (void));
_PROTOTYPE(void test7d, (void));
_PROTOTYPE(void test7e, (void));
_PROTOTYPE(void test7f, (void));
_PROTOTYPE(void test7g, (void));
_PROTOTYPE(void test7h, (void));
_PROTOTYPE(void test7i, (void));
_PROTOTYPE(void test7j, (void));
_PROTOTYPE(void cloexec_test, (void));
_PROTOTYPE(int set, (int how, int first, int last));
_PROTOTYPE(int locked, (int b));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void sigfunc, (int s));
_PROTOTYPE(void quit, (void));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
if (m == 0) cloexec_test(); /* important; do not remove this! */
printf("Test 7 ");
fflush(stdout);
system("rm -rf DIR_07; mkdir DIR_07");
chdir("DIR_07");
for (i = 0; i < ITERATIONS; i++) {
if (m & 00001) test7a();
if (m & 00002) test7b();
if (m & 00004) test7c();
if (m & 00010) test7d();
if (m & 00020) test7e();
if (m & 00040) test7f();
if (m & 00100) test7g();
if (m & 00200) test7h();
if (m & 00400) test7i();
if (m & 01000) test7j();
}
quit();
return(-1); /* impossible */
}
void test7a()
{
/* Test pipe(). */
int i, fd[2], ect;
char buf2[ITEMS+1];
/* Create a pipe, write on it, and read it back. */
subtest = 1;
if (pipe(fd) != 0) e(1);
if (write(fd[1], buf, ITEMS) != ITEMS) e(2);
buf2[0] = 0;
if (read(fd[0], buf2, ITEMS+1) != ITEMS) e(3);
ect = 0;
for (i = 0; i < ITEMS; i++) if (buf[i] != buf2[i]) ect++;
if (ect != 0) e(4);
if (close(fd[0]) != 0) e(5);
if (close(fd[1]) != 0) e(6);
/* Error test. Keep opening pipes until it fails. Check error code. */
errno = 0;
while (1) {
if (pipe(fd) < 0) break;
}
if (errno != EMFILE) e(7);
/* Close all the pipes. */
for (i = 3; i < OPEN_MAX; i++) close(i);
}
void test7b()
{
/* Test mkfifo(). */
int fdr, fdw, status;
char buf2[ITEMS+1];
int efork;
/* Create a fifo, write on it, and read it back. */
subtest = 2;
if (mkfifo("T7.b", 0777) != 0) e(1);
switch (fork()) {
case -1:
efork = errno;
printf("Fork failed: %s (%d)\n", strerror(efork), efork);
exit(1);
case 0:
/* Child reads from the fifo. */
if ( (fdr = open("T7.b", O_RDONLY)) < 0) e(5);
if (read(fdr, buf2, ITEMS+1) != ITEMS) e(6);
if (strcmp(buf, buf2) != 0) e(7);
if (close(fdr) != 0) e(8);
exit(0);
default:
/* Parent writes on the fifo. */
if ( (fdw = open("T7.b", O_WRONLY)) < 0) e(2);
if (write(fdw, buf, ITEMS) != ITEMS) e(3);
wait(&status);
if (close(fdw) != 0) e(4);
}
/* Check some error conditions. */
if (mkfifo("T7.b", 0777) != -1) e(9);
errno = 0;
if (mkfifo("a/b/c", 0777) != -1) e(10);
if (errno != ENOENT) e(11);
errno = 0;
if (mkfifo("", 0777) != -1) e(12);
if (errno != ENOENT) e(13);
errno = 0;
if (mkfifo("T7.b/x", 0777) != -1) e(14);
if (errno != ENOTDIR) e(15);
if (unlink("T7.b") != 0) e(16);
/* Now check fifos and the O_NONBLOCK flag. */
if (mkfifo("T7.b", 0600) != 0) e(17);
errno = 0;
if (open("T7.b", O_WRONLY | O_NONBLOCK) != -1) e(18);
if (errno != ENXIO) e(19);
if ( (fdr = open("T7.b", O_RDONLY | O_NONBLOCK)) < 0) e(20);
if (fork()) {
/* Parent reads from fdr. */
wait(&status); /* but first make sure writer has already run*/
if ( ( (status>>8) & 0377) != 77) e(21);
if (read(fdr, buf2, ITEMS+1) != ITEMS) e(22);
if (strcmp(buf, buf2) != 0) e(23);
if (close(fdr) != 0) e(24);
} else {
/* Child opens the fifo for writing and writes to it. */
if ( (fdw = open("T7.b", O_WRONLY | O_NONBLOCK)) < 0) e(25);
if (write(fdw, buf, ITEMS) != ITEMS) e(26);
if (close(fdw) != 0) e(27);
exit(77);
}
if (unlink("T7.b") != 0) e(28);
}
void test7c()
{
/* Test fcntl(). */
int fd, m, s, newfd, newfd2;
struct stat stat1, stat2, stat3;
subtest = 3;
errno = -100;
if ( (fd = creat("T7.c", 0777)) < 0) e(1);
/* Turn the per-file-descriptor flags on and off. */
if (fcntl(fd, F_GETFD) != 0) e(2); /* FD_CLOEXEC is initially off */
if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) e(3);/* turn it on */
if (fcntl(fd, F_GETFD) != FD_CLOEXEC) e(4); /* should be on now */
if (fcntl(fd, F_SETFD, 0) != 0) e(5); /* turn it off */
if (fcntl(fd, F_GETFD) != 0) e(6); /* should be off now */
/* Turn the open-file-description flags on and off. Start with O_APPEND. */
m = O_WRONLY;
if (fcntl(fd, F_GETFL) != m) e(7); /* O_APPEND, O_NONBLOCK are off */
if (fcntl(fd, F_SETFL, O_APPEND) != 0) e(8); /* turn on O_APPEND */
if (fcntl(fd, F_GETFL) != (O_APPEND | m)) e(9);/* should be on now */
if (fcntl(fd, F_SETFL, 0) != 0) e(10); /* turn it off */
if (fcntl(fd, F_GETFL) != m) e(11); /* should be off now */
/* Turn the open-file-description flags on and off. Now try O_NONBLOCK. */
if (fcntl(fd, F_SETFL, O_NONBLOCK) != 0) e(12); /* turn on O_NONBLOCK */
if (fcntl(fd, F_GETFL) != (O_NONBLOCK | m)) e(13); /* should be on now */
if (fcntl(fd, F_SETFL, 0) != 0) e(14); /* turn it off */
if (fcntl(fd, F_GETFL) != m) e(15); /* should be off now */
/* Now both at once. */
if (fcntl(fd, F_SETFL, O_APPEND|O_NONBLOCK) != 0) e(16);
if (fcntl(fd, F_GETFL) != (O_NONBLOCK | O_APPEND | m)) e(17);
if (fcntl(fd, F_SETFL, 0) != 0) e(18);
if (fcntl(fd, F_GETFL) != m) e(19);
/* Now test F_DUPFD. */
if ( (newfd = fcntl(fd, F_DUPFD, 0)) != 4) e(20); /* 0-4 open */
if ( (newfd2 = fcntl(fd, F_DUPFD, 0)) != 5) e(21); /* 0-5 open */
if (close(newfd) != 0) e(22); /* 0-3, 5 open */
if ( (newfd = fcntl(fd, F_DUPFD, 0)) != 4) e(23); /* 0-5 open */
if (close(newfd) != 0) e(24); /* 0-3, 5 open */
if ( (newfd = fcntl(fd, F_DUPFD, 5)) != 6) e(25); /* 0-3, 5, 6 open */
if (close(newfd2) != 0) e(26); /* 0-3, 6 open */
/* O_APPEND should be inherited, but FD_CLOEXEC should be cleared. Check. */
if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) e(26);/* turn FD_CLOEXEC on */
if (fcntl(fd, F_SETFL, O_APPEND) != 0) e(27); /* turn O_APPEND on */
if ( (newfd2 = fcntl(fd, F_DUPFD, 10)) != 10) e(28); /* 0-3, 6, 10 open */
if (fcntl(newfd2, F_GETFD) != 0) e(29); /* FD_CLOEXEC must be 0 */
if (fcntl(newfd2, F_GETFL) != (O_APPEND | m)) e(30); /* O_APPEND set */
if (fcntl(fd, F_SETFD, 0) != 0) e(31);/* turn FD_CLOEXEC off */
/* Check if newfd and newfd2 are the same inode. */
if (fstat(fd, &stat1) != 0) e(32);
if (fstat(fd, &stat2) != 0) e(33);
if (fstat(fd, &stat3) != 0) e(34);
if (stat1.st_dev != stat2.st_dev) e(35);
if (stat1.st_dev != stat3.st_dev) e(36);
if (stat1.st_ino != stat2.st_ino) e(37);
if (stat1.st_ino != stat3.st_ino) e(38);
/* Now check on the FD_CLOEXEC flag. Set it for fd (3) and newfd2 (10) */
if (fd != 3 || newfd2 != 10 || newfd != 6) e(39);
if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) e(40); /* close 3 on exec */
if (fcntl(newfd2, F_SETFD, FD_CLOEXEC) != 0) e(41); /* close 10 on exec */
if (fcntl(newfd, F_SETFD, 0) != 0) e(42); /* don't close 6 */
if (fork()) {
wait(&s); /* parent just waits */
if (WEXITSTATUS(s) != 0) e(43);
} else {
execle("../test7", "test7", "0", (char *) 0, environ);
exit(1); /* the impossible never happens, right? */
}
/* Finally, close all the files. */
if (fcntl(fd, F_SETFD, 0) != 0) e(44); /* FD_CLOEXEC off */
if (fcntl(newfd2, F_SETFD, 0) != 0) e(45); /* FD_CLOEXEC off */
if (close(fd) != 0) e(46);
if (close(newfd) != 0) e(47);
if (close(newfd2) != 0) e(48);
}
void test7d()
{
/* Test file locking. */
subtest = 4;
if ( (xfd = creat("T7.d", 0777)) != 3) e(1);
close(xfd);
if ( (xfd = open("T7.d", O_RDWR)) < 0) e(2);
if (write(xfd, buf, ITEMS) != ITEMS) e(3);
if (set(WRITE, 0, 3) != 0) e(4);
if (set(WRITE, 5, 9) != 0) e(5);
if (set(UNLOCK, 0, 3) != 0) e(6);
if (set(UNLOCK, 4, 9) != 0) e(7);
if (set(READ, 1, 4) != 0) e(8);
if (set(READ, 4, 7) != 0) e(9);
if (set(UNLOCK, 4, 7) != 0) e(10);
if (set(UNLOCK, 1, 4) != 0) e(11);
if (set(WRITE, 0, 3) != 0) e(12);
if (set(WRITE, 5, 7) != 0) e(13);
if (set(WRITE, 9 ,10) != 0) e(14);
if (set(UNLOCK, 0, 4) != 0) e(15);
if (set(UNLOCK, 0, 7) != 0) e(16);
if (set(UNLOCK, 0, 2000) != 0) e(17);
if (set(WRITE, 0, 3) != 0) e(18);
if (set(WRITE, 5, 7) != 0) e(19);
if (set(WRITE, 9 ,10) != 0) e(20);
if (set(UNLOCK, 0, 100) != 0) e(21);
if (set(WRITE, 0, 9) != 0) e(22);
if (set(UNLOCK, 8, 9) != 0) e(23);
if (set(UNLOCK, 0, 2) != 0) e(24);
if (set(UNLOCK, 5, 5) != 0) e(25);
if (set(UNLOCK, 4, 6) != 0) e(26);
if (set(UNLOCK, 3, 3) != 0) e(27);
if (set(UNLOCK, 7, 7) != 0) e(28);
if (set(WRITE, 0, 10) != 0) e(29);
if (set(UNLOCK, 0, 1000) != 0) e(30);
/* Up until now, all locks have been disjoint. Now try conflicts. */
if (set(WRITE, 0, 4) != 0) e(31);
if (set(WRITE, 4, 7) != 0) e(32); /* owner may lock same byte twice */
if (set(WRITE, 5, 10) != 0) e(33);
if (set(UNLOCK, 0, 11) != 0) e(34);
/* File is now unlocked. Length 0 means whole file. */
if (set(WRITE, 2, 1) != 0) e(35); /* this locks whole file */
if (set(WRITE, 9,10) != 0) e(36); /* a process can relock its file */
if (set(WRITE, 3, 3) != 0) e(37);
if (set(UNLOCK, 0, -1) != 0) e(38); /* file is now unlocked. */
/* Test F_GETLK. */
if (set(WRITE, 2, 3) != 0) e(39);
if (locked(1) != U) e(40);
if (locked(2) != L) e(41);
if (locked(3) != L) e(42);
if (locked(4) != U) e(43);
if (set(UNLOCK, 2, 3) != 0) e(44);
if (locked(2) != U) e(45);
if (locked(3) != U) e(46);
close(xfd);
}
void test7e()
{
/* Test to see if SETLKW blocks as it should. */
int pid, s;
subtest = 5;
if ( (xfd = creat("T7.e", 0777)) != 3) e(1);
if (close(xfd) != 0) e(2);
if ( (xfd = open("T7.e", O_RDWR)) < 0) e(3);
if (write(xfd, buf, ITEMS) != ITEMS) e(4);
if (set(WRITE, 0, 3) != 0) e(5);
if ( (pid = fork()) ) {
/* Parent waits until child has started before signaling it. */
while (access("T7.e1", 0) != 0) ;
unlink("T7.e1");
sleep(1);
if (kill(pid, SIGKILL) < 0) e(6);
if (wait(&s) != pid) e(7);
} else {
/* Child tries to lock and should block. */
if (creat("T7.e1", 0777) < 0) e(8);
func_code = F_SETLKW;
if (set(WRITE, 0, 3) != 0) e(9); /* should block */
errno = -1000;
e(10); /* process should be killed by signal */
exit(0); /* should never happen */
}
close(xfd);
}
void test7f()
{
/* Test to see if SETLKW gives EINTR when interrupted. */
int pid, s;
subtest = 6;
if ( (xfd = creat("T7.f", 0777)) != 3) e(1);
if (close(xfd) != 0) e(2);
if ( (xfd = open("T7.f", O_RDWR)) < 0) e(3);
if (write(xfd, buf, ITEMS) != ITEMS) e(4);
if (set(WRITE, 0, 3) != 0) e(5);
if ( (pid = fork()) ) {
/* Parent waits until child has started before signaling it. */
while (access("T7.f1", 0) != 0) ;
unlink("T7.f1");
sleep(1);
if (kill(pid, SIGTERM) < 0) e(6);
if (wait(&s) != pid) e(7);
if ( (s>>8) != 19) e(8);
} else {
/* Child tries to lock and should block.
* `signal(SIGTERM, sigfunc);' to set the signal handler is inadequate
* because on systems like BSD the sigaction flags for signal include
* `SA_RESTART' so syscalls are restarted after they have been
* interrupted by a signal.
*/
struct sigaction sa, osa;
sa.sa_handler = sigfunc;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGTERM, &sa, &osa) < 0) e(999);
if (creat("T7.f1", 0777) < 0) e(9);
func_code = F_SETLKW;
if (set(WRITE, 0, 3) != -1) e(10); /* should block */
if (errno != EINTR) e(11); /* signal should release it */
exit(19);
}
close(xfd);
}
void test7g()
{
/* Test to see if SETLKW unlocks when the needed lock becomes available. */
int pid, s;
subtest = 7;
if ( (xfd = creat("T7.g", 0777)) != 3) e(1);
if (close(xfd) != 0) e(2);
if ( (xfd = open("T7.g", O_RDWR)) < 0) e(3);
if (write(xfd, buf, ITEMS) != ITEMS) e(4);
if (set(WRITE, 0, 3) != 0) e(5); /* bytes 0 to 3 are now locked */
if ( (pid = fork()) ) {
/* Parent waits for child to start. */
while (access("T7.g1", 0) != 0) ;
unlink("T7.g1");
sleep(1);
if (set(UNLOCK, 0, 3) != 0) e(5);
if (wait(&s) != pid) e(6);
if ( (s >> 8) != 29) e(7);
} else {
/* Child tells parent it is alive, then tries to lock and is blocked.*/
func_code = F_SETLKW;
if (creat("T7.g1", 0777) < 0) e(8);
if (set(WRITE, 3, 3) != 0) e(9); /* process must block now */
if (set(UNLOCK, 3, 3) != 0) e(10);
exit(29);
}
close(xfd);
}
void test7h()
{
/* Test to see what happens if two processed block on the same lock. */
int pid, pid2, s, w;
subtest = 8;
if ( (xfd = creat("T7.h", 0777)) != 3) e(1);
if (close(xfd) != 0) e(2);
if ( (xfd = open("T7.h", O_RDWR)) < 0) e(3);
if (write(xfd, buf, ITEMS) != ITEMS) e(4);
if (set(WRITE, 0, 3) != 0) e(5); /* bytes 0 to 3 are now locked */
if ( (pid = fork()) ) {
if ( (pid2 = fork()) ) {
/* Parent waits for child to start. */
while (access("T7.h1", 0) != 0) ;
while (access("T7.h2", 0) != 0) ;
unlink("T7.h1");
unlink("T7.h2");
sleep(1);
if (set(UNLOCK, 0, 3) != 0) e(6);
w = wait(&s);
if (w != pid && w != pid2) e(7);
s = s >> 8;
if (s != 39 && s != 49) e(8);
w = wait(&s);
if (w != pid && w != pid2) e(9);
s = s >> 8;
if (s != 39 && s != 49) e(10);
} else {
func_code = F_SETLKW;
if (creat("T7.h1", 0777) < 0) e(11);
if (set(WRITE, 0, 0) != 0) e(12); /* block now */
if (set(UNLOCK, 0, 0) != 0) e(13);
exit(39);
}
} else {
/* Child tells parent it is alive, then tries to lock and is blocked.*/
func_code = F_SETLKW;
if (creat("T7.h2", 0777) < 0) e(14);
if (set(WRITE, 0, 1) != 0) e(15); /* process must block now */
if (set(UNLOCK, 0, 1) != 0) e(16);
exit(49);
}
close(xfd);
}
void test7i()
{
/* Check error conditions for fcntl(). */
int tfd, i;
subtest = 9;
errno = 0;
if ( (xfd = creat("T7.i", 0777)) != 3) e(1);
if (close(xfd) != 0) e(2);
if ( (xfd = open("T7.i", O_RDWR)) < 0) e(3);
if (write(xfd, buf, ITEMS) != ITEMS) e(4);
if (set(WRITE, 0, 3) != 0) e(5); /* bytes 0 to 3 are now locked */
if (set(WRITE, 0, 0) != 0) e(6);
if (errno != 0) e(7);
errno = 0;
if (set(WRITE, 3, 3) != 0) e(8);
if (errno != 0) e(9);
tfd = xfd; /* hold good value */
xfd = -99;
errno = 0;
if (set(WRITE, 0, 0) != -1) e(10);
if (errno != EBADF) e(11);
errno = 0;
if ( (xfd = open("T7.i", O_WRONLY)) < 0) e(12);
if (set(READ, 0, 0) != -1) e(13);
if (errno != EBADF) e(14);
if (close(xfd) != 0) e(15);
errno = 0;
if ( (xfd = open("T7.i", O_RDONLY)) < 0) e(16);
if (set(WRITE, 0, 0) != -1) e(17);
if (errno != EBADF) e(18);
if (close(xfd) != 0) e(19);
xfd = tfd; /* restore legal xfd value */
/* Check for EINVAL. */
errno = 0;
if (fcntl(xfd, F_DUPFD, OPEN_MAX) != -1) e(20);
if (errno != EINVAL) e(21);
errno = 0;
if (fcntl(xfd, F_DUPFD, -1) != -1) e(22);
if (errno != EINVAL) e(23);
xfd = 0; /* stdin does not support locking */
errno = 0;
if (set(READ, 0, 0) != -1) e(24);
if (errno != EINVAL) e(25);
xfd = tfd;
/* Check ENOLCK. */
for (i = 0; i < ITEMS; i++) {
if (set(WRITE, i, i) == 0) continue;
if (errno != ENOLCK) {
e(26);
break;
}
}
/* Check EMFILE. */
for (i = xfd + 1; i < OPEN_MAX; i++) open("T7.i", 0); /* use up all fds */
errno = 0;
if (fcntl(xfd, F_DUPFD, 0) != -1) e(27); /* No fds left */
if (errno != EMFILE) e(28);
for (i = xfd; i < OPEN_MAX; i++) if (close(i) != 0) e(29);
}
void test7j()
{
/* Test file locking with two processes. */
int s;
subtest = 10;
if ( (xfd = creat("T7.j", 0777)) != 3) e(1);
close(xfd);
if ( (xfd = open("T7.j", O_RDWR)) < 0) e(2);
if (write(xfd, buf, ITEMS) != ITEMS) e(3);
if (set(WRITE, 0, 4) != 0) e(4); /* lock belongs to parent */
if (set(READ, 10, 16) != 0) e(5); /* lock belongs to parent */
/* Up until now, all locks have been disjoint. Now try conflicts. */
if (fork()) {
/* Parent just waits for child to finish. */
wait(&s);
} else {
/* Child does the testing. */
errno = -100;
if (set(WRITE, 5, 7) < 0) e(6); /* should work */
if (set(WRITE, 4, 7) >= 0) e(7); /* child may not lock byte 4 */
if (errno != EACCES && errno != EAGAIN) e(8);
if (set(WRITE, 5, 9) != 0) e(9);
if (set(UNLOCK, 5, 9) != 0) e(10);
if (set(READ, 9, 17) < 0) e(11); /* shared READ lock is ok */
exit(0);
}
close(xfd);
}
void cloexec_test()
{
/* To text whether the FD_CLOEXEC flag actually causes files to be
* closed upon exec, we have to exec something. The test is carried
* out by forking, and then having the child exec test7 itself, but
* with argument 0. This is detected, and control comes here.
* File descriptors 3 and 10 should be closed here, and 10 open.
*/
if (close(3) == 0) e(1001); /* close should fail; it was closed on exec */
if (close(6) != 0) e(1002); /* close should succeed */
if (close(10) == 0) e(1003); /* close should fail */
fflush(stdout);
exit(0);
}
int set(how, first, last)
int how, first, last;
{
int r;
struct flock flock;
if (how == READ) flock.l_type = F_RDLCK;
if (how == WRITE) flock.l_type = F_WRLCK;
if (how == UNLOCK) flock.l_type = F_UNLCK;
flock.l_whence = whence;
flock.l_start = (long) first;
flock.l_len = (long) last - (long) first + 1;
r = fcntl(xfd, func_code, &flock);
if (r != -1)
return(0);
else
return(-1);
}
int locked(b)
int b;
/* Test to see if byte b is locked. Return L or U */
{
struct flock flock;
pid_t pid;
int status;
flock.l_type = F_WRLCK;
flock.l_whence = whence;
flock.l_start = (long) b;
flock.l_len = 1;
/* Process' own locks are invisible to F_GETLK, so fork a child to test. */
pid = fork();
if (pid == 0) {
if (fcntl(xfd, F_GETLK, &flock) != 0) e(2000);
exit(flock.l_type == F_UNLCK ? U : L);
}
if (pid == -1) e(2001);
if (fcntl(xfd, F_GETLK, &flock) != 0) e(2002);
if (flock.l_type != F_UNLCK) e(2003);
if (wait(&status) != pid) e(2004);
if (!WIFEXITED(status)) e(2005);
return(WEXITSTATUS(status));
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
fflush(stdout);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}
void sigfunc(s)
int s; /* for ANSI */
{
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(1);
}
}

1051
test/test8.c Normal file

File diff suppressed because it is too large Load Diff

274
test/test9.c Normal file
View File

@@ -0,0 +1,274 @@
/* Test 9 setjmp with register variables. Author: Ceriel Jacobs */
#include <sys/types.h>
#include <setjmp.h>
#include <signal.h>
#define MAX_ERROR 4
#include "common.c"
char *tmpa;
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test9a, (void));
_PROTOTYPE(void test9b, (void));
_PROTOTYPE(void test9c, (void));
_PROTOTYPE(void test9d, (void));
_PROTOTYPE(void test9e, (void));
_PROTOTYPE(void test9f, (void));
_PROTOTYPE(char *addr, (void));
_PROTOTYPE(void garbage, (void));
_PROTOTYPE(void level1, (void));
_PROTOTYPE(void level2, (void));
_PROTOTYPE(void dolev, (void));
_PROTOTYPE(void catch, (int s));
_PROTOTYPE(void hard, (void));
int main(argc, argv)
int argc;
char *argv[];
{
jmp_buf envm;
int i, j, m = 0xFFFF;
start(9);
if (argc == 2) m = atoi(argv[1]);
for (j = 0; j < 100; j++) {
if (m & 00001) test9a();
if (m & 00002) test9b();
if (m & 00004) test9c();
if (m & 00010) test9d();
if (m & 00020) test9e();
if (m & 00040) test9f();
}
if (errct) quit();
i = 1;
if (setjmp(envm) == 0) {
i = 2;
longjmp(envm, 1);
} else {
if (i == 2) {
/* Correct */
} else if (i == 1) {
printf("WARNING: The setjmp/longjmp of this machine restore register variables\n\
to the value they had at the time of the Setjmp\n");
} else {
printf("Aha, I just found one last error\n");
return 1;
}
}
quit();
return(-1); /* impossible */
}
void test9a()
{
register p;
subtest = 1;
p = 200;
garbage();
if (p != 200) e(1);
}
void test9b()
{
register p, q;
subtest = 2;
p = 200;
q = 300;
garbage();
if (p != 200) e(1);
if (q != 300) e(2);
}
void test9c()
{
register p, q, r;
subtest = 3;
p = 200;
q = 300;
r = 400;
garbage();
if (p != 200) e(1);
if (q != 300) e(2);
if (r != 400) e(3);
}
char buf[512];
void test9d()
{
register char *p;
subtest = 4;
p = &buf[100];
garbage();
if (p != &buf[100]) e(1);
}
void test9e()
{
register char *p, *q;
subtest = 5;
p = &buf[100];
q = &buf[200];
garbage();
if (p != &buf[100]) e(1);
if (q != &buf[200]) e(2);
}
void test9f()
{
register char *p, *q, *r;
subtest = 6;
p = &buf[100];
q = &buf[200];
r = &buf[300];
garbage();
if (p != &buf[100]) e(1);
if (q != &buf[200]) e(2);
if (r != &buf[300]) e(3);
}
jmp_buf env;
/* return address of local variable.
This way we can check that the stack is not polluted.
*/
char *
addr()
{
char a;
return &a;
}
void garbage()
{
register i, j, k;
register char *p, *q, *r;
char *a;
p = &buf[300];
q = &buf[400];
r = &buf[500];
i = 10;
j = 20;
k = 30;
switch (setjmp(env)) {
case 0:
a = addr();
#ifdef __GNUC__
/*
* to defeat the smartness of the GNU C optimizer we pretend we
* use 'a'. Otherwise the optimizer will not detect the looping
* effectuated by setjmp/longjmp, so that it thinks it can get
* rid of the assignment to 'a'.
*/
srand((unsigned)&a);
#endif
longjmp(env, 1);
break;
case 1:
if (i != 10) e(11);
if (j != 20) e(12);
if (k != 30) e(13);
if (p != &buf[300]) e(14);
if (q != &buf[400]) e(15);
if (r != &buf[500]) e(16);
tmpa = addr();
if (a != tmpa) e(17);
level1();
break;
case 2:
if (i != 10) e(21);
if (j != 20) e(22);
if (k != 30) e(23);
if (p != &buf[300]) e(24);
if (q != &buf[400]) e(25);
if (r != &buf[500]) e(26);
tmpa = addr();
if (a != tmpa) e(27);
level2();
break;
case 3:
if (i != 10) e(31);
if (j != 20) e(32);
if (k != 30) e(33);
if (p != &buf[300]) e(34);
if (q != &buf[400]) e(35);
if (r != &buf[500]) e(36);
tmpa = addr();
if (a != tmpa) e(37);
hard();
case 4:
if (i != 10) e(41);
if (j != 20) e(42);
if (k != 30) e(43);
if (p != &buf[300]) e(44);
if (q != &buf[400]) e(45);
if (r != &buf[500]) e(46);
tmpa = addr();
if (a != tmpa) e(47);
return;
break;
default: e(100);
}
e(200);
}
void level1()
{
register char *p;
register i;
i = 1000;
p = &buf[10];
i = 200;
p = &buf[20];
longjmp(env, 2);
}
void level2()
{
register char *p;
register i;
i = 0200;
p = &buf[2];
*p = i;
dolev();
}
void dolev()
{
register char *p;
register i;
i = 010;
p = &buf[3];
*p = i;
longjmp(env, 3);
}
void catch(s)
int s;
{
longjmp(env, 4);
}
void hard()
{
register char *p;
signal(SIGHUP, catch);
for (p = buf; p <= &buf[511]; p++) *p = 025;
kill(getpid(), SIGHUP);
}