# HG changeset patch # User Andrew Janke # Date 1548119248 18000 # Node ID 3bf19af20af85763a1ef713ba143b3b57474d03f # Parent e449134870fbd496313546c74c80d814a9934c20 tar, untar, unpack: Add support for BSD tar (bug #53695) * tar_is_bsd.m: New function. * tar.m: Use it to determine how to run tar and parse command output. * unpack.m: Likewise. diff -r e449134870fb -r 3bf19af20af8 scripts/miscellaneous/private/tar_is_bsd.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/miscellaneous/private/tar_is_bsd.m Mon Jan 21 20:07:28 2019 -0500 @@ -0,0 +1,42 @@ +## Copyright (C) 2019 Andrew Janke +## +## This file is part of Octave. +## +## Octave is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . + +## -*- texinfo -*- +## @deftypefn {} {@var{out} =} tar_is_bsd () +## True if the default tar command is BSD tar. +## +## Checks whether the default tar command (the one invoked when an un-prefixed +## @code{tar} is executed) is BSD tar or another tar. Caches the results for +## performance. +## +## Returns true if the detected tar is BSD tar, and false otherwise. Errors if +## @code{tar --version} does not succeed. +## @end deftypefn + +function out = tar_is_bsd () + ## BSD tar needs to be handled differently from GNU tar + persistent cache + if isempty (cache) + [status, tar_ver_str] = system ("tar --version"); + if (status) + error ("tar: Failed executing tar --version (status = %d)", status); + endif + cache = ! isempty (regexp (tar_ver_str, "bsdtar")); + endif + out = cache; +endfunction diff -r e449134870fb -r 3bf19af20af8 scripts/miscellaneous/tar.m --- a/scripts/miscellaneous/tar.m Wed Aug 07 19:21:35 2019 +0200 +++ b/scripts/miscellaneous/tar.m Mon Jan 21 20:07:28 2019 -0500 @@ -60,8 +60,14 @@ tarfile = __w2mpth__ (tarfile); endif - cmd = sprintf ("tar cvf %s -C %s %s", - tarfile, rootdir, sprintf (" %s", files{:})); + ## BSD tar emits progress on stderr + if (tar_is_bsd ()) + cmd = sprintf ("tar cvf %s -C %s %s 2>&1", + tarfile, rootdir, sprintf (" '%s'", files{:})); + else + cmd = sprintf ("tar cvf %s -C %s %s", + tarfile, rootdir, sprintf (" %s", files{:})); + end ## Save and restore the TAR_OPTIONS environment variable used by GNU tar. tar_options_env = getenv ("TAR_OPTIONS"); @@ -81,6 +87,11 @@ if (nargout > 0) filelist = ostrsplit (output, "\r\n", true); filelist = filelist'; + + ## BSD tar emits file actions in the first 2 columns + if (tar_is_bsd ()) + filelist = cellfun (@(x) x(3:end), filelist, 'UniformOutput', false); + endif endif endfunction diff -r e449134870fb -r 3bf19af20af8 scripts/miscellaneous/unpack.m --- a/scripts/miscellaneous/unpack.m Wed Aug 07 19:21:35 2019 +0200 +++ b/scripts/miscellaneous/unpack.m Mon Jan 21 20:07:28 2019 -0500 @@ -308,7 +308,11 @@ endfunction function output = __parse_tar__ (output) - ## This is a no-op, but it makes things simpler for other cases. + ## BSD tar emits file actions in the first 2 columns + + if (tar_is_bsd ()) + output = cellfun (@(x) x(3:end), output, 'UniformOutput', false); + endif endfunction function files = __parse_gzip__ (output)