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
				
			
		|  | @ -162,24 +162,24 @@ static pid_t path_xargs(Shell_t *shp,const char *path, char *argv[],char *const | |||
| 	pid_t pid; | ||||
| 	if(shp->xargmin < 0) | ||||
| 		return((pid_t)-1); | ||||
| 	size = shp->gd->lim.arg_max-1024; | ||||
| 	size = shp->gd->lim.arg_max-2048; | ||||
| 	for(ev=envp; cp= *ev; ev++) | ||||
| 		size -= strlen(cp)-1; | ||||
| 		size -= strlen(cp)+1; | ||||
| 	for(av=argv; (cp= *av) && av< &argv[shp->xargmin]; av++)   | ||||
| 		size -= strlen(cp)-1; | ||||
| 		size -= strlen(cp)+1; | ||||
| 	for(av=avlast; cp= *av; av++,nlast++)   | ||||
| 		size -= strlen(cp)-1; | ||||
| 		size -= strlen(cp)+1; | ||||
| 	av =  &argv[shp->xargmin]; | ||||
| 	if(!spawn) | ||||
| 		job_clear(); | ||||
| 	shp->exitval = 0; | ||||
| 	while(av<avlast) | ||||
| 	{ | ||||
| 		/* for each argument, account for terminating zero and 16-byte alignment */ | ||||
| 		/* for each argument, account for terminating zero and possible alignment */ | ||||
| 		for(xv=av,left=size; left>0 && av<avlast;) | ||||
| 		{ | ||||
| 			n = strlen(*av++) + 1 + 16; | ||||
| 			left -= n + n % 16; | ||||
| 			n = strlen(*av++) + 1 + ARG_ALIGN_BYTES; | ||||
| 			left -= n + (ARG_ALIGN_BYTES ? n % ARG_ALIGN_BYTES : 0); | ||||
| 		} | ||||
| 		/* leave at least two for last */ | ||||
| 		if(left<0 && (avlast-av)<2) | ||||
|  | @ -1244,11 +1244,11 @@ pid_t path_spawn(Shell_t *shp,const char *opath,register char **argv, char **env | |||
| #endif /* EMLINK */ | ||||
| 		return(-1); | ||||
| 	    case E2BIG: | ||||
| 		if(shp->xargmin) | ||||
| 		if(sh_isstate(SH_XARG)) | ||||
| 		{ | ||||
| 			pid = path_xargs(shp,opath, &argv[0] ,envp,spawn); | ||||
| 			if(pid<0) | ||||
| 				errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),"%s: 'command -x' failed",path); | ||||
| 				errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),"command -x: could not execute %s",path); | ||||
| 			return(pid); | ||||
| 		} | ||||
| 	    default: | ||||
|  |  | |||
|  | @ -1024,7 +1024,7 @@ int sh_exec(register const Shnode_t *t, int flags) | |||
| 			} | ||||
| #endif /* SHOPT_NAMESPACE */ | ||||
| 			com0 = com[0]; | ||||
| 			shp->xargexit = 0; | ||||
| 			sh_offstate(SH_XARG); | ||||
| 			while(np==SYSCOMMAND || !np && com0 && nv_search(com0,shp->fun_tree,0)==SYSCOMMAND) | ||||
| 			{ | ||||
| 				register int n = b_command(0,com,&shp->bltindata); | ||||
|  | @ -1036,13 +1036,12 @@ int sh_exec(register const Shnode_t *t, int flags) | |||
| 					break; | ||||
| 				np = nv_bfsearch(com0, shp->bltin_tree, &nq, &cp);  | ||||
| 			} | ||||
| 			if(shp->xargexit) | ||||
| 			if(sh_isstate(SH_XARG)) | ||||
| 			{ | ||||
| 				shp->xargmin -= command; | ||||
| 				shp->xargmax -= command; | ||||
| 				shp->xargexit = 0; | ||||
| 			} | ||||
| 			else | ||||
| 				shp->xargmin = 0; | ||||
| 			argn -= command; | ||||
| 			if(np && is_abuiltin(np)) | ||||
| 			{ | ||||
|  | @ -1233,7 +1232,7 @@ int sh_exec(register const Shnode_t *t, int flags) | |||
| 					pipejob = 1; | ||||
| 				} | ||||
| 				/* check for builtins */ | ||||
| 				if(np && is_abuiltin(np)) | ||||
| 				if(np && is_abuiltin(np) && !sh_isstate(SH_XARG)) | ||||
| 				{ | ||||
| 					volatile int scope=0, share=0; | ||||
| 					volatile void *save_ptr; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue