Using BB_EXECVP allows for more control over the compressor
program executed.

The xz compressor is disabled when applets are prefered,
since the xz applet does not support compression.

Signed-off-by: Nadav Tasher <tasherna...@gmail.com>
---
 archival/tar.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/archival/tar.c b/archival/tar.c
index d6ca6c1e0..6cfea8fd5 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -575,6 +575,7 @@ static void NOINLINE vfork_compressor(int tar_fd, const 
char *gzip)
        // 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
+       char *compressor_arg0, compressor_arg1[] = "-f", *compressor_argv[3];
        volatile int vfork_exec_errno = 0;
        struct fd_pair data;
 #  if WAIT_FOR_CHILD
@@ -614,11 +615,28 @@ static void NOINLINE vfork_compressor(int tar_fd, const 
char *gzip)
                xmove_fd(tfd, 1);
 
                /* exec gzip/bzip2/... program */
-               //BB_EXECLP(gzip, gzip, "-f", (char *)0); - WRONG for "xz",
-               // if xz is an enabled applet, it'll be a version which
-               // can only decompress. We do need to execute external
-               // program, not applet.
-               execlp(gzip, gzip, "-f", (char *)0);
+
+# if ENABLE_FEATURE_PREFER_APPLETS && ENABLE_XZ
+               /* if xz is an enabled applet, it'll be a version which
+                * can only decompress. We can't use BB_EXECVP, since
+                * it will execute the applet. */
+               if (strncmp(gzip, "xz", 2))
+                       _exit_FAILURE();
+# endif
+
+               /* we need to duplicate gzip, since BB_EXECVP might
+                * modify it. */
+               compressor_arg0 = xstrdup(gzip);
+
+               compressor_argv[0] = compressor_arg0;
+               compressor_argv[1] = compressor_arg1;
+               compressor_argv[2] = NULL;
+
+               /* This works for all other compressions. */
+               BB_EXECVP(compressor_argv[0], compressor_argv);
+
+               /* we need to free the copy of gzip */
+               free(compressor_arg0);
 
                vfork_exec_errno = errno;
                _exit_FAILURE();
-- 
2.43.0

_______________________________________________
busybox mailing list
busybox@busybox.net
https://lists.busybox.net/mailman/listinfo/busybox

Reply via email to