>From 0bc9113dc8fa6c3f631094dd1caa44c2874984b0 Mon Sep 17 00:00:00 2001
From: John Spencer <[email protected]>
Date: Fri, 20 Sep 2013 19:28:29 +0200
Subject: [PATCH] tar: support xz compression as well
the previous patch by Boris Reisig, dfc2473b9ed88039697ac89ee2a4301cdaefcf84 ,
while adding the J flag for xz, did only add recognition of the J flag,
but did not activate usage of a compressor for xz files.
so usage of `tar cJf etc.tar.xz /etc/` resulted in a regular uncompressed
tarball.
unfortunately busybox currently does not offer xz compression support,
but this makes it at least able to use the J flag when the full xz is
installed without having to install a separate tar program.
in order to implement this effectively, some old ifdef cruft was removed,
which resulted in a 12-byte smaller tar binary when no compressor support
was enabled at all. i decided to sacrifice these 12bytes in this uncommon
usage case for readability.
---
archival/tar.c | 65 +++++++++++++++++++++++++++++--------------------------
1 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/archival/tar.c b/archival/tar.c
index 3cd033b..7e5cf2d 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -58,13 +58,6 @@
#define block_buf bb_common_bufsiz1
-#if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2
-/* Do not pass gzip flag to writeTarFile() */
-#define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \
- writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude)
-#endif
-
-
#if ENABLE_FEATURE_TAR_CREATE
/*
@@ -519,21 +512,29 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb
return TRUE;
}
-#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
-# if !(ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2)
-# define vfork_compressor(tar_fd, gzip) vfork_compressor(tar_fd)
-# endif
+enum compressor_type {
+ ct_none = 0,
+ ct_gzip = 1,
+ ct_bzip2 = 2,
+ ct_xz = 3,
+};
+
+#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ
/* Don't inline: vfork scares gcc and pessimizes code */
-static void NOINLINE vfork_compressor(int tar_fd, int gzip)
+static void NOINLINE vfork_compressor(int tar_fd, enum compressor_type ct)
{
pid_t gzipPid;
-# if ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2
- const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2";
-# elif ENABLE_FEATURE_SEAMLESS_GZ
- const char *zip_exec = "gzip";
-# else /* only ENABLE_FEATURE_SEAMLESS_BZ2 */
- const char *zip_exec = "bzip2";
-# endif
+ static const char compressor[][6] = {
+ [ct_gzip - 1] = "gzip",
+#if ENABLE_FEATURE_SEAMLESS_BZ2
+ [ct_bzip2 - 1] = "bzip2",
+#endif
+#if ENABLE_FEATURE_SEAMLESS_XZ
+ [ct_xz - 1] = "xz",
+#endif
+ };
+ const char *zip_exec = compressor[ct-1];
+
// On Linux, vfork never unpauses parent early, although standard
// allows for that. Do we want to waste bytes checking for it?
# define WAIT_FOR_CHILD 0
@@ -593,13 +594,13 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip)
bb_perror_msg_and_die("can't execute '%s'", zip_exec);
}
}
-#endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */
+#endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ */
/* gcc 4.2.1 inlines it, making code bigger */
static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
int recurseFlags, const llist_t *include,
- const llist_t *exclude, int gzip)
+ const llist_t *exclude, enum compressor_type ct)
{
int errorFlag = FALSE;
struct TarBallInfo tbInfo;
@@ -612,9 +613,9 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
* can avoid including the tarball into itself.... */
xfstat(tbInfo.tarFd, &tbInfo.tarFileStatBuf, "can't stat tar file");
-#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
- if (gzip)
- vfork_compressor(tbInfo.tarFd, gzip);
+#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ
+ if (ct != ct_none)
+ vfork_compressor(tbInfo.tarFd, ct);
#endif
tbInfo.excludeList = exclude;
@@ -647,8 +648,8 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
if (errorFlag)
bb_error_msg("error exit delayed from previous errors");
-#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
- if (gzip) {
+#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ
+ if (ct != ct_none) {
int status;
if (safe_waitpid(-1, &status, 0) == -1)
bb_perror_msg("waitpid");
@@ -662,7 +663,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
#else
int writeTarFile(int tar_fd, int verboseFlag,
int recurseFlags, const llist_t *include,
- const llist_t *exclude, int gzip);
+ const llist_t *exclude, enum compressor_type ct);
#endif /* FEATURE_TAR_CREATE */
#if ENABLE_FEATURE_TAR_FROM
@@ -1053,12 +1054,14 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
/* Create an archive */
if (opt & OPT_CREATE) {
-#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
- int zipMode = 0;
+ enum compressor_type zipMode = ct_none;
+#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ
if (ENABLE_FEATURE_SEAMLESS_GZ && (opt & OPT_GZIP))
- zipMode = 1;
+ zipMode = ct_gzip;
if (ENABLE_FEATURE_SEAMLESS_BZ2 && (opt & OPT_BZIP2))
- zipMode = 2;
+ zipMode = ct_bzip2;
+ if (ENABLE_FEATURE_SEAMLESS_XZ && (opt & OPT_XZ))
+ zipMode = ct_xz;
#endif
/* NB: writeTarFile() closes tar_handle->src_fd */
return writeTarFile(tar_handle->src_fd, verboseFlag,
--
1.7.3.4
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox