Hello,
I'm sending you an updated patch against the current git master. Note,
in addition to supporting lz4 and zstd does it add a single 'break;'
into tar.c at line 1130:
case LZOP_OPTION:
s = xasprintf (_("filter the archive through %s"), LZOP_PROGRAM);
+ break;
which previously caused the case to fall-through and for the --help
option to print a wrong message regarding what gets filter through which
compression tool. Because it's a single, missing break-statement did I
not create an extra patch for it.
Regards,
Sven
On 05/08/17 15:25, Sven C. Dack wrote:
Hello,
I've created a patch for tar, which adds support for lz4 and zstd
compression. Both compression tools have become increasingly popular
and offer high-speed compression and decompression, making them
interesting alternatives to previous compression tools.
lz4 is similar to lzo, but offers faster decompression. zstd is
similar to gzip, but offers much faster compression and decompression.
See also:
http://lz4.github.io/lz4/
http://facebook.github.io/zstd/
For example, creating an archive from a directory of 1.12 GB
containing binary and ASCII files ("/usr/local/gnu/"):
Compression
name time size ratio
gnu.tar.gz 57.2s 534077354 44.3%
gnu.tar.bz2 1:53.9s 509401491 42.3%
gnu.tar.xz 7:15.6s 423886520 35.2%
gnu.tar.lz 7:37.2s 425162846 35.3%
gnu.tar.lzo 4.7s 676569472 56.2%
gnu.tar.lz4 4.9s 676600069 56.2%
gnu.tar.zst 10.7s 517897416 43.0%
Decompression
name time
gnu.tar.gz 7.1s
gnu.tar.bz2 45.2s
gnu.tar.xz 26.3s
gnu.tar.lz 30.4s
gnu.tar.lzo 3.5s
gnu.tar.lz4 2.0s
gnu.tar.zst 3.2s
A second example using the Linux kernel source code (4.12.4),
containing 697 MB of data:
Compression
name time size ratio
linux.tar.gz 28.2s 156988489 21.4%
linux.tar.bz2 1:05.5s 120659282 16.5%
linux.tar.xz 4:26.9s 102214892 13.9%
linux.tar.lz 4:18.4s 104105244 14.2%
linux.tar.lzo 3.6s 261745137 35.7%
linux.tar.lz4 3.9s 252707015 34.5%
linux.tar.zst 5.9s 150448272 20.5%
Decompression
name time
linux.tar.gz 3.6s
linux.tar.bz2 19.4s
linux.tar.xz 7.2s
linux.tar.lz 8.1s
linux.tar.lzo 2.5s
linux.tar.lz4 1.5s
linux.tar.zst 2.1s
(The tools were used with their default arguments. The hardware used
was an AMD FX8350 4GHz.)
Attached files are:
patch-part-1 - diffs of buffer.c config.h.in configure.ac suffix.c tar.c
patch-part-2 - diffs of tar.texi tar.1 cs.po de.po fi.po ga.po id.po
ru.po sl.po zh_CN.po
Cheers
diff --git a/configure.ac b/configure.ac
index e89ed1d..680dde7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -249,6 +249,8 @@ TAR_COMPR_PROGRAM(bzip2)
TAR_COMPR_PROGRAM(lzip)
TAR_COMPR_PROGRAM(lzma)
TAR_COMPR_PROGRAM(lzop)
+TAR_COMPR_PROGRAM(lz4)
+TAR_COMPR_PROGRAM(zstd)
TAR_COMPR_PROGRAM(xz)
AC_MSG_CHECKING(for default archive format)
diff --git a/doc/tar.1 b/doc/tar.1
index f5c1fca..3506169 100644
--- a/doc/tar.1
+++ b/doc/tar.1
@@ -13,7 +13,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
-.TH TAR 1 "March 23, 2016" "TAR" "GNU TAR Manual"
+.TH TAR 1 "August 5, 2017" "TAR" "GNU TAR Manual"
.SH NAME
tar \- an archiving utility
.SH SYNOPSIS
@@ -818,6 +818,14 @@ Filter the archive through
Filter the archive through
.BR lzop (1).
.TP
+\fB\-\-lz4\fR
+Filter the archive through
+.BR lz4 (1).
+.TP
+\fB\-\-zstd\fR
+Filter the archive through
+.BR zstd (1).
+.TP
\fB\-\-no\-auto\-compress\fR
Do not use archive suffix to determine the compression program.
.TP
@@ -1285,6 +1293,8 @@ failure during backup to a remote device.
.BR gzip (1),
.BR lzma (1),
.BR lzop (1),
+.BR lz4 (1),
+.BR zstd (1),
.BR rmt (8),
.BR symlink (7),
.BR tar (5),
diff --git a/doc/tar.texi b/doc/tar.texi
index edd190e..1ac1d4b 100644
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -2971,6 +2971,16 @@ This option tells @command{tar} to read or write archives through
This option tells @command{tar} to read or write archives through
@command{lzop}. @xref{gzip}.
+@item --lz4
+
+This option tells @command{tar} to read or write archives through
+@command{lz4}. @xref{gzip}.
+
+@item --zstd
+
+This option tells @command{tar} to read or write archives through
+@command{zstd}. @xref{gzip}.
+
@opsummary{mode}
@item --mode=@var{permissions}
@@ -9568,14 +9578,17 @@ switch to @samp{posix}.
@cindex lzip
@cindex lzma
@cindex lzop
+@cindex lz4
+@cindex zstd
@cindex compress
@GNUTAR{} is able to create and read compressed archives. It supports
a wide variety of compression programs, namely: @command{gzip},
@command{bzip2}, @command{lzip}, @command{lzma}, @command{lzop},
-@command{xz} and traditional @command{compress}. The latter is
-supported mostly for backward compatibility, and we recommend
-against using it, because it is by far less effective than the other
-compression programs@footnote{It also had patent problems in the past.}.
+@command{lz4}, @command{zstd}, @command{xz} and traditional
+@command{compress}. The latter is supported mostly for backward
+compatibility, and we recommend against using it, because it is by far
+less effective than the other compression programs@footnote{It also
+had patent problems in the past.}.
Creating a compressed archive is simple: you just specify a
@dfn{compression option} along with the usual archive creation
@@ -9584,10 +9597,11 @@ create a @command{gzip} compressed archive, @option{-j}
(@option{--bzip2}) to create a @command{bzip2} compressed archive,
@option{--lzip} to create an @asis{lzip} compressed archive,
@option{-J} (@option{--xz}) to create an @asis{XZ} archive,
-@option{--lzma} to create an @asis{LZMA} compressed
-archive, @option{--lzop} to create an @asis{LSOP} archive, and
-@option{-Z} (@option{--compress}) to use @command{compress} program.
-For example:
+@option{--lzma} to create an @asis{LZMA} compressed archive,
+@option{--lzop} to create an @asis{LSOP} archive, @option{--lz4} to
+create an @asis{LZ4} archive, @option{--zstd} to create an @asis{ZST}
+archive, and @option{-Z} (@option{--compress}) to use
+@command{compress} program. For example:
@smallexample
$ @kbd{tar czf archive.tar.gz .}
@@ -9707,6 +9721,14 @@ Filter the archive through @command{lzma}.
@item --lzop
Filter the archive through @command{lzop}.
+@opindex lz4
+@item --lz4
+Filter the archive through @command{lz4}.
+
+@opindex zstd
+@item --zstd
+Filter the archive through @command{zstd}.
+
@opindex compress
@opindex uncompress
@item -Z
@@ -9778,6 +9800,8 @@ suffix. The following suffixes are recognized:
@item @samp{.lzma} @tab @command{lzma}
@item @samp{.tlz} @tab @command{lzma}
@item @samp{.lzo} @tab @command{lzop}
+@item @samp{.lz4} @tab @command{lz4}
+@item @samp{.zst} @tab @command{zstd}
@item @samp{.xz} @tab @command{xz}
@end multitable
diff --git a/src/buffer.c b/src/buffer.c
index 6f96c2f..d635499 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -281,6 +281,8 @@ enum compress_type {
ct_lzip,
ct_lzma,
ct_lzop,
+ ct_lz4,
+ ct_zstd,
ct_xz
};
@@ -309,6 +311,8 @@ static struct zip_magic const magic[] = {
{ ct_lzip, 4, "LZIP" },
{ ct_lzma, 6, "\xFFLZMA" },
{ ct_lzop, 4, "\211LZO" },
+ { ct_lz4, 4, "\x04\x22\x4D\x18" },
+ { ct_zstd, 4, "\x28\xB5\x2F\xFD" },
{ ct_xz, 6, "\xFD" "7zXZ" },
};
@@ -324,6 +328,8 @@ static struct zip_program zip_program[] = {
{ ct_lzma, LZMA_PROGRAM, "--lzma" },
{ ct_lzma, XZ_PROGRAM, "-J" },
{ ct_lzop, LZOP_PROGRAM, "--lzop" },
+ { ct_lz4, LZ4_PROGRAM, "--lz4" },
+ { ct_zstd, ZSTD_PROGRAM, "--zstd" },
{ ct_xz, XZ_PROGRAM, "-J" },
{ ct_none }
};
diff --git a/src/suffix.c b/src/suffix.c
index 47027e7..251a3ae 100644
--- a/src/suffix.c
+++ b/src/suffix.c
@@ -44,6 +44,8 @@ static struct compression_suffix compression_suffixes[] = {
{ S(lzma, LZMA) },
{ S(tlz, LZMA) },
{ S(lzo, LZOP) },
+ { S(lz4, LZ4) },
+ { S(zst, ZSTD) },
{ S(xz, XZ) },
{ S(txz, XZ) }, /* Slackware */
{ NULL }
diff --git a/src/tar.c b/src/tar.c
index ea68c82..74b8a6e 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -293,6 +293,8 @@ enum
LZIP_OPTION,
LZMA_OPTION,
LZOP_OPTION,
+ LZ4_OPTION,
+ ZSTD_OPTION,
MODE_OPTION,
MTIME_OPTION,
NEWER_MTIME_OPTION,
@@ -681,6 +683,8 @@ static struct argp_option options[] = {
{"lzip", LZIP_OPTION, 0, 0, NULL, GRID+1 },
{"lzma", LZMA_OPTION, 0, 0, NULL, GRID+1 },
{"lzop", LZOP_OPTION, 0, 0, NULL, GRID+1 },
+ {"lz4", LZ4_OPTION, 0, 0, NULL, GRID+1 },
+ {"zstd", ZSTD_OPTION, 0, 0, NULL, GRID+1 },
{"xz", 'J', 0, 0, NULL, GRID+1 },
#undef GRID
@@ -1123,6 +1127,15 @@ tar_help_filter (int key, const char *text, void *input)
case LZOP_OPTION:
s = xasprintf (_("filter the archive through %s"), LZOP_PROGRAM);
+ break;
+
+ case LZ4_OPTION:
+ s = xasprintf (_("filter the archive through %s"), LZ4_PROGRAM);
+ break;
+
+ case ZSTD_OPTION:
+ s = xasprintf (_("filter the archive through %s"), ZSTD_PROGRAM);
+ break;
case 'J':
s = xasprintf (_("filter the archive through %s"), XZ_PROGRAM);
@@ -1494,6 +1507,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
set_use_compress_program_option (LZOP_PROGRAM, args->loc);
break;
+ case LZ4_OPTION:
+ set_use_compress_program_option (LZ4_PROGRAM, args->loc);
+ break;
+
+ case ZSTD_OPTION:
+ set_use_compress_program_option (ZSTD_PROGRAM, args->loc);
+ break;
+
case 'm':
touch_option = true;
break;