| #
470d6e5e |
| 14-Oct-2024 |
kre <kre@NetBSD.org> |
Apologies for that commit message ... it should have been the same as for revision 1.124 of Makefile (and as below).
(This change changes nothing).
Reject nul characters in shell input.
At the req
Apologies for that commit message ... it should have been the same as for revision 1.124 of Makefile (and as below).
(This change changes nothing).
Reject nul characters in shell input.
At the request of Thomas Klausner (wiz@) copy an idea from OpenBSD, and have the shell simply reject any (sh) input containing a \0 (nul) character. Previously nul characters were simply ignored (removed from the input before it was examined in any other way).
Note this affects data read by the shell itself only, and has no impact on other utilities, including those that are built into the shell (so 'read' can still use -d '' to process output using \0 as the record separator).
While I have tested that this works, there are so many places where a nul might appear, that I cannot possibly test them all (or even imagine all the possible places), so if this change causes any problems, let me know (if from a script, send me the script).
To undo this change, simply comment out (or delete) the line CPPFLAGS+= -DREJECT_NULS from the Makefile, and build again. Eventually if this causes no problems, that option (conditional compilation) will probably just go away, and this change would be permanent.
While the conditional compilation (on or off) persists, the NETBSD_SHELL variable value will contain the word REJECT_NULLS so you can easily verify if you are running a shell with this included or not.
No pullups planned.
show more ...
|
| #
472691bd |
| 14-Oct-2024 |
kre <kre@NetBSD.org> |
# $NetBSD: Makefile,v 1.123 2023/10/19 04:27:24 mrg Exp $ # @(#)Makefile 8.4 (Berkeley) 5/5/95
.include <bsd.own.mk>
PROG= sh SHSRCS= alias.c arith_token.c arithmetic.c cd.c echo.c error.c eval.c e
# $NetBSD: Makefile,v 1.123 2023/10/19 04:27:24 mrg Exp $ # @(#)Makefile 8.4 (Berkeley) 5/5/95
.include <bsd.own.mk>
PROG= sh SHSRCS= alias.c arith_token.c arithmetic.c cd.c echo.c error.c eval.c exec.c \ expand.c histedit.c input.c jobs.c mail.c main.c memalloc.c \ miscbltin.c mystring.c options.c parser.c redir.c show.c trap.c \ output.c var.c test.c kill.c syntax.c GENSRCS=builtins.c init.c nodes.c GENHDRS=builtins.h nodes.h token.h nodenames.h optinit.h SRCS= ${SHSRCS} ${GENSRCS}
DPSRCS+=${GENHDRS}
LDADD+= -ledit -lterminfo DPADD+= ${LIBEDIT} ${LIBTERMINFO}
# Environment for scripts executed during build. SCRIPT_ENV= \ AWK=${TOOL_AWK:Q} \ MKTEMP=${TOOL_MKTEMP:Q} \ SED=${TOOL_SED:Q}
CPPFLAGS+=-DSHELL -I. -I${.CURDIR} -I${NETBSDSRCDIR}/lib/libedit CPPFLAGS+= -DUSE_LRAND48 CPPFLAGS+= -DREJECT_NULS
#XXX: For testing only. #CPPFLAGS+=-DDEBUG=1 #COPTS+=-g #CFLAGS+=-funsigned-char #TARGET_CHARFLAG?= -DTARGET_CHAR="unsigned char" -funsigned-char
# Reproducible build parameters ... export into sh for NETBSD_SHELL setting .if ${MKREPRO_TIMESTAMP:Uno} != "no" BUILD_DATE!= ${TOOL_DATE} -u -r "${MKREPRO_TIMESTAMP}" "+%Y%m%d%H%M%S" # These are (should be) equivalent, but the 2nd is easier to understand #CPPFLAGS+= -DBUILD_DATE='"${BUILD_DATE:C/([^0]0?)(00)*$/\1/}Z"' CPPFLAGS+= -DBUILD_DATE='"${BUILD_DATE:S/00$//:S/00$//:S/00$//}Z"' .endif
.ifdef SMALLPROG CPPFLAGS+=-DSMALL .endif .ifdef TINYPROG CPPFLAGS+=-DTINY .else SRCS+=printf.c .endif
.PATH: ${.CURDIR}/bltin ${NETBSDSRCDIR}/bin/test \ ${NETBSDSRCDIR}/usr.bin/printf \ ${NETBSDSRCDIR}/bin/kill
CLEANFILES+= ${GENSRCS} ${GENHDRS} sh.html1 CLEANFILES+= trace.*
token.h: mktokens ${_MKTARGET_CREATE} ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC}
.ORDER: builtins.h builtins.c builtins.h builtins.c: mkbuiltins shell.h builtins.def ${_MKTARGET_CREATE} ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.OBJDIR} [ -f builtins.h ]
init.c: mkinit.sh ${SHSRCS} ${_MKTARGET_CREATE} ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC}
.ORDER: nodes.h nodes.c nodes.c nodes.h: mknodes.sh nodetypes nodes.c.pat ${_MKTARGET_CREATE} ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.OBJDIR} [ -f nodes.h ]
nodenames.h: mknodenames.sh nodes.h ${_MKTARGET_CREATE} ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} > ${.TARGET}
optinit.h: mkoptions.sh option.list ${_MKTARGET_CREATE} ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.TARGET} ${.OBJDIR}
.if ${USETOOLS} == "yes" NBCOMPATLIB= -L${TOOLDIR}/lib -lnbcompat .endif
SUBDIR.roff+=USD.doc
COPTS.printf.c = -Wno-format-nonliteral COPTS.jobs.c = -Wno-format-nonliteral COPTS.var.c = -Wno-format-nonliteral
# XXXGCC12 - only on some targets COPTS.parser.c+= ${${ACTIVE_CC} == "gcc" && ${HAVE_GCC:U0} >= 12:? -Wno-error=clobbered :}
.include <bsd.prog.mk> .include <bsd.subdir.mk>
${OBJS}: Makefile
show more ...
|
| #
50a5715b |
| 03-Aug-2024 |
kre <kre@NetBSD.org> |
Change the "string" argument to evalstring() and setinputstring() from being "char *" to being "const char *".
This is needed for a forthcoming change which needs to pass a const char * to evalstrin
Change the "string" argument to evalstring() and setinputstring() from being "char *" to being "const char *".
This is needed for a forthcoming change which needs to pass a const char * to evalstring (and through it to setinputstring) and be assured that nothing will alter the characters in the string supplied.
This is (aside from the additional compile time protection provided) a no-op change, all evalstring() does with its string is pass it to setinputstring() and all that does with it is determine its length (strlen() which expects a const char *) and assign the string pointer to parsenextc which is already a const char * - there never has been any reason for these two functions to not include the "const" in the arg declaration -- except that when originally written (early 1990's) I suspect "const" either didn't exist at all, or wasn't supported by relevant compilers.
NFCI. Most probably (though I didn't check) no binary change at all.
show more ...
|
| #
c591669f |
| 13-Jul-2024 |
kre <kre@NetBSD.org> |
Implement the HISTFILE and HISTAPPEND variables.
See the (newly updated) sh(1) for details. Also add the -z option to fc (clear history).
None of this exists in SMALL shells.
|
| #
00668d1e |
| 16-Feb-2021 |
kre <kre@NetBSD.org> |
PR bin/55979
Correctly handle (ie: ignore completely) \0 chars (nuls) in the shell command input stream (script, dot file, or stdin).
Previously nul chars were ignored correctly in the line in whic
PR bin/55979
Correctly handle (ie: ignore completely) \0 chars (nuls) in the shell command input stream (script, dot file, or stdin).
Previously nul chars were ignored correctly in the line in which they occurred, but would cause trailing chars of that line to reappear as the start of the following line. If there was just one \0 skipped, this would generally result in an extra \n in the sh input, which in most cases has no effect. With multiple \0's in a single line, more of the end of that line was duplicated into the following one. This usually manifested as a weird "command not found" error.
Note that any \0 chars in the sh input make the script non-conforming, so fixing this is not crucial (no \0's should really ever be seen) but it was an obvious bug in the code, which was attempting to ignore nul chars (as do many other shells), so let it be fixed.
XXX pullup -9
show more ...
|
| #
b4a242b5 |
| 09-Feb-2019 |
kre <kre@NetBSD.org> |
KNF - white space changes, indent using tabs not spaces. NFC.
|
| #
e8999de4 |
| 09-Feb-2019 |
kre <kre@NetBSD.org> |
INTON / INTOFF audit and cleanup.
No visible differences expected - there is a remote chance that some internal lossage may no longer occur in interactive shells that receive SIGINT (untrapped) at i
INTON / INTOFF audit and cleanup.
No visible differences expected - there is a remote chance that some internal lossage may no longer occur in interactive shells that receive SIGINT (untrapped) at inopportune times, but you would have had to have been very unlucky to have ever suffered from that.
show more ...
|
| #
1a9b5ae6 |
| 16-Jan-2019 |
kre <kre@NetBSD.org> |
Redo 1.65 in a simpler way. This is the bit rot avoidance code that is #if 0'd and (still) has never been compiled (most likely never will be.)
While here, in the same uncompiled code, deal with l
Redo 1.65 in a simpler way. This is the bit rot avoidance code that is #if 0'd and (still) has never been compiled (most likely never will be.)
While here, in the same uncompiled code, deal with line number counting. Whether this is correct depends upon how this code is used, and as it never is (and never has been since line numbers first started being counted), this is somewhat speculative, but it seems likely to be the correct way to handle things.
NFC (this code is still all #if 0).
show more ...
|
| #
20c0839a |
| 15-Jan-2019 |
kre <kre@NetBSD.org> |
Don't use quoteflag when deciding if the word after an alias should be looked up as a potential following alias - if the first expands to a string that ends with a space (any space, quoted or not) th
Don't use quoteflag when deciding if the word after an alias should be looked up as a potential following alias - if the first expands to a string that ends with a space (any space, quoted or not) then the next word is to be treated as an alias candidate. (POSIX was to specify only unquoted spaces, but is now going to leave that unspecified, and the "any space" version turns out to be more useful.
And besides, the quoteflag test didn't work properly, and would have been very messy to fix ... if in a word (as if we have a quoted space) it means that the word has been quoted, which meant that quoted spaces were correctly detected, but it outside a word, it just means that the previous word was quoted, so it would sometimes reject alias lookup on the next word in cases where it is unquestioned it should be done.
show more ...
|
| #
39225745 |
| 09-Jan-2019 |
kre <kre@NetBSD.org> |
Correct an (old) typo in a comment. NFC - it is just a comment.
|
| #
ed405f1d |
| 09-Jan-2019 |
kre <kre@NetBSD.org> |
Fix the code taken from FreeBSD 2 revisions back, which fixed aliases, to actually do what it was supposed to do, and not just come close by accident. (How broken this was, while still seeming to w
Fix the code taken from FreeBSD 2 revisions back, which fixed aliases, to actually do what it was supposed to do, and not just come close by accident. (How broken this was, while still seeming to work perfectly most of the time was truly amazing!)
This corrects the behaviour of an alias defined with a blank char as the last of its value, to correctly do an alias lookup on the word that follows the alias.
show more ...
|
| #
6046dde4 |
| 09-Jan-2019 |
kre <kre@NetBSD.org> |
Update some dead (#if 0'd) code that is never called to cope with the changes made in the previous revision, in an attempt to avoid bit rot.
Untested (uncompiled) - though it should work.
NFC: this
Update some dead (#if 0'd) code that is never called to cope with the changes made in the previous revision, in an attempt to avoid bit rot.
Untested (uncompiled) - though it should work.
NFC: this change doesn't get compiled, let alone used.
show more ...
|
| #
021ba509 |
| 03-Dec-2018 |
kre <kre@NetBSD.org> |
Revamp aliases - as dumb an idea as they are, if we're going to have them, they should work as documented, not cause core dumps, reference after free, incorrect replacements, failing to implement ali
Revamp aliases - as dumb an idea as they are, if we're going to have them, they should work as documented, not cause core dumps, reference after free, incorrect replacements, failing to implement alias after alias, ...
The big comment that ended: This is a good idea ------- ***NOT*** and the hack it was describing are gone.
Note that most of this was from original CVS version 1.1 code (ie: came from the original import, even before 4.4-Lite was merged. That is, May 1994. And no-one in 24.5 years noticed (or at least complained about) all the bugs (or at least, most of them)).
With these changes, aliases ought to work (if you can call it that) as they are expected to by POSIX. Now if only we could get POSIX to delete them (or make them optional)...
Changes partly inspired by similar changes made by FreeBSD, (as was the previous change to alias.c, forgot ack in commit log for that one, apologies) but done a little differently, and perhaps with a slightly better outcome.
show more ...
|
| #
8a9a9619 |
| 19-Aug-2018 |
kre <kre@NetBSD.org> |
PR bin/48875 (is related, and ameliorated, but not exactly "fixed")
Import a whole set of tree evaluation enhancements from FreeBSD.
With these, before forking, the shell predicts (often) when all
PR bin/48875 (is related, and ameliorated, but not exactly "fixed")
Import a whole set of tree evaluation enhancements from FreeBSD.
With these, before forking, the shell predicts (often) when all it will have to do after forking (in the parent) is wait for the child and then exit with the status from the child, and in such a case simply does not fork, but rather allows the child to take over the parent's role.
This turns out to handle the particular test case from PR bin/48875 in such a way that it works as hoped, rather than as it did (the delay there was caused by an extra copy of the shell hanging around waiting for the background child to complete ... and keeping the command substitution stdout open, so the "real" parent had to wait in case more output appeared).
As part of doing this, redirection processing for compound commands gets moved out of evalsubshell() and into a new evalredir(), which allows us to properly handle errors occurring while performing those redirects, and not mishandle (as in simply forget) fd's which had been moved out of the way temporarily.
evaltree() has its degree of recursion reduced by making it loop to handle the subsequent operation: that is instead of (for any binop like ';' '&&' (etc)) where it used to evaltree(node->left); evaltree(node->right); return; it now does (kind of) next = node; while ((node = next) != NULL) { next = NULL;
if (node is a binary op) { evaltree(node->left); if appropriate /* if && test for success, etc */ next = node->right; continue; } /* similar for loops, etc */ } which can be a good saving, as while the left side (now) tends to be (usually) a simple (or simpleish) command, the right side can be many commands (in a command sequence like a; b; c; d; ... the node at the top of the tree will now have "a" as its left node, and the tree for b; c; d; ... as its right node - until now everything was evaluated recursively so it made no difference, and the tree was constructed the other way).
if/while/... statements are done similarly, recurse to evaluate the condition, then if the (or one of the) body parts is to be evaluated, set next to that, and loop (previously it recursed).
There is more to do in this area (particularly in the way that case statements are processed - we can avoid recursion there as well) but that can wait for another day.
While doing all of this we keep much better track of when the shell is just going to exit once the current tree is evaluated (with a new predicate at_eof() to tell us that we have, for sure, reached the end of the input stream, that is, this shell will, for certain, not be reading more command input) and use that info to avoid unneeded forks. For that we also need another new predicate (have_traps()) to determine of there are any caught traps which might occur - if there are, we need to remain to (potentially) handle them, so these optimisations will not occur (to make the issue in PR 48875 appear again, run the same code, but with a trap set to execute some code when a signal (or EXIT) occurs - note that the trap must be set in the appropriate level of sub-shell to have this effect, any caught traps are cleared in a subshell whenever one is created).
There is still work to be done to handle traps properly, whatever weirdness they do (some of which is related to some of this.)
These changes do not need man page updates, but 48875 does - an update to sh.1 will be forthcoming once it is decided what it should say...
Once again, all the heavy lifting for this set of changes comes directly (with thanks) from the FreeBSD shell.
XXX pullup-8 (but not very soon)
show more ...
|
| #
a9e6fc0b |
| 19-Aug-2017 |
kre <kre@NetBSD.org> |
NFC - DEBUG mode change only - add some sanity to a debug printf format string
|
| #
70a37837 |
| 05-Aug-2017 |
kre <kre@NetBSD.org> |
PR bin/52458
Avoid mangling history when editing is enabled, and the prompt contains a \n
Also, allow empty input lines into history when they are being appended to a previous (partial) command (bu
PR bin/52458
Avoid mangling history when editing is enabled, and the prompt contains a \n
Also, allow empty input lines into history when they are being appended to a previous (partial) command (but not when they would just make an empty entry).
For all the gory details, see the PR.
Note nothing here actually makes prompts containing \n work correctly when editing is enabled, that's a libedit issue, which will be addressed some other time.
show more ...
|
| #
ae375f01 |
| 05-Jul-2017 |
kre <kre@NetBSD.org> |
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to the new format. Also #if 0 a function definition that is used nowhere. While here, change the function of pushfile() slightly
Mostly DEBUG and white space changes. Convert DEEBUG TRACE() calls to the new format. Also #if 0 a function definition that is used nowhere. While here, change the function of pushfile() slightly - it now sets the buf pointer in the top (new) input descriptor to NULL, instead of simply leaving it - code that needs a buffer always (before and after) must malloc() one and assign it after the call. But code which does not (which will be reading from a string or similar) now does not have to explicitly set it to NULL (cleaner interface.) NFC intended (or observed.)
show more ...
|
| #
1fca9bbf |
| 30-Jun-2017 |
kre <kre@NetBSD.org> |
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic expansions, and if enabled by the promptcmds option, command substitutions.)
|
| #
727a69dc |
| 07-Jun-2017 |
kre <kre@NetBSD.org> |
A better LINENO implementation. This version deletes (well, #if 0's out) the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)). (Code to invert the LINENO hack when required,
A better LINENO implementation. This version deletes (well, #if 0's out) the LINENO hack, and uses the LINENO var for both ${LINENO} and $((LINENO)). (Code to invert the LINENO hack when required, like when de-compiling the execution tree to provide the "jobs" command strings, is still included, that can be deleted when the LINENO hack is completely removed - look for refs to VSLINENO throughout the code. The var funclinno in parser.c can also be removed, it is used only for the LINENO hack.)
This version produces accurate results: $((LINENO)) was made as accurate as the LINENO hack made ${LINENO} which is very good. That's why the LINENO hack is not yet completely removed, so it can be easily re-enabled. If you can tell the difference when it is in use, or not in use, then something has broken (or I managed to miss a case somewhere.)
The way that LINENO works is documented in its own (new) section in the man page, so nothing more about that, or the new options, etc, here.
This version introduces the possibility of having a "reference" function associated with a variable, which gets called whenever the value of the variable is required (that's what implements LINENO). There is just one function pointer however, so any particular variable gets at most one of the set function (as used for PATH, etc) or the reference function. The VFUNCREF bit in the var flags indicates which func the variable in question uses (if any - the func ptr, as before, can be NULL).
I would not call the results of this perfect yet, but it is close.
show more ...
|
| #
fd38bbe2 |
| 07-Jun-2017 |
kre <kre@NetBSD.org> |
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version does about as well as most other shell implementations wh
An initial attempt at implementing LINENO to meet the specs.
Aside from one problem (not too hard to fix if it was ever needed) this version does about as well as most other shell implementations when expanding $((LINENO)) and better for ${LINENO} as it retains the "LINENO hack" for the latter, and that is very accurate.
Unfortunately that means that ${LINENO} and $((LINENO)) do not always produce the same value when used on the same line (a defect that other shells do not share - aside from the FreeBSD sh as it is today, where only the LINENO hack exists and so (like for us before this commit) $((LINENO)) is always either 0, or at least whatever value was last set, perhaps by LINENO=${LINENO} which does actually work ... for that one line...)
This could be corrected by simply removing the LINENO hack (look for the string LINENO in parser.c) in which case ${LINENO} and $((LINENO)) would give the same (not perfectly accurate) values, as do most other shells.
POSIX requires that LINENO be set before each command, and this implementation does that fairly literally - except that we only bother before the commands which actually expand words (for, case and simple commands). Unfortunately this forgot that expansions also occur in redirects, and the other compound commands can also have redirects, so if a redirect on one of the other compound commands wants to use the value of $((LINENO)) as a part of a generated file name, then it will get an incorrect value. This is the "one problem" above. (Because the LINENO hack is still enabled, using ${LINENO} works.)
This could be fixed, but as this version of the LINENO implementation is just for reference purposes (it will be superseded within minutes by a better one) I won't bother. However should anyone else decide that this is a better choice (it is probably a smaller implementation, in terms of code & data space then the replacement, but also I would expect, slower, and definitely less accurate) this defect is something to bear in mind, and fix.
This version retains the *BSD historical practice that line numbers in functions (all functions) count from 1 from the start of the function, and elsewhere, start from 1 from where the shell started reading the input file/stream in question. In an "eval" expression the line number starts at the line of the "eval" (and then increases if the input is a multi-line string).
Note: this version is not documented (beyond as much as LINENO was before) hence this slightly longer than usual commit message.
show more ...
|
| #
70d8efb3 |
| 03-May-2017 |
kre <kre@NetBSD.org> |
Another fix from FreeBSD. I'm not sure how to trigger the problem fixed (there might be no way) - but it "feels right"!
When popping an (exhausted) input string off the input stack, allow for the
Another fix from FreeBSD. I'm not sure how to trigger the problem fixed (there might be no way) - but it "feels right"!
When popping an (exhausted) input string off the input stack, allow for the possibility that the previous string might also just happened to have run out of steam as well, so keep poppin' along until we run out of pop, or find something to consume.
show more ...
|
| #
eaa91315 |
| 03-May-2017 |
kre <kre@NetBSD.org> |
Deal with \newline line continuations more correctly. They can occur anywhere (*anywhere*) not only where it happens to be convenient to the parser...
This fix from FreeBSD (thanks again folks).
To
Deal with \newline line continuations more correctly. They can occur anywhere (*anywhere*) not only where it happens to be convenient to the parser...
This fix from FreeBSD (thanks again folks).
To make this work, pushstring()'s signature needed to change to allow a const char * as its string arg, which meant sprinkling some const other places for a brighter appearance (and handling fallout).
All this because I wanted to see what number would come from
echo $\ {\ L\ I\ N\ E\ N\ O\ }
and was surprised at the result! That works now...
The bug would also affect stuff like
true &\ & false
and all kinds of other uses where the \newline occurred in the "wrong" place.
An ATF test for sh syntax is coming... (sometime.)
show more ...
|
| #
9e4f9b37 |
| 03-May-2017 |
kre <kre@NetBSD.org> |
Fix idiot typos in previous (this is not the advertised :next commit") Same typo - two different places. Ugh!
|
| #
323e8358 |
| 03-May-2017 |
kre <kre@NetBSD.org> |
NFC: Change prototype of pushstring() to give a real type for the 3rd arg (struct alias *) rather than using void * and then casting it when used. For callers, the arg either is a struct alias *, o
NFC: Change prototype of pushstring() to give a real type for the 3rd arg (struct alias *) rather than using void * and then casting it when used. For callers, the arg either is a struct alias *, or is NULL, so nothing to adjust there.
NB: This change untested by itself, it was going to be a part of the next change (coming in a few minutes) but is logically unrelated, so ...
show more ...
|
| #
51c4dfe4 |
| 29-Apr-2017 |
kre <kre@NetBSD.org> |
Keep track of which file descriptors the shell is using for its own purposes, and move them elsewhere whenever a user redirection happens to pick the same number. With this we can move the shell fi
Keep track of which file descriptors the shell is using for its own purposes, and move them elsewhere whenever a user redirection happens to pick the same number. With this we can move the shell file descriptors back to lower values (be slightly kinder to the kernel) since we can no longer clash. (Also get rid of a little old unneeded code.)
This also completes the fdflags command, which no longer permits access to (by way or either obtaining, or changing) the shell's internal fds.
show more ...
|