mirror of
				git://git.code.sf.net/p/cdesktopenv/code
				synced 2025-03-09 15:50:02 +00:00 
			
		
		
		
	Backport bugfix for BUG_CSUBSTDO from ksh93v- 2012-08-24 (#259)
This commit fixes BUG_CSUBSTDO, which could break stdout inside of non-forking command substitutions. The breakage only occurred when stdout was closed outside of the command substitution and a file descriptor other than stdout was redirected in the command substitution (such as stderr). Thanks to the ast-open-history repo, I was able to identify and backport the bugfix from ksh93v- 2012-08-24. This backport may fix other bugs as well. On 93v- 2012-08-24 it fixed the regression below, though it was not triggered on 93u+(m). src/cmd/ksh93/tests/heredoc.sh 487 print foo > $tmp/foofile 488 x=$( $SHELL 2> /dev/null 'read <<< $(<'"$tmp"'/foofile) 2> /dev/null;print -r "$REPLY"') 489 [[ $x == foo ]] || err_exit '<<< $(<file) not working' src/cmd/ksh93/sh/io.c: sh_open(): - If the just-opened file descriptor exists in sftable and is flagged with SF_STRING (as in non-forking command substitutions, among other situations), then move the file descriptor to a number >= 10. src/cmd/ksh93/tests/io.sh: - Add a regression test for BUG_CSUBSTDO, adapted from the one in modernish.
This commit is contained in:
		
							parent
							
								
									b2a7ec032f
								
							
						
					
					
						commit
						0cd8646361
					
				
					 4 changed files with 25 additions and 6 deletions
				
			
		|  | @ -755,6 +755,7 @@ onintr(struct addrinfo* addr, void* handle) | |||
| int sh_open(register const char *path, int flags, ...) | ||||
| { | ||||
| 	Shell_t			*shp = sh_getinterp(); | ||||
| 	Sfio_t			*sp; | ||||
| 	register int		fd = -1; | ||||
| 	mode_t			mode; | ||||
| 	char			*e; | ||||
|  | @ -869,6 +870,16 @@ int sh_open(register const char *path, int flags, ...) | |||
| 		mode = IOREAD; | ||||
| 	if(fd >= shp->gd->lim.open_max) | ||||
| 		sh_iovalidfd(shp,fd); | ||||
| 	if((sp = shp->sftable[fd]) && (sfset(sp,0,0) & SF_STRING)) | ||||
| 	{ | ||||
| 		int n,err=errno; | ||||
| 		if((n = sh_fcntl(fd,F_DUPFD,10)) >= 10) | ||||
| 		{ | ||||
| 			while(close(fd) < 0 && errno == EINTR) | ||||
| 				errno = err; | ||||
| 			fd = n; | ||||
| 		} | ||||
| 	} | ||||
| 	shp->fdstatus[fd] = mode; | ||||
| 	return(fd); | ||||
| } | ||||
|  |  | |||
|  | @ -785,5 +785,15 @@ then | |||
| 		"(expected $(printf %q "$expect"), got $(printf %q "$actual"))" | ||||
| fi | ||||
| 
 | ||||
| # ====== | ||||
| # Test for BUG_CSUBSTDO: If stdout is closed before running a command substitution, | ||||
| # redirecting any file descriptor in the command substitution would break stdout | ||||
| # inside of the command substitution. This only occurred when redirecting any other | ||||
| # file descriptor inside of the command substitution. | ||||
| exp='Foo bar' | ||||
| { got=$(echo 'Foo bar' 2>/dev/null); } >&- | ||||
| [[ $exp == $got ]] || err_exit "BUG_CSUBSTDO: Closing stdout outside of command substitution breaks stdout inside of command substitution" \ | ||||
| 	"(expected $(printf %q "$exp"), got $(printf %q "$got"))" | ||||
| 
 | ||||
| # ====== | ||||
| exit $((Errors<125?Errors:125)) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue