mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
The xargs-like functionality of 'command -x' was still failing with E2BIG in cases or on systems where the environment variables list is very large. For instance, on a default NixOS installation it's about 50k by default (absurd; *each* process carries this weight). This commit tweaks the feature test and introduces a runtime fallback if it still fails. POSIX: "The number of bytes available for the new process' combined argument and environment lists is {ARG_MAX}. It is implementation- defined whether null terminators, pointers, and/or any alignment bytes are included in this total." https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html More recommended reading: https://mina86.com/2021/the-real-arg-max-part-1/ https://mina86.com/2021/the-real-arg-max-part-2/ So, operating systems are free to consume ARG_MAX space in whatever bizarre way they want, and may even come up with more innovative ways to waste buffer space in future. <sigh> command_xargs() allows for the possibility of adding a certain number of extra bytes per argument to account for pointers and whatnot. As of this commit, we still start off from the value that was determined by the _arg_extrabytes test in features/externs, but path_spawn() will now increase that number at runtime and retry if E2BIG still occurs. Hopefully this makes it future-proof. src/cmd/ksh93/features/externs: - Rename generated ARG_EXTRA_BYTES macro to _arg_extrabytes for better naming consistency with other iffe feature tests. - Tweaks to avoid detecting 9 extra bytes instead of 8 on some versions of 64-bit Linux (it needs the size of a 64 bit pointer). - Show the result in the iffe output. src/cmd/ksh93/include/shell.h, src/cmd/ksh93/sh/init.c: - Do not store getconf(CONF_ARG_MAX) at init time; on Linux, this value may be changed dynamically (via ulimit -s), so it must be re-obtained on every use. src/cmd/ksh93/sh/path.c: - command_xargs(): - Use a static global variable for the number of extra bytes per argument. Initialise it with the results of the feature test. This allows increasing it at runtime if an OS does something weird causing an E2BIG failure. - Abort instead of return if command_xargs() is called with sh.xargmin < 0; this should never happen. - To allow retrying without crashing, restore saved args before returning -1. - Leave more generous space for the environment -- half the size of the existing environment. This was experimentally determined to be needed to keep Linux and macOS happy. - Instead of crashing, return with E2BIG if there is too little space to run. - Get rid of unnecessary (void*) typecasts; we no longer pretend to be compatible with C++ (re: a34e8319). - Remove a couple of dead 'if(saveargs) free(saveargs);' statements; at those points, saveargs is known to be NULL. - Return -2 instead of -1 when retrying would be pointless. - path_spawn(): - When command_xargs() returns -1 and the error is E2BIG, increase the number of extra bytes by the size of a char* pointer and try again. Give up if adding bytes the size of 8 char* pointers fails. src/cmd/ksh93/sh/xec.c: check_exec_optimization(): - Do not use this optimization if we are running 'command -x'; I noticed some instances of the PATH search yielding incorrect results if we do. TODO: work this out at some point.
This commit is contained in:
parent
225323f138
commit
05fc199c95
5 changed files with 85 additions and 41 deletions
|
@ -217,7 +217,6 @@ struct sh_scoped
|
|||
|
||||
struct limits
|
||||
{
|
||||
long arg_max; /* max arg+env exec() size */
|
||||
int open_max; /* maximum number of file descriptors */
|
||||
int clk_tck; /* number of ticks per second */
|
||||
int child_max; /* maximum number of children */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue