diff options
Diffstat (limited to 'archival/tar.c')
-rw-r--r-- | archival/tar.c | 57 |
1 files changed, 25 insertions, 32 deletions
diff --git a/archival/tar.c b/archival/tar.c index ae1ccc756..9239d8ee4 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -596,34 +596,30 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb /* Don't inline: vfork scares gcc and pessimizes code */ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) { - pid_t gzipPid; - // 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 volatile int vfork_exec_errno = 0; - struct fd_pair gzipDataPipe; + struct fd_pair data; # if WAIT_FOR_CHILD - struct fd_pair gzipStatusPipe; - xpiped_pair(gzipStatusPipe); + struct fd_pair status; + xpiped_pair(status); # endif - xpiped_pair(gzipDataPipe); + xpiped_pair(data); signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ - gzipPid = xvfork(); - - if (gzipPid == 0) { + if (xvfork() == 0) { /* child */ /* NB: close _first_, then move fds! */ - close(gzipDataPipe.wr); + close(data.wr); # if WAIT_FOR_CHILD - close(gzipStatusPipe.rd); - /* gzipStatusPipe.wr will close only on exec - + close(status.rd); + /* status.wr will close only on exec - * parent waits for this close to happen */ - fcntl(gzipStatusPipe.wr, F_SETFD, FD_CLOEXEC); + fcntl(status.wr, F_SETFD, FD_CLOEXEC); # endif - xmove_fd(gzipDataPipe.rd, 0); + xmove_fd(data.rd, 0); xmove_fd(tar_fd, 1); /* exec gzip/bzip2 program/applet */ BB_EXECLP(gzip, gzip, "-f", (char *)0); @@ -632,20 +628,18 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) } /* parent */ - xmove_fd(gzipDataPipe.wr, tar_fd); - close(gzipDataPipe.rd); + xmove_fd(data.wr, tar_fd); + close(data.rd); # if WAIT_FOR_CHILD - close(gzipStatusPipe.wr); + close(status.wr); while (1) { - char buf; - int n; - /* Wait until child execs (or fails to) */ - n = full_read(gzipStatusPipe.rd, &buf, 1); + char buf; + int n = full_read(status.rd, &buf, 1); if (n < 0 /* && errno == EAGAIN */) continue; /* try it again */ } - close(gzipStatusPipe.rd); + close(status.rd); # endif if (vfork_exec_errno) { errno = vfork_exec_errno; @@ -1155,17 +1149,16 @@ int tar_main(int argc UNUSED_PARAM, char **argv) if (LONE_DASH(tar_filename)) { tar_handle->src_fd = tar_fd; tar_handle->seek = seek_by_read; + } else + if (ENABLE_FEATURE_TAR_AUTODETECT + && flags == O_RDONLY + && !(opt & OPT_ANY_COMPRESS) + ) { + tar_handle->src_fd = open_zipped(tar_filename, /*fail_if_not_compressed:*/ 0); + if (tar_handle->src_fd < 0) + bb_perror_msg_and_die("can't open '%s'", tar_filename); } else { - if (ENABLE_FEATURE_TAR_AUTODETECT - && flags == O_RDONLY - && !(opt & OPT_ANY_COMPRESS) - ) { - tar_handle->src_fd = open_zipped(tar_filename, /*fail_if_not_compressed:*/ 0); - if (tar_handle->src_fd < 0) - bb_perror_msg_and_die("can't open '%s'", tar_filename); - } else { - tar_handle->src_fd = xopen(tar_filename, flags); - } + tar_handle->src_fd = xopen(tar_filename, flags); } } |