tar: handle the case when opened created tarball happens to have fd#0
Reproducer: exec 0>&- exec 1>&- tar czf z.tar.gz FILE function old new delta vfork_compressor 229 257 +28 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
45d68c3749
commit
037759bb4f
@ -611,6 +611,7 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip)
|
||||
|
||||
if (xvfork() == 0) {
|
||||
/* child */
|
||||
int tfd;
|
||||
/* NB: close _first_, then move fds! */
|
||||
close(data.wr);
|
||||
# if WAIT_FOR_CHILD
|
||||
@ -619,8 +620,23 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip)
|
||||
* parent waits for this close to happen */
|
||||
fcntl(status.wr, F_SETFD, FD_CLOEXEC);
|
||||
# endif
|
||||
/* copy it: parent's tar_fd variable must not change */
|
||||
tfd = tar_fd;
|
||||
if (tfd == 0) {
|
||||
/* Output tar fd may be zero.
|
||||
* xmove_fd(data.rd, 0) would destroy it.
|
||||
* Reproducer:
|
||||
* exec 0>&-
|
||||
* exec 1>&-
|
||||
* tar czf Z.tar.gz FILE
|
||||
* Swapping move_fd's order wouldn't work:
|
||||
* data.rd is 1 and _it_ would be destroyed.
|
||||
*/
|
||||
xmove_fd(tfd, 3);
|
||||
tfd = 3;
|
||||
}
|
||||
xmove_fd(data.rd, 0);
|
||||
xmove_fd(tar_fd, 1);
|
||||
xmove_fd(tfd, 1);
|
||||
/* exec gzip/bzip2 program/applet */
|
||||
BB_EXECLP(gzip, gzip, "-f", (char *)0);
|
||||
vfork_exec_errno = errno;
|
||||
@ -715,11 +731,7 @@ static NOINLINE int writeTarFile(
|
||||
return errorFlag;
|
||||
}
|
||||
|
||||
#else /* !FEATURE_TAR_CREATE */
|
||||
|
||||
# define writeTarFile(...) 0
|
||||
|
||||
#endif
|
||||
#endif /* FEATURE_TAR_CREATE */
|
||||
|
||||
#if ENABLE_FEATURE_TAR_FROM
|
||||
static llist_t *append_file_list_to_list(llist_t *list)
|
||||
|
Loading…
Reference in New Issue
Block a user