zdiff problem

Bryan Kadzban bryan at kadzban.is-a-geek.net
Sun May 17 20:48:08 PDT 2009


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.)

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 260 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxfromscratch.org/pipermail/lfs-dev/attachments/20090517/ab1ee7dc/attachment.sig>


More information about the lfs-dev mailing list