even if the specified file is not in the PATH.
This change enforces security and makes it conform to POSIX.
Closes PR #6794.
I thought Christos committed this but not appeared yet. :)
The setstackmark()/popstackmark() pair in dotcmd(), used for freeing
stack storage possibly allocated by find_dot_file(), is redundant for now
since dotcmd() is surrounded by another pair in evalcommand().
This redundancy, however, may help future modifications
(suggested by Christos).
The problem was that system calls got restarted after a signal,
instead of returning EINTR. Thus the read builtin, had no way to
know that a signal occured that could change the course of execution.
Since the code has sprinkled checks for EINTR all over the place,
it is supposed to work properly with non restartable syscalls.
The fix is to use siginterrupt(signo, 1), before setting a signal
handler, to make sure that system calls don't get restarted.
Rewrite man page in mandoc format rather than nasty man format.
Fix a ton of parsing errors, and generate proper .Xr's.
document all known environment variables.
suggest ksh rather than bash.
The last two fix PR #1966. Wheee!
Somebody with access to the POSIX spec needs to go in here, and document
our adherence, or lack thereof.
such as sh -c 'echo `echo foo`' .
The memory allocated with ckmalloc() at
parser.c:1349:readtoken1() (search for "done:" label)
was never freed.
I changed this to use 'string stack' framework of Ash.
Note that a string on string stack is properly freed on
exception and end of command parsing, and no explicit free
or signal handlings required.
See TOUR for an overview, and memalloc.[ch] for details
of string stack.
and must be freed to avoid memory leaks if called repeatedly.
The leaks occured on symbolic umask command, such as "umask go-w",
which is undocumented.
- it was in the wrong place
- makefiles shouldn't override CFLAGS; only CPPFLAGS and COPTS
- christos fixed unsigned char stuff in 1.33 which should
remove the need for -w anyway
* move .include <bsd.prog.mk> to EOF
involved in the `for' list, the list was recorded twice, leading to incorrect
argument expansion.
Introduce ifsfree() function that free's the IFS region list, GC'ing duplicated
code.
sleep
cmd='set `type "sleep"`; eval echo \$$#'
which=`eval $cmd`
echo $which
because the region did not get recorded at all, and it was interpreted as
a single word. I modified the code to keep track when the result of a
backquote expansion has been recorded to avoid recording it twice. I still
feel that this is not the right fix... More to come.
assignment. E.g.
echo ${foo:=`echo 1 2 3 4`}
prints:
1 2 3 1 2 3 4
because when the arquments are not quoted, the backquote result
gets recorded twice. The fix right now is to comment out the
record_region() call in expbackq(). I hope that it does not break
anything else.
escape character (including line continuation), unless the `-r' option
is specified:
* adopt to this behaviour, add the `-r' option to disable it;
* remove the `-e' option, which was previously necessary to get this behaviour.
cmdenviron is pointing to varlist.list; varlist gets reset everytime
you enter evalcommand, but cmdenviron does not. The wonders of global
variables...
unsigned character machines. So that people don't have to reverse engineer
this again:
mksyntax detects if characters are signed or not and builts a syntax
table that has a base of 129 for signed characters or 1 for unsigned
characters. This is so the largest negative signed char [-128] + the
base == 1. 0 is special and means end of file in both cases. PEOF
is -1 for the unsigned character case and -129 for the signed
character case, so that syntax[PEOF + base] == syntax[0] == CEOF
So PEOF has to be -1, but it is explicitly compared with
unsigned characters on machines where characters are unsigned.
The quick fix is to define UPEOF the (unsigned char) version of PEOF
and use that. A better fix is to always use unsigned characters
when referencing symbol table entries, but that would require
extensive changes to the shell. So to summarize
syntax[0] == CEOF, base + PEOF == 0
unsigned signed
base 1 129
PEOF -1 -129
- treat $0 specially since it is not in shellparams
- check the number of parameters instead of walking
the parameters array to avoid checking against the
null terminated element.
set -- ""; echo ${1:-wwww} works.
- when expanding arithmetic, discard previous ifs recorded regions, since we
are doing our own scanning. x=ab; echo $((${#x}+1)) now works.
- in ${var#word} fix two bugs:
* if there was an exact match, there was an off-by-one bug in the
comparison of the words. x=abcd; echo ${x#abcd}
* if there was no match, the stack region was not adjusted and the rest
of the word was getting written in the wrong place. x=123; echo ${x#abc}X
shell's idea of the current working directory match reality when
symlinks (or anything else we can't stat) are traversed with the
cd command. However, this does not print out the cwd after cd
traverses symlinks, as it used to, though the capability is still
there should one want to use it.
- the 3 argument version of getopts would not reset properly
- OPTARG did not get cleared after a non argument option was found
- OPTIND was not set properly after a non argument option.
command not found. Add extra exception type and generalize
error handling routines to take that exception type. Use
a global variable exerrno to keep the last exec error.
This is used to implement the POSIX behavior when OPTIND=1
- Call setvarsafe instead of setvar. If one ran
"getopts optstr badvariable"
where badvariable contained an illegal variable name, there was no way
to recover, since setvar() would longjmp on the error.
1. OPTIND value was not computed correctly when the argument was part of the
option string (i.e. for "l:" "-l 1" was working "-l1" was not). (PR/2505).
2. OPTARG was not being unset in case of errors [in the non POSIX error case].
3. optvar could be set to random values.
4. Option string starting with a : was not treated specially as POSIX
specifies (if the option string starts with a :, then there is no
error printed when there are missing option arguments or illegal options,
and OPTARG and optvar are being set specially).
5. Implemented getopts "opts" optvar [arg]. The optional argument case
was not implemented.
To do:
- what does Posix say about resetting the getopts state? Bash does it
by setting OPTIND=0; is that correct? Should we be doing the same thing?
- should we be using getopt(3) for everything internal to the shell? Is that
feasible because we might need to handle multiple invocations at once.
(1) it needs to be ALIGNed for both halves of the 'if,' and
(2) if you're going to claim that you now have ALIGN(newlen)
bytes left, you should have actually allocated
ALIGN(newlen), rather than just 'newlen' bytes.
and many user complaints why the shell hangs in echo "`"
- eval.c: Fix exitstatus invalid resetting in `if' statements were:
if (exit 3); then
echo foo $?
else
echo bar $?
fi
printed 'bar 0' instead of bar 3
symlinks. From Chris Demetriou <cgd@NetBSD.ORG>. Fixes PR #1776.
Changed so that INTOFF/INTON are paired in getpwd(). From Matthias
Pfaller <leo@marco.de>. Fixes PR #2130.
- restore parsing state after parsing old style command substitution.
The ';' in '`echo z;`' broke the following:
for i in 1; do
cat > /dev/tty << __EOF__
`echo z;`
__EOF__
done
cVS: Enter Log. Lines beginning with `CVS: ' are removed automatically
When not in a function, it skips the rest of the current input file.
Instances of `return' outside function definitions were previously ignored.
What does joe posix have to say about this?
[fixes PR/1444]
$ cat foo
echo $FOO
$ FOO=1 . ./foo
$ echo $FOO
Did not echo 1 at all. Now variable assignments before sourced scripts
are honored during and after the execution of the script.
false
foo=bar
echo $?
would print 1
Also fixed the long standing bug:
false
echo `echo $?`
would print 0
The exitstatus needs rethinking and rewriting. The trial and error method
is not very efficient
begin with a space, but contains one. Fixes PR bin/809.
#!/bin/sh
list="a b c "
echo "With ordinary IFS"
for i in $list;do
echo $i
done
IFS=":${IFS}"
echo "With changed IFS"
for i in $list;do
echo $i
done
Note that before the fix ":${IFS}" behaved differently than "${IFS}:".