mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
command -x: fix efficiency; always run external cmd (re: acf84e96
)
This commit fixes 'command -x' to adapt to OS limitations with
regards to data alignment in the arguments list. A feature test is
added that detects if the OS aligns the argument on 32-bit or
64-bit boundaries or not at all, allowing 'command -x' to avoid
E2BIG errors while maximising efficiency.
Also, as of now, 'command -x' is a way to bypass built-ins and
run/query an external command. Built-ins do not limit the length of
their argument list, so '-x' never made sense to use for them. And
because '-x' hangs on Linux and macOS on every ksh93 release
version to date (see acf84e96
), few use it, so there is little
reason not to make this change.
Finally, this fixes a longstanding bug that caused the minimum exit
status of 'command -x' to be 1 if a command with many arguments was
divided into several command invocations. This is done by replacing
broken flaggery with a new SH_XARG state flag bit.
src/cmd/ksh93/features/externs:
- Add new C feature test detecting byte alignment in args list.
The test writes a #define ARG_ALIGN_BYTES with the amount of
bytes the OS aligns arguments to, or zero for no alignment.
src/cmd/ksh93/include/defs.h:
- Add new SH_XARG state bit indicating 'command -x' is active.
src/cmd/ksh93/sh/path.c: path_xargs():
- Leave extra 2k in the args buffer instead of 1k, just to be sure;
some commands add large environment variables these days.
- Fix a bug in subtracting the length of existing arguments and
environment variables. 'size -= strlen(cp)-1;' subtracts one less
than the size of cp, which makes no sense; what is necessary is
to substract the length plus one to account for the terminating
zero byte, i.e.: 'size -= strlen(cp)+1'.
- Use the ARG_ALIGN_BYTES feature test result to match the OS's
data alignment requirements.
- path_spawn(): E2BIG: Change to checking SH_XARG state bit.
src/cmd/ksh93/bltins/whence.c: b_command():
- Allow combining -x with -p, -v and -V with the expected results
by setting P_FLAG to act like 'whence -p'. E.g., as of now,
command -xv printf
is equivalent to
whence -p printf
but note that 'whence' has no equivalent of 'command -pvx printf'
which searches $(getconf PATH) for a command.
- When -x will run a command, now set the new SH_XARG state flag.
src/cmd/ksh93/sh/xec.c: sh_exec():
- Change to using the new SH_XARG state bit.
- Skip the check for built-ins if SH_XARG is active, so that
'command -x' now always runs an external command.
src/lib/libcmd/date.c, src/lib/libcmd/uname.c:
- These path-bound builtins sometimes need to run the external
system command by the same name, but they did that by hardcoding
an unportable direct path. Now that 'command -x' runs an external
command, change this to using 'command -px' to guarantee using
the known-good external system utility in the default PATH.
- In date.c, fix the format string passed to 'command -px date'
when setting the date; it was only compatible with BSD systems.
Use the POSIX variant on non-BSD systems.
This commit is contained in:
parent
005d38f410
commit
66e1d44642
12 changed files with 239 additions and 75 deletions
|
@ -467,40 +467,47 @@ USAGE_LICENSE
|
|||
;
|
||||
|
||||
const char sh_optcommand[] =
|
||||
"[-1c?\n@(#)$Id: command (AT&T Research/ksh93) 2020-09-09 $\n]"
|
||||
"[-1c?\n@(#)$Id: command (AT&T Research/ksh93) 2021-01-30 $\n]"
|
||||
USAGE_LICENSE
|
||||
"[+NAME?command - execute a simple command disabling special properties]"
|
||||
"[+DESCRIPTION?Without \b-v\b or \b-V\b, \bcommand\b executes \acommand\a "
|
||||
"[+DESCRIPTION?Without \b-v\b or \b-V\b, \bcommand\b executes \acmd\a "
|
||||
"with arguments given by \aarg\a, suppressing the shell function lookup "
|
||||
"that normally occurs. If \acommand\a is a special built-in command, "
|
||||
"that normally occurs. If \acmd\a is a special built-in command, "
|
||||
"then the special properties are removed so that failures will not "
|
||||
"cause the script that executes it to terminate and preceding "
|
||||
"assignments will not persist beyond the command invocation. "
|
||||
"If \acommand\a is a declaration built-in command and the "
|
||||
"If \acmd\a is a declaration built-in command and the "
|
||||
"\b-o posix\b shell option is on, then the declaration properties are "
|
||||
"removed so that arguments containing \b=\b are not treated specially.]"
|
||||
"[+?With the \b-v\b or \b-V\b options, \bcommand\b is equivalent to the "
|
||||
"\bwhence\b(1) command.]"
|
||||
"[p?Instead of \b$PATH\b, search the OS's default utility path as output by "
|
||||
"\bgetconf PATH\b.]"
|
||||
"[v?Equivalent to \bwhence\b \acommand\a [\aarg\a ...]].]"
|
||||
"[x?If \acommand\a fails because there are too many \aarg\as, it will be "
|
||||
"invoked multiple times with a subset of the arguments on each "
|
||||
"invocation. Arguments that occur prior to the first word that expand "
|
||||
"to multiple arguments and arguments that occur after the last word "
|
||||
"that expands to multiple arguments will be passed on each invocation. "
|
||||
"The exit status will be the maximum invocation exit status.]"
|
||||
"[V?Equivalent to \bwhence \b-v\b \acommand\a [\aarg\a ...]].]"
|
||||
"[v?Equivalent to \bwhence\b \acmd\a [\aarg\a ...]].]"
|
||||
"[V?Equivalent to \bwhence \b-v\b \acmd\a [\aarg\a ...]].]"
|
||||
"[x?Search \acmd\a as an external command, bypassing built-ins. "
|
||||
"If the \aarg\as include a word "
|
||||
"such as \b\"$@\"\b or \b\"${array[@]]}\"\b "
|
||||
"that expands to multiple arguments, "
|
||||
"and the size of the expanded \aarg\a list "
|
||||
"exceeds \bgetconf ARG_MAX\b bytes, "
|
||||
"then \acmd\a will be run multiple times, "
|
||||
"dividing the \aarg\as over the invocations. "
|
||||
"Any \aarg\as that come before the first \b\"$@\"\b or similar, "
|
||||
"as well as any that follow the last such word, "
|
||||
"are considered static and will be repeated for each invocation "
|
||||
"so as to allow all invocations to use the same command options. "
|
||||
"The exit status will be the highest returned by the invocations.]"
|
||||
"\n"
|
||||
"\n[command [arg ...]]\n"
|
||||
"\n[cmd [arg ...]]\n"
|
||||
"\n"
|
||||
"[+EXIT STATUS?If \acommand\a is invoked, the exit status of \bcommand\b "
|
||||
"will be that of \acommand\a. Otherwise, it will be one of "
|
||||
"[+EXIT STATUS?If \acmd\a is invoked, the exit status of \bcommand\b "
|
||||
"will be that of \acmd\a. Otherwise, it will be one of "
|
||||
"the following:]{"
|
||||
"[+0?\bcommand\b completed successfully.]"
|
||||
"[+>0?\b-v\b or \b-V\b has been specified and an error occurred.]"
|
||||
"[+126?\acommand\a was found but could not be invoked.]"
|
||||
"[+127?\acommand\a could not be found.]"
|
||||
"[+126?\acmd\a was found but could not be invoked.]"
|
||||
"[+127?\acmd\a could not be found.]"
|
||||
"}"
|
||||
|
||||
"[+SEE ALSO?\bwhence\b(1), \bgetconf\b(1)]"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue