diff --git a/NEWS b/NEWS index 3ea2ded9d..b82989706 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,10 @@ Any uppercase BUG_* names are modernish shell bug IDs. based on the incorrect assumption the IFS would never be larger than a single byte. +- Fixed a bug that caused the sleep builtin to continue after being given + an unrecognized option. 'sleep -: 1' will now show a usage message and + exit instead of sleep for one second. + 2020-07-23: - Fixed an infinite loop that could occur when ksh is the system's /bin/sh. diff --git a/src/cmd/ksh93/bltins/sleep.c b/src/cmd/ksh93/bltins/sleep.c index c34f3db53..15df5b1a7 100644 --- a/src/cmd/ksh93/bltins/sleep.c +++ b/src/cmd/ksh93/bltins/sleep.c @@ -62,6 +62,8 @@ int b_sleep(register int argc,char *argv[],Shbltin_t *context) errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); break; } + if(error_info.errors) + errormsg(SH_DICT, ERROR_usage(2), "%s", optusage(NULL)); argv += opt_info.index; if(cp = *argv) { diff --git a/src/cmd/ksh93/bltins/trap.c b/src/cmd/ksh93/bltins/trap.c index 1e19c2594..974ac5de4 100644 --- a/src/cmd/ksh93/bltins/trap.c +++ b/src/cmd/ksh93/bltins/trap.c @@ -249,8 +249,19 @@ endopts: int b_suspend(int argc,char *argv[],Shbltin_t *context) { NOT_USED(argc); - if(optget(argv, sh_optsuspend)) /* no options supported (except AST --man, etc.) */ - errormsg(SH_DICT, ERROR_exit(2), "%s", opt_info.arg); + + int n; + while((n = optget(argv, sh_optsuspend))) switch(n) + { + case ':': + errormsg(SH_DICT,2, "%s", opt_info.arg); + break; + case '?': + errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); + break; + } + if(error_info.errors) /* no options supported (except AST --man, etc.) */ + errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0)); if(argv[opt_info.index]) /* no operands supported */ errormsg(SH_DICT, ERROR_exit(2), e_toomanyops); if(sh_isoption(SH_LOGIN_SHELL)) diff --git a/src/cmd/ksh93/tests/builtins.sh b/src/cmd/ksh93/tests/builtins.sh index 46a880b9d..da0291d2e 100755 --- a/src/cmd/ksh93/tests/builtins.sh +++ b/src/cmd/ksh93/tests/builtins.sh @@ -885,5 +885,16 @@ fi EOF "$SHELL" -i "$sleepsig" 2> /dev/null || err_exit "'sleep -s' doesn't work with intervals of more than 30 seconds" +# ========== +# Builtins should handle unrecognized options correctly +( + builtin $(builtin -l | awk -F "/" '/\/opt/ {print $5}') # Load all /opt/ast/bin builtins + for name in $(builtin -l | grep -Ev '(echo|/opt|test|true|false|getconf|uname|\[|:)'); do + actual="$($name --this-option-does-not-exist 2>&1)" + expect="Usage: $name" + [[ $actual =~ $expect ]] || err_exit "$name should show usage info on unrecognized options (expected $(printf '%q' "$expect"), got $(printf '%q' "$actual"))" + done +) + # ====== exit $((Errors<125?Errors:125))