From acf84e9633f03b10da7d674773ca831dc4b9d88e Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sun, 16 Aug 2020 09:08:07 +0100 Subject: [PATCH] Fix 'command -x' on macOS, Linux, Solaris 'command -x' (basically builtin xargs for 'command') worked for long argument lists on *BSD and HP-UX, but not on macOS and Linux, where it reliably entered into an infinite loop. The problem was that it assumed that every byte of the environment space can be used for arguments, without accounting for alignment that some OSs do. MacOS seems to be the most wasteful one: it aligns on 16-byte boundaries and requires some extra bytes per argument as well. src/cmd/ksh93/sh/path.c: - path_xargs(): When calculating how much space to subtract per argument, add 16 extra bytes to the length of each argument, then align the result on 16-byte boundaries. The extra 16 bytes is more than even macOS needs, but hopefully it is future-proof. - path_spawn(): If path_xargs() does fail, do not enter a retry loop (which always becomes an infinite loop if the argument list exceeds OS limitations), but abort with an error message. --- NEWS | 6 ++++++ src/cmd/ksh93/sh/path.c | 9 ++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 4b34437ae..888814b9f 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,12 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2020-08-16: + +- Fixed 'command -x' on macOS, Linux and Solaris by accounting for a 16-byte + argument alignment. If execution does fail, it now aborts with an internal + error message instead of entering an infinite retry loop. + 2020-08-13: - Fixed memory leaks and a crashing bug that occurred when defining and diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c index 5447b0275..9b683539f 100644 --- a/src/cmd/ksh93/sh/path.c +++ b/src/cmd/ksh93/sh/path.c @@ -175,8 +175,12 @@ static pid_t path_xargs(Shell_t *shp,const char *path, char *argv[],char *const shp->exitval = 0; while(av0 && av0) return(pid); -retry: switch(shp->path_err = errno) { case ENOEXEC: @@ -1238,7 +1241,7 @@ retry: { pid = path_xargs(shp,opath, &argv[0] ,envp,spawn); if(pid<0) - goto retry; + errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),"%s: 'command -x' failed",path); return(pid); } default: