Bruce Dubbs wrote: > The problem code looks like: > > gzip_status=$( > exec 4>&1 > (gzip -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- | > ( (gzip -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- 5<&- </dev/null | > eval "$cmp" /dev/fd/5 -) 5<&0 > )
Sheesh, that's complicated! Let's see if I can decipher... Duplicate FD 1 into FD 4. Then start a subshell with FD 3 closed (...but where was 3 opened? before this?); in that subshell, gunzip $1 to FD 1, closing FD 4 before doing so, and echo the exit status into FD 4. Pipe FD 1 (the decompressed file) into another subshell, and duplicate that input stream into FD 5 (hmm; FDs 0 and 5 are both this stream...). In that second subshell, start yet another subshell with FDs 5 and 3 (...again, with 3) closed, and with stdin coming from /dev/null (not the pipe); in that subshell, gunzip $2 to stdout with FD 4 closed, and echo the exit status of this gzip into FD 4 as well. Pipe the decompressed file into "eval $cmp /dev/fd/5 -" (whatever $cmp is; presumably - means stdin). Both exit statuses are put into gzip_status, along with whatever "$cmp" outputs. This last bit might be the bug, depending on where FD 3 is going. If FD 3 is a duplicate of the output stream of zdiff (e.g. they did an "exec 3>&1" earlier), then your fix is correct: the output of $cmp needs to be shown to the user, not dumped into the gzip_status variable. Looks like it's attempting to run "$cmp" (whatever it is) on the two streams of gunzip output. (/dev/fd/X is the current process's file descriptor X; useful for programs like diff and cmp that require file names, when you want to compare a stream.) It's a giant Y; the two arms of the Y are the gunzip streams, and the point in the middle is the $cmp invocation. The rest is just scaffolding to be able to capture the exit status of each gzip, and to make sure programs can't get at FDs they shouldn't be able to get at. (Does that actually help? :-) ) > When I look at /dev/fd, I only have 0 through 3 (and on RH and Ubuntu other > systems too, but none use gzip-1.3.12). That's because the ls process only has stdin, stdout, and stderr open; FD 3 is a handle to the /proc/self/fd directory itself in this case (because you're looking at its contents; opendir() returned 3). (Oh: /dev/fd is a symlink to /proc/self/fd; see /lib/udev/devices.)
signature.asc
Description: OpenPGP digital signature
-- http://linuxfromscratch.org/mailman/listinfo/lfs-dev FAQ: http://www.linuxfromscratch.org/faq/ Unsubscribe: See the above information page