653 lines
15 KiB
Plaintext
653 lines
15 KiB
Plaintext
if [ $# != 1 ] ; then
|
||
echo "Usage: ksh-prog Bugs ksh-prog" 1>&2
|
||
exit 1
|
||
fi
|
||
THIS_KSH=$1
|
||
shift
|
||
|
||
echo 'The following tests are known to fail:
|
||
39'
|
||
|
||
tbase=bug-t$$
|
||
tfile=/tmp/$tbase
|
||
sfile=/tmp/bug-s$$
|
||
|
||
# 1. Everywhere
|
||
# lex array code has problems....
|
||
# $ echo blah[
|
||
# missing ]
|
||
# $
|
||
# Different view of same bug:
|
||
# $ n=blah echo "hi[ $n ]"
|
||
# hi[ $n ]
|
||
# $
|
||
n=blah
|
||
x=$(echo hi[ $n ]=1)
|
||
if [ "$x" = 'hi[ $n ]=1' ] ; then
|
||
echo 'Bug 1 present (echo "hi[ $n ] " prints hi[ $n ]).'
|
||
fi
|
||
unset n x
|
||
|
||
#
|
||
# 2. Everywhere
|
||
# When PATH is set before running a command, the new path is not used
|
||
# in doing the path search
|
||
# $ echo echo hi > /tmp/q ; chmod a+rx /tmp/q
|
||
# $ PATH=/tmp q
|
||
# q: not found
|
||
# $
|
||
# in comexec() the two lines
|
||
# while (*vp != NULL)
|
||
# (void) typeset(*vp++, xxx, 0);
|
||
# need to be moved out of the switch to before findcom() is called - I
|
||
# don't know what this will break.
|
||
cat > $tfile << 'EOF'
|
||
#!/bin/sh
|
||
echo hi
|
||
exit 0
|
||
EOF
|
||
chmod a+rx $tfile
|
||
PATH=/tmp $tbase > /dev/null 2>&1
|
||
if [ $? != 0 ] ; then
|
||
echo "Bug 2 present: local assignments to PATH don't effect PATH search"
|
||
fi
|
||
rm -f $tfile
|
||
|
||
#
|
||
# 3. Sun OS 4.0.x (This seems to be a problem with sun's PENDIN not being done
|
||
# properly)
|
||
# sleep 5^J ls^J ls^J ls [only first ls runs]
|
||
# vi ... ZZ (while waiting type) [some of the input gets eaten]
|
||
# [not present in SunOS 4.1.x]
|
||
echo " [No automatic test for bug 3 - interactive]"
|
||
|
||
#
|
||
# 4. (fixed)
|
||
#
|
||
echo " [Don't know what bug 4 was]"
|
||
|
||
#
|
||
# 5. Everywhere
|
||
# File name completion (^X,*) does not mesh well with cd and
|
||
# symbolic links. cd does path simplification wrt $PWD before
|
||
# doing the actual chdir(), while file name completion does
|
||
# not do the simplification. E.g., you are in directory A
|
||
# which has a symbolic link to directory B, you create a file
|
||
# called foobar and you then cd to the symlink to B, and type
|
||
# $ echo ../foo^X
|
||
# and the shell beeps at you. Would be more consistent to
|
||
# do the completion after simplifing the `$PWD/..'.
|
||
echo " [No automatic test for bug 5 - interactive]"
|
||
|
||
#
|
||
# 6. Everywhere
|
||
# Parsing of $(..) expressions is non-optimal. It is
|
||
# impossible to have any parentheses inside the expression.
|
||
# I.e.,
|
||
# $ ksh -c 'echo $(echo \( )'
|
||
# no closing quote
|
||
# $ ksh -c 'echo $(echo "(" )'
|
||
# no closing quote
|
||
# $
|
||
# The solution is to hack the parsing clode in lex.c, the
|
||
# question is how to hack it: should any parentheses be
|
||
# escaped by a backslash, or should recursive parsing be done
|
||
# (so quotes could also be used to hide hem). The former is
|
||
# easier, the later better...
|
||
cat > $tfile << 'EOF'
|
||
echo $(echo \()
|
||
EOF
|
||
out=`$THIS_KSH $tfile 2>&1`
|
||
if [ "X$out" != 'X(' ] ; then
|
||
echo 'Bug 6 present: can'\''t quote ( inside $(..) escapes'
|
||
fi
|
||
rm -f $tfile
|
||
|
||
#
|
||
# 7. (fixed)
|
||
#
|
||
echo " [Don't know what bug 7 was]"
|
||
|
||
#
|
||
# 8. Everywhere - NOT A BUG - this is what at&t ksh does
|
||
# Strange typset -x behaviour in functions. The following function
|
||
# does not set the environment variable BLAH outside the function:
|
||
# function blah
|
||
# {
|
||
# typeset -x BLAH=foobar
|
||
# }
|
||
# This function does work:
|
||
# function blah
|
||
# { BLAH=foobar; export BLAH
|
||
# }
|
||
echo ' [Bug 8 was bogus]'
|
||
|
||
#
|
||
# 9. (fixed) Fix is to make sure Volatile is not defined to nothing
|
||
# (see defines in sh.h)
|
||
# Continue in a for loop does not work right:
|
||
# for i in a b c ; do
|
||
# if [ $i = b ] ; then
|
||
# continue
|
||
# fi
|
||
# echo $i
|
||
# done
|
||
# Prints a forever...
|
||
first=yes
|
||
for i in a b c ; do
|
||
if [ $i = b ] ; then
|
||
if [ $first = no ] ; then
|
||
echo 'Bug 9 present: continue in for loop broken'
|
||
break # hope break isn't broken too :-)
|
||
fi
|
||
first=no
|
||
continue
|
||
fi
|
||
done
|
||
|
||
#
|
||
# 10. Everywhere
|
||
# The following:
|
||
# set -- `false`
|
||
# echo $?
|
||
# shoud not print 0. (according to /bin/sh, at&t ksh, and the
|
||
# getopt(1) man page - not according to POSIX)
|
||
set -- `false`
|
||
if [ $? != 1 ] ; then
|
||
echo 'Bug 10 present: set exit code overrides exit code of command subst'
|
||
fi
|
||
|
||
#
|
||
# 11. Some places (sun4s but not mips)
|
||
# The following:
|
||
# x=/foo/bar/blah
|
||
# echo ${x##*/}
|
||
# should echo blah but on some machines echos /foo/bar/blah.
|
||
x=/foo/bar/blah
|
||
if [ ${x##*/} != blah ] ; then
|
||
echo 'Bug 11 present: ${x##*/} doesn'\''t work'
|
||
fi
|
||
unset x
|
||
|
||
#
|
||
# 12. Everywhere:
|
||
# Both of the following echos produce the same output under sh/ksh.att:
|
||
# #!/bin/sh
|
||
# x="foo bar"
|
||
# echo "`echo \"$x\"`"
|
||
# echo "`echo "$x"`"
|
||
# pdksh produces different output for the former (foo instead of foo\tbar)
|
||
x="foo bar"
|
||
if [ "X`echo \"$x\"`" != "Xfoo bar" ] ; then
|
||
echo 'Bug 12 present: quotes inside `` sequences different from sh'
|
||
fi
|
||
unset x
|
||
|
||
#
|
||
# 13. Everywhere
|
||
# The following command hangs forever:
|
||
# $ (: ; cat /etc/termcap) | sleep 2
|
||
# This is because the shell forks a shell to run the (..) command
|
||
# and this shell has the pipe open. When the sleep dies, the cat
|
||
# doesn't get a SIGPIPE 'cause a process (ie, the second shell)
|
||
# still has the pipe open.
|
||
trap 'echo "Bug 13 present: pipes not closed properly"; trap 2' 2
|
||
echo " [If this hangs for more than a second, hit ^C]"
|
||
(: ; cat /etc/termcap) | sleep 1
|
||
trap 2
|
||
echo " [relax, no bug 13]"
|
||
|
||
|
||
#
|
||
# 14. Everywhere
|
||
# The command
|
||
# $ (foobar) 2> /dev/null
|
||
# generates no output under /bin/sh, but pdksh produces the error
|
||
# foobar: not found
|
||
# Also, the command
|
||
# $ foobar 2> /dev/null
|
||
# generates an error under /bin/sh and pdksh, but at&t ksh produces
|
||
# no error (redirected to /dev/null).
|
||
cat > $tfile << 'EOF'
|
||
(you/should/not/see/this/error/1) 2> /dev/null
|
||
you/should/not/see/this/error/2 2> /dev/null
|
||
EOF
|
||
if $THIS_KSH $tfile 2>&1 | grep you/should > /dev/null; then
|
||
echo "Bug 14 present: shell 'command not found' error not redirected"
|
||
fi
|
||
rm -f $tfile
|
||
|
||
#
|
||
# 15. Everywhere
|
||
# The command
|
||
# $ whence foobar
|
||
# generates a blank line under pdksh and sets the exit status to 0.
|
||
# at&t ksh generates no output and sets the exit status to 1. Also,
|
||
# the command
|
||
# $ whence foobar cat
|
||
# generates no output under at&t ksh (pdksh generates a blank line
|
||
# and /bin/cat).
|
||
echo " [Note that there are three bug 15 tests: 15a, 15b, 15c]"
|
||
cat > $tfile << 'EOF'
|
||
whence does/not/exist > /dev/null
|
||
echo $?
|
||
EOF
|
||
out=`$THIS_KSH $tfile 2> /dev/null`
|
||
if [ "$out" != 1 ] ; then
|
||
echo 'Bug 15a present: exit status of whence wrong'
|
||
fi
|
||
rm -f $tfile
|
||
x=$(whence does/not/exist | wc -l)
|
||
case $x in
|
||
*0*) ;;
|
||
*) echo 'Bug 15b present: whence produces blank lines'
|
||
esac
|
||
x=$(whence does/not/exist cat | wc -l)
|
||
case $x in
|
||
*2*) echo 'Bug 15c present: whence continues after error'
|
||
esac
|
||
unset x
|
||
|
||
#
|
||
# 16. Everywhere
|
||
# ${var%%expr} seems to be broken in many places. On the mips
|
||
# the commands
|
||
# $ read line < /etc/passwd
|
||
# $ echo $line
|
||
# root:0:1:...
|
||
# $ echo ${line%%:*}
|
||
# root
|
||
# $ echo $line
|
||
# root
|
||
# $
|
||
# change the value of line. On sun4s & pas, the echo ${line%%:*} doesn't
|
||
# work. Haven't checked elsewhere...
|
||
read x < /etc/passwd
|
||
y=$x
|
||
echo ${x%%:*} > /dev/null
|
||
if [ "$x" != "$y" ] ; then
|
||
echo 'Bug 16 present: ${..%%..} trashes variables'
|
||
fi
|
||
unset x y
|
||
|
||
#
|
||
# 17. Everywhere
|
||
# The command
|
||
# . /foo/bar
|
||
# should set the exit status to non-zero (sh and at&t ksh do).
|
||
# XXX doting a non existant file is a fatal error for a script
|
||
cat > $tfile << 'EOF'
|
||
(. does/not/exist)
|
||
echo $?
|
||
EOF
|
||
out=`$THIS_KSH $tfile 2> /dev/null`
|
||
if [ "$out" != 1 ] ; then
|
||
echo 'Bug 17 present: exit status of . wrong'
|
||
fi
|
||
rm -f $tfile
|
||
|
||
#
|
||
# 18. Everywhere
|
||
# In vi mode ^X (and *) can dump core:
|
||
# $ ab[cd^XMemory fault (core dumped)
|
||
echo " [No automatic test for bug 18 - interactive]"
|
||
|
||
#
|
||
# 19. Everywhere
|
||
# Both of the following echos should produce the same thing, but don't:
|
||
# $ x=foo/bar
|
||
# $ echo ${x%/*}
|
||
# foo
|
||
# $ echo "${x%/*}"
|
||
# foo/bar
|
||
x=foo/bar
|
||
if [ "${x%/*}" != foo ] ; then
|
||
echo 'Bug 19 present: ${..%..} in double quotes broken'
|
||
fi
|
||
unset x
|
||
|
||
#
|
||
# 20. (same as 18)
|
||
#
|
||
|
||
#
|
||
# 21. Everywhere
|
||
# backslash does not work as expected in case labels:
|
||
# $ x='-x'
|
||
# $ case $x in
|
||
# -\?) echo hi
|
||
# esac
|
||
# hi
|
||
# $ x='-?'
|
||
# $ case $x in
|
||
# -\\?) echo hi
|
||
# esac
|
||
# hi
|
||
# $
|
||
case -x in
|
||
-\?) echo 'Bug 21 present: backslashes do not work in case patterns'
|
||
esac
|
||
|
||
#
|
||
# 22. Quoting backquotes inside backquotes doesn't work:
|
||
# $ echo `echo hi \`echo there\` folks`
|
||
# asks for more info. sh and at&t ksh both echo
|
||
# hi there folks
|
||
cat > $tfile << 'EOF'
|
||
echo `echo hi \`echo there\` folks`
|
||
EOF
|
||
out=`$THIS_KSH $tfile 2>&1`
|
||
if [ "$out" != 'hi there folks' ] ; then
|
||
echo 'Bug 22 present: quoting backquotes inside backquotes broken'
|
||
fi
|
||
rm -f $tfile
|
||
|
||
#
|
||
# 23. )) is not treated `correctly':
|
||
# $ (echo hi ; (echo there ; echo folks))
|
||
# missing ((
|
||
# $
|
||
# instead of (as sh and ksh.att)
|
||
# $ (echo hi ; (echo there ; echo folks))
|
||
# hi
|
||
# there
|
||
# folks
|
||
# $
|
||
cat > $tfile << 'EOF'
|
||
( : ; ( : ; echo hi))
|
||
EOF
|
||
out=`$THIS_KSH $tfile 2>&1`
|
||
if [ "$out" != 'hi' ] ; then
|
||
echo 'Bug 23 present: )) always assumed to be end of (( )) expr'
|
||
fi
|
||
rm -f $tfile
|
||
|
||
|
||
#
|
||
# 24. strangeness with file name completion involving symlinks to nowhere
|
||
# $ mkdir foo foo/bar
|
||
# $ ln -s /stuff/junk foo/bar/xx
|
||
# $ echo foo/*/xx
|
||
# (beep)
|
||
# $
|
||
echo " [No automatic test for bug 24 - interactive]"
|
||
|
||
#
|
||
# 25. Check reading stdin in a while loop. The read should only read
|
||
# a single line, not a whole stdio buffer; the cat should get
|
||
# the rest.
|
||
#
|
||
(echo a; echo b) | while read x ; do
|
||
[ "$x" = b ] && echo 'Bug 25 present (read reads too much from pipe).'
|
||
cat > /dev/null
|
||
done
|
||
|
||
#
|
||
# 26a. Check reading stdin in a while loop. The read should read both
|
||
# lines, not just the first.
|
||
#
|
||
cat > $tfile << 'EOF'
|
||
a
|
||
b
|
||
EOF
|
||
cat > $sfile << 'EOF'
|
||
a=
|
||
while [ "$a" != xxx ] ; do
|
||
last=$x
|
||
read x
|
||
cat /dev/null | sed 's/x/y/'
|
||
a=x$a
|
||
done
|
||
if [ "$last" != b ] ; then
|
||
echo 'Bug 26 present (reading in a while loop broken).'
|
||
fi
|
||
EOF
|
||
$THIS_KSH $sfile < $tfile
|
||
rm -f $tfile $sfile
|
||
|
||
#
|
||
# 26b Check reading stdin in a while loop. The read should read both
|
||
# lines, not just the first. This differs from 26 in that lines
|
||
# are placed against the margin.
|
||
#
|
||
cat > $tfile << 'EOF'
|
||
ab
|
||
cd
|
||
EOF
|
||
cat > $sfile << 'EOF'
|
||
a=
|
||
while [ "$a" != xxx ] ; do
|
||
last=$x
|
||
read x
|
||
cat /dev/null | sed 's/x/y/'
|
||
a=x$a
|
||
done
|
||
if [ "$last" != cd ] ; then
|
||
echo "Bug 26b present (last line should be cd was $last.)"
|
||
fi
|
||
EOF
|
||
$THIS_KSH $sfile < $tfile
|
||
rm -f $tfile $sfile
|
||
|
||
#
|
||
# 27. Everywhere
|
||
# The command
|
||
# . /does/not/exist
|
||
# should cause a script to exit.
|
||
cat > $tfile << 'EOF'
|
||
. does/not/exist
|
||
echo hi
|
||
EOF
|
||
out=`$THIS_KSH $tfile 2> /dev/null`
|
||
if [ "$out" = hi ] ; then
|
||
echo "Bug 27 present: .'ing a non-existant file doesn't kill script"
|
||
fi
|
||
rm -f $tfile
|
||
|
||
|
||
#
|
||
# 28. Everywhere
|
||
# variable assignements not detected well
|
||
#
|
||
cat > $tfile << 'EOF'
|
||
a.x=1 echo hi
|
||
EOF
|
||
out=`$THIS_KSH $tfile 2> /dev/null`
|
||
if [ "$out" = hi ] ; then
|
||
echo "Bug 28 present: strange chars allowed in variables"
|
||
fi
|
||
rm -f $tfile
|
||
|
||
#
|
||
# 29. Everywhere
|
||
# alias expansion different from real ksh
|
||
#
|
||
cat > $tfile << 'EOF'
|
||
alias a='for ' b='i in'
|
||
a b hi ; do echo $i ; done
|
||
EOF
|
||
out=`$THIS_KSH $tfile 2> /dev/null`
|
||
if [ "$out" != hi ] ; then
|
||
echo "Bug 29 present: keyword in alias with trailing space doesn't work"
|
||
fi
|
||
rm -f $tfile
|
||
|
||
|
||
#
|
||
# 30. Everywhere
|
||
# strange characters allowed inside ${...}
|
||
#
|
||
cat > $tfile << 'EOF'
|
||
echo ${a{b}}
|
||
EOF
|
||
out=`$THIS_KSH $tfile 2> /dev/null`
|
||
if [ $? = 0 ] ; then
|
||
echo 'Bug 30 present: strange chars allowed inside ${..}'
|
||
fi
|
||
rm -f $tfile
|
||
|
||
|
||
#
|
||
# 31. Everywhere
|
||
# Does read handle partial lines correctly
|
||
#
|
||
cat > $tfile << 'EOF'
|
||
a A Aa
|
||
b B Bb
|
||
EOF
|
||
print -n 'c' >> $tfile
|
||
cat > $sfile << 'EOF'
|
||
a=
|
||
ret=
|
||
while [ "$a" != xxx ] ; do
|
||
read x y z
|
||
ret=$?
|
||
a=x$a
|
||
done
|
||
if [ "$x" != c ] ; then
|
||
echo 'Bug 31a present: read throws away partial lines'
|
||
fi
|
||
if [ "$ret" != 1 ] ; then
|
||
echo 'Bug 31b present: read does not return eof for partial lines'
|
||
fi
|
||
EOF
|
||
$THIS_KSH $sfile < $tfile 2> /dev/null
|
||
rm -f $sfile $tfile
|
||
|
||
|
||
#
|
||
# 32. Everywhere
|
||
# Does read set variables to null at eof?
|
||
#
|
||
cat > $tfile << 'EOF'
|
||
a A Aa
|
||
b B Bb
|
||
EOF
|
||
cat > $sfile << 'EOF'
|
||
a=
|
||
while [ "$a" != xxx ] ; do
|
||
read x y z
|
||
a=x$a
|
||
done
|
||
if [ -n "$x$y$z" ] ; then
|
||
echo "Bug 32 present: read does not set variables to null at eof"
|
||
fi
|
||
EOF
|
||
$THIS_KSH $sfile < $tfile
|
||
rm -f $sfile $tfile
|
||
|
||
|
||
#
|
||
# 33. Everywhere
|
||
# Does umask print a leading 0 when umask is 3 digits?
|
||
#
|
||
cat > $sfile << 'EOF'
|
||
umask 222
|
||
umask
|
||
EOF
|
||
out=`$THIS_KSH $sfile`
|
||
if [ X"$out" = X222 ] ; then
|
||
echo "Bug 33 present: umask doesn't always start with 0"
|
||
fi
|
||
rm -f $sfile
|
||
|
||
|
||
#
|
||
# 34. Everywhere
|
||
# Does umask print a umask of 0 sanely?
|
||
#
|
||
cat > $sfile << 'EOF'
|
||
umask 0
|
||
umask
|
||
EOF
|
||
out=`$THIS_KSH $sfile`
|
||
if [ X"$out" = X00 ] ; then
|
||
echo "Bug 34 present: umask prints 0 as \`$out'"
|
||
fi
|
||
rm -f $sfile
|
||
|
||
#
|
||
# 35. Everywhere
|
||
# Tempory files used for here-docs in functions get trashed after
|
||
# the function is parsed (before it is executed)
|
||
#
|
||
cat > $sfile << 'EOF'
|
||
f1() {
|
||
cat <<- EOF
|
||
F1
|
||
EOF
|
||
f2() {
|
||
cat <<- EOF
|
||
F2
|
||
EOF
|
||
}
|
||
}
|
||
f1
|
||
f2
|
||
unset -f f1
|
||
f2
|
||
EOF
|
||
out=`$THIS_KSH $sfile 2>&1`
|
||
expected='F1
|
||
F2
|
||
F2'
|
||
if [ X"$out" != X"$expected" ] ; then
|
||
echo "Bug 35 present: here documents in functions don't work"
|
||
fi
|
||
rm -f $sfile
|
||
|
||
#
|
||
# 36. Everywhere (test from <sjg@void.zen.oz.au>)
|
||
# Command substitution breaks reading in while loop
|
||
#
|
||
cat > $sfile << 'EOF'
|
||
(echo abcdef; echo; echo 123) |
|
||
while read line
|
||
do
|
||
# the following line breaks it
|
||
c=`echo $line | wc -c`
|
||
echo $c
|
||
done
|
||
|
||
EOF
|
||
out=`$THIS_KSH $sfile 2>&1`
|
||
expect='7
|
||
1
|
||
4'
|
||
if [ X"$out" != X"$expect" ] ; then
|
||
echo "Bug 36 present: reading broken by command substitution in while loops"
|
||
fi
|
||
rm -f $sfile
|
||
|
||
#
|
||
# 37. Machines with broken times() (reported by <sjg@void.zen.oz.au>)
|
||
# time does not report correct real time
|
||
#
|
||
out=`$THIS_KSH -c 'time sleep 1' 2>&1 | awk '
|
||
/^[ ]*0*\.0*s?[ ][ ]*real/ { print "bad" }
|
||
/^[ ]*real[ ][ ]*0*\.0*s?([ ]|$)/ { print "bad" }'`
|
||
if [ -n "$out" ] ; then
|
||
echo "Bug 37 present: time does not report real-time correctly"
|
||
fi
|
||
|
||
#
|
||
# 38. set -e doesn't ignore exit codes for if/while/until/&&/||/!.
|
||
#
|
||
out=`$THIS_KSH -e -c '
|
||
if false; then echo hi ; fi
|
||
false || true
|
||
false && true
|
||
while false; do echo hi; done
|
||
echo ok' 2>&1`
|
||
if [ X"$out" != Xok ] ; then
|
||
echo "Bug 38 present: set -e exits when it shouldn't"
|
||
fi
|
||
|
||
#
|
||
# 39. set -e: errors in command substitutions aren't ignored
|
||
#
|
||
out=`$THIS_KSH -e -c 'if test X\`false; echo hi\` = Xhi; then echo ok ; fi' 2>&1`
|
||
if [ X"$out" != Xok ] ; then
|
||
echo "Bug 39 present: set -e: errors in command substitutions not ignored"
|
||
fi
|