Opened 5 years ago

#56237 new enhancement

Use /usr/bin/gzip to decompress .xz files on macOS >= 10.10

Reported by: raimue (Rainer Müller) Owned by:
Priority: Normal Milestone: MacPorts Future
Component: base Version:
Keywords: Cc:
Port:

Description

On macOS >= 10.10, the /usr/bin/gzip binary can not only decompress gzip, but also accepts data compressed with bzip2 or xz. Note that it can only decompress these formats and compression is only supported to the gzip format.

$ echo "MacPorts" | xz -c | /usr/bin/gzip -d
MacPorts

The implementation can be found in file_cmds, where file_cmds-242 corresponds to the version shipped with OS X 10.10.

We should detect this in our configure script. If xz was not found, then check whether gzip also supports the xz format. If it does, fill the path to gzip into a new portutil::autoconf::unxz_path (similar to the existing xz_path). This variable can then be used as the fallback with findBinary when the goal is to find a binary for decompression only. Extra dependencies on bin:xz:xz would only be necessary when unxz_path is empty.

set xz [findBinary xz ${portutil::autoconf::unxz_path}]

The complicated part will be the check for the configure script. To test the decompression, we will need to embed a binary representation of a string compressed with xz into the configure script.

I already came up with the following example which should be POSIX shell compatible. Octal seems to be the only standardized format to store such data. Note this should not require any special tools for conversion back to the binary format before piping to the decompressor.

Prepare this once for inclusion into the configure script. Compress a string and convert the binary data to a string of octal character constants.

echo "MacPorts" | xz -c | xxd -p -c 1 | while read c; do printf "\%o" 0x$c; done; echo

The actual check in the configure script would then look something like this:

xzdata="\375\67\172\130\132\0\0\4\346\326\264\106\2\0\41\1\26\0\0\0\164\57\345\243\1\0\10\115\141\143\120\157\162\164\163\12\0\0\0\0\215\276\42\112\33\313\231\317\0\1\41\11\154\30\305\325\37\266\363\175\1\0\0\0\0\4\131\132"
dec=$(printf $xzdata | gzip -dc 2>/dev/null)
if [ "$dec" == "MacPorts" ]; then
    ...
fi

Change History (0)

Note: See TracTickets for help on using tickets.