diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-11-13 01:40:28 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-11-13 01:40:28 +0100 |
commit | 931cf64ae70f52024260090c44f09d7aaca33ec5 (patch) | |
tree | 28be18bfe4bc395d00065e8e1941a212c4e65964 | |
parent | 02e93b3a28e857015cd7678fbd8dd54c01ab8a5a (diff) | |
download | busybox-w32-931cf64ae70f52024260090c44f09d7aaca33ec5.tar.gz busybox-w32-931cf64ae70f52024260090c44f09d7aaca33ec5.tar.bz2 busybox-w32-931cf64ae70f52024260090c44f09d7aaca33ec5.zip |
tar: code shrink, better help text
function old new delta
tar_main 994 1013 +19
packed_usage 31893 31863 -30
writeTarFile 250 207 -43
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 19/-73) Total: -54 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/tar.c | 130 |
1 files changed, 68 insertions, 62 deletions
diff --git a/archival/tar.c b/archival/tar.c index 08924903e..4f4a7d8f3 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -49,7 +49,7 @@ | |||
49 | //config: tarballs. Currently it works only on files (not pipes etc). | 49 | //config: tarballs. Currently it works only on files (not pipes etc). |
50 | //config: | 50 | //config: |
51 | //config:config FEATURE_TAR_FROM | 51 | //config:config FEATURE_TAR_FROM |
52 | //config: bool "Enable -X (exclude from) and -T (include from) options)" | 52 | //config: bool "Enable -X (exclude from) and -T (include from) options" |
53 | //config: default y | 53 | //config: default y |
54 | //config: depends on TAR | 54 | //config: depends on TAR |
55 | //config: help | 55 | //config: help |
@@ -156,7 +156,9 @@ typedef struct TarBallInfo { | |||
156 | int tarFd; /* Open-for-write file descriptor | 156 | int tarFd; /* Open-for-write file descriptor |
157 | * for the tarball */ | 157 | * for the tarball */ |
158 | int verboseFlag; /* Whether to print extra stuff or not */ | 158 | int verboseFlag; /* Whether to print extra stuff or not */ |
159 | # if ENABLE_FEATURE_TAR_FROM | ||
159 | const llist_t *excludeList; /* List of files to not include */ | 160 | const llist_t *excludeList; /* List of files to not include */ |
161 | # endif | ||
160 | HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */ | 162 | HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */ |
161 | HardLinkInfo *hlInfo; /* Hard Link Info for the current file */ | 163 | HardLinkInfo *hlInfo; /* Hard Link Info for the current file */ |
162 | //TODO: save only st_dev + st_ino | 164 | //TODO: save only st_dev + st_ino |
@@ -278,7 +280,7 @@ static void chksum_and_xwrite(int fd, struct tar_header_t* hp) | |||
278 | xwrite(fd, hp, sizeof(*hp)); | 280 | xwrite(fd, hp, sizeof(*hp)); |
279 | } | 281 | } |
280 | 282 | ||
281 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 283 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
282 | static void writeLongname(int fd, int type, const char *name, int dir) | 284 | static void writeLongname(int fd, int type, const char *name, int dir) |
283 | { | 285 | { |
284 | static const struct { | 286 | static const struct { |
@@ -318,7 +320,7 @@ static void writeLongname(int fd, int type, const char *name, int dir) | |||
318 | memset(&header, 0, size); | 320 | memset(&header, 0, size); |
319 | xwrite(fd, &header, size); | 321 | xwrite(fd, &header, size); |
320 | } | 322 | } |
321 | #endif | 323 | # endif |
322 | 324 | ||
323 | /* Write out a tar header for the specified file/directory/whatever */ | 325 | /* Write out a tar header for the specified file/directory/whatever */ |
324 | static int writeTarHeader(struct TarBallInfo *tbInfo, | 326 | static int writeTarHeader(struct TarBallInfo *tbInfo, |
@@ -347,30 +349,30 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, | |||
347 | header.typeflag = LNKTYPE; | 349 | header.typeflag = LNKTYPE; |
348 | strncpy(header.linkname, tbInfo->hlInfo->name, | 350 | strncpy(header.linkname, tbInfo->hlInfo->name, |
349 | sizeof(header.linkname)); | 351 | sizeof(header.linkname)); |
350 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 352 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
351 | /* Write out long linkname if needed */ | 353 | /* Write out long linkname if needed */ |
352 | if (header.linkname[sizeof(header.linkname)-1]) | 354 | if (header.linkname[sizeof(header.linkname)-1]) |
353 | writeLongname(tbInfo->tarFd, GNULONGLINK, | 355 | writeLongname(tbInfo->tarFd, GNULONGLINK, |
354 | tbInfo->hlInfo->name, 0); | 356 | tbInfo->hlInfo->name, 0); |
355 | #endif | 357 | # endif |
356 | } else if (S_ISLNK(statbuf->st_mode)) { | 358 | } else if (S_ISLNK(statbuf->st_mode)) { |
357 | char *lpath = xmalloc_readlink_or_warn(fileName); | 359 | char *lpath = xmalloc_readlink_or_warn(fileName); |
358 | if (!lpath) | 360 | if (!lpath) |
359 | return FALSE; | 361 | return FALSE; |
360 | header.typeflag = SYMTYPE; | 362 | header.typeflag = SYMTYPE; |
361 | strncpy(header.linkname, lpath, sizeof(header.linkname)); | 363 | strncpy(header.linkname, lpath, sizeof(header.linkname)); |
362 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 364 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
363 | /* Write out long linkname if needed */ | 365 | /* Write out long linkname if needed */ |
364 | if (header.linkname[sizeof(header.linkname)-1]) | 366 | if (header.linkname[sizeof(header.linkname)-1]) |
365 | writeLongname(tbInfo->tarFd, GNULONGLINK, lpath, 0); | 367 | writeLongname(tbInfo->tarFd, GNULONGLINK, lpath, 0); |
366 | #else | 368 | # else |
367 | /* If it is larger than 100 bytes, bail out */ | 369 | /* If it is larger than 100 bytes, bail out */ |
368 | if (header.linkname[sizeof(header.linkname)-1]) { | 370 | if (header.linkname[sizeof(header.linkname)-1]) { |
369 | free(lpath); | 371 | free(lpath); |
370 | bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); | 372 | bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); |
371 | return FALSE; | 373 | return FALSE; |
372 | } | 374 | } |
373 | #endif | 375 | # endif |
374 | free(lpath); | 376 | free(lpath); |
375 | } else if (S_ISDIR(statbuf->st_mode)) { | 377 | } else if (S_ISDIR(statbuf->st_mode)) { |
376 | header.typeflag = DIRTYPE; | 378 | header.typeflag = DIRTYPE; |
@@ -400,9 +402,9 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, | |||
400 | * It always does unless off_t is wider than 64 bits. | 402 | * It always does unless off_t is wider than 64 bits. |
401 | */ | 403 | */ |
402 | else if (ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 404 | else if (ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
403 | #if ULLONG_MAX > 0xffffffffffffffffLL /* 2^64-1 */ | 405 | # if ULLONG_MAX > 0xffffffffffffffffLL /* 2^64-1 */ |
404 | && (filesize <= 0x3fffffffffffffffffffffffLL) | 406 | && (filesize <= 0x3fffffffffffffffffffffffLL) |
405 | #endif | 407 | # endif |
406 | ) { | 408 | ) { |
407 | /* GNU tar uses "base-256 encoding" for very large numbers. | 409 | /* GNU tar uses "base-256 encoding" for very large numbers. |
408 | * Encoding is binary, with highest bit always set as a marker | 410 | * Encoding is binary, with highest bit always set as a marker |
@@ -429,13 +431,13 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, | |||
429 | return FALSE; | 431 | return FALSE; |
430 | } | 432 | } |
431 | 433 | ||
432 | #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 434 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
433 | /* Write out long name if needed */ | 435 | /* Write out long name if needed */ |
434 | /* (we, like GNU tar, output long linkname *before* long name) */ | 436 | /* (we, like GNU tar, output long linkname *before* long name) */ |
435 | if (header.name[sizeof(header.name)-1]) | 437 | if (header.name[sizeof(header.name)-1]) |
436 | writeLongname(tbInfo->tarFd, GNULONGNAME, | 438 | writeLongname(tbInfo->tarFd, GNULONGNAME, |
437 | header_name, S_ISDIR(statbuf->st_mode)); | 439 | header_name, S_ISDIR(statbuf->st_mode)); |
438 | #endif | 440 | # endif |
439 | 441 | ||
440 | /* Now write the header out to disk */ | 442 | /* Now write the header out to disk */ |
441 | chksum_and_xwrite(tbInfo->tarFd, &header); | 443 | chksum_and_xwrite(tbInfo->tarFd, &header); |
@@ -457,7 +459,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, | |||
457 | return TRUE; | 459 | return TRUE; |
458 | } | 460 | } |
459 | 461 | ||
460 | #if ENABLE_FEATURE_TAR_FROM | 462 | # if ENABLE_FEATURE_TAR_FROM |
461 | static int exclude_file(const llist_t *excluded_files, const char *file) | 463 | static int exclude_file(const llist_t *excluded_files, const char *file) |
462 | { | 464 | { |
463 | while (excluded_files) { | 465 | while (excluded_files) { |
@@ -483,9 +485,9 @@ static int exclude_file(const llist_t *excluded_files, const char *file) | |||
483 | 485 | ||
484 | return 0; | 486 | return 0; |
485 | } | 487 | } |
486 | #else | 488 | # else |
487 | # define exclude_file(excluded_files, file) 0 | 489 | # define exclude_file(excluded_files, file) 0 |
488 | #endif | 490 | # endif |
489 | 491 | ||
490 | static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statbuf, | 492 | static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statbuf, |
491 | void *userData, int depth UNUSED_PARAM) | 493 | void *userData, int depth UNUSED_PARAM) |
@@ -538,12 +540,12 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb | |||
538 | if (exclude_file(tbInfo->excludeList, header_name)) | 540 | if (exclude_file(tbInfo->excludeList, header_name)) |
539 | return SKIP; | 541 | return SKIP; |
540 | 542 | ||
541 | #if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 543 | # if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
542 | if (strlen(header_name) >= NAME_SIZE) { | 544 | if (strlen(header_name) >= NAME_SIZE) { |
543 | bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); | 545 | bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); |
544 | return TRUE; | 546 | return TRUE; |
545 | } | 547 | } |
546 | #endif | 548 | # endif |
547 | 549 | ||
548 | /* Is this a regular file? */ | 550 | /* Is this a regular file? */ |
549 | if (tbInfo->hlInfo == NULL && S_ISREG(statbuf->st_mode)) { | 551 | if (tbInfo->hlInfo == NULL && S_ISREG(statbuf->st_mode)) { |
@@ -590,7 +592,7 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb | |||
590 | return TRUE; | 592 | return TRUE; |
591 | } | 593 | } |
592 | 594 | ||
593 | #if SEAMLESS_COMPRESSION | 595 | # if SEAMLESS_COMPRESSION |
594 | /* Don't inline: vfork scares gcc and pessimizes code */ | 596 | /* Don't inline: vfork scares gcc and pessimizes code */ |
595 | static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) | 597 | static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) |
596 | { | 598 | { |
@@ -598,13 +600,13 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) | |||
598 | 600 | ||
599 | // On Linux, vfork never unpauses parent early, although standard | 601 | // On Linux, vfork never unpauses parent early, although standard |
600 | // allows for that. Do we want to waste bytes checking for it? | 602 | // allows for that. Do we want to waste bytes checking for it? |
601 | # define WAIT_FOR_CHILD 0 | 603 | # define WAIT_FOR_CHILD 0 |
602 | volatile int vfork_exec_errno = 0; | 604 | volatile int vfork_exec_errno = 0; |
603 | struct fd_pair gzipDataPipe; | 605 | struct fd_pair gzipDataPipe; |
604 | # if WAIT_FOR_CHILD | 606 | # if WAIT_FOR_CHILD |
605 | struct fd_pair gzipStatusPipe; | 607 | struct fd_pair gzipStatusPipe; |
606 | xpiped_pair(gzipStatusPipe); | 608 | xpiped_pair(gzipStatusPipe); |
607 | # endif | 609 | # endif |
608 | xpiped_pair(gzipDataPipe); | 610 | xpiped_pair(gzipDataPipe); |
609 | 611 | ||
610 | signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ | 612 | signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ |
@@ -615,12 +617,12 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) | |||
615 | /* child */ | 617 | /* child */ |
616 | /* NB: close _first_, then move fds! */ | 618 | /* NB: close _first_, then move fds! */ |
617 | close(gzipDataPipe.wr); | 619 | close(gzipDataPipe.wr); |
618 | # if WAIT_FOR_CHILD | 620 | # if WAIT_FOR_CHILD |
619 | close(gzipStatusPipe.rd); | 621 | close(gzipStatusPipe.rd); |
620 | /* gzipStatusPipe.wr will close only on exec - | 622 | /* gzipStatusPipe.wr will close only on exec - |
621 | * parent waits for this close to happen */ | 623 | * parent waits for this close to happen */ |
622 | fcntl(gzipStatusPipe.wr, F_SETFD, FD_CLOEXEC); | 624 | fcntl(gzipStatusPipe.wr, F_SETFD, FD_CLOEXEC); |
623 | # endif | 625 | # endif |
624 | xmove_fd(gzipDataPipe.rd, 0); | 626 | xmove_fd(gzipDataPipe.rd, 0); |
625 | xmove_fd(tar_fd, 1); | 627 | xmove_fd(tar_fd, 1); |
626 | /* exec gzip/bzip2 program/applet */ | 628 | /* exec gzip/bzip2 program/applet */ |
@@ -632,7 +634,7 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) | |||
632 | /* parent */ | 634 | /* parent */ |
633 | xmove_fd(gzipDataPipe.wr, tar_fd); | 635 | xmove_fd(gzipDataPipe.wr, tar_fd); |
634 | close(gzipDataPipe.rd); | 636 | close(gzipDataPipe.rd); |
635 | # if WAIT_FOR_CHILD | 637 | # if WAIT_FOR_CHILD |
636 | close(gzipStatusPipe.wr); | 638 | close(gzipStatusPipe.wr); |
637 | while (1) { | 639 | while (1) { |
638 | char buf; | 640 | char buf; |
@@ -644,55 +646,52 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) | |||
644 | continue; /* try it again */ | 646 | continue; /* try it again */ |
645 | } | 647 | } |
646 | close(gzipStatusPipe.rd); | 648 | close(gzipStatusPipe.rd); |
647 | # endif | 649 | # endif |
648 | if (vfork_exec_errno) { | 650 | if (vfork_exec_errno) { |
649 | errno = vfork_exec_errno; | 651 | errno = vfork_exec_errno; |
650 | bb_perror_msg_and_die("can't execute '%s'", gzip); | 652 | bb_perror_msg_and_die("can't execute '%s'", gzip); |
651 | } | 653 | } |
652 | } | 654 | } |
653 | #endif /* SEAMLESS_COMPRESSION */ | 655 | # endif /* SEAMLESS_COMPRESSION */ |
654 | 656 | ||
655 | 657 | ||
656 | #if !SEAMLESS_COMPRESSION | 658 | # if !SEAMLESS_COMPRESSION |
657 | /* Do not pass gzip flag to writeTarFile() */ | 659 | /* Do not pass gzip flag to writeTarFile() */ |
658 | #define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \ | 660 | #define writeTarFile(tbInfo, recurseFlags, filelist, gzip) \ |
659 | writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude) | 661 | writeTarFile(tbInfo, recurseFlags, filelist) |
660 | #endif | 662 | # endif |
661 | /* gcc 4.2.1 inlines it, making code bigger */ | 663 | /* gcc 4.2.1 inlines it, making code bigger */ |
662 | static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | 664 | static NOINLINE int writeTarFile( |
663 | int recurseFlags, const llist_t *include, | 665 | struct TarBallInfo *tbInfo, |
664 | const llist_t *exclude, const char *gzip) | 666 | int recurseFlags, |
667 | const llist_t *filelist, | ||
668 | const char *gzip) | ||
665 | { | 669 | { |
666 | int errorFlag = FALSE; | 670 | int errorFlag = FALSE; |
667 | struct TarBallInfo tbInfo; | ||
668 | 671 | ||
669 | tbInfo.hlInfoHead = NULL; | 672 | /*tbInfo->hlInfoHead = NULL; - already is */ |
670 | tbInfo.tarFd = tar_fd; | ||
671 | tbInfo.verboseFlag = verboseFlag; | ||
672 | 673 | ||
673 | /* Store the stat info for the tarball's file, so | 674 | /* Store the stat info for the tarball's file, so |
674 | * can avoid including the tarball into itself.... */ | 675 | * can avoid including the tarball into itself.... */ |
675 | xfstat(tbInfo.tarFd, &tbInfo.tarFileStatBuf, "can't stat tar file"); | 676 | xfstat(tbInfo->tarFd, &tbInfo->tarFileStatBuf, "can't stat tar file"); |
676 | 677 | ||
677 | #if SEAMLESS_COMPRESSION | 678 | # if SEAMLESS_COMPRESSION |
678 | if (gzip) | 679 | if (gzip) |
679 | vfork_compressor(tbInfo.tarFd, gzip); | 680 | vfork_compressor(tbInfo->tarFd, gzip); |
680 | #endif | 681 | # endif |
681 | |||
682 | tbInfo.excludeList = exclude; | ||
683 | 682 | ||
684 | /* Read the directory/files and iterate over them one at a time */ | 683 | /* Read the directory/files and iterate over them one at a time */ |
685 | while (include) { | 684 | while (filelist) { |
686 | if (!recursive_action(include->data, recurseFlags, | 685 | if (!recursive_action(filelist->data, recurseFlags, |
687 | writeFileToTarball, writeFileToTarball, &tbInfo, 0) | 686 | writeFileToTarball, writeFileToTarball, tbInfo, 0) |
688 | ) { | 687 | ) { |
689 | errorFlag = TRUE; | 688 | errorFlag = TRUE; |
690 | } | 689 | } |
691 | include = include->link; | 690 | filelist = filelist->link; |
692 | } | 691 | } |
693 | /* Write two empty blocks to the end of the archive */ | 692 | /* Write two empty blocks to the end of the archive */ |
694 | memset(block_buf, 0, 2*TAR_BLOCK_SIZE); | 693 | memset(block_buf, 0, 2*TAR_BLOCK_SIZE); |
695 | xwrite(tbInfo.tarFd, block_buf, 2*TAR_BLOCK_SIZE); | 694 | xwrite(tbInfo->tarFd, block_buf, 2*TAR_BLOCK_SIZE); |
696 | 695 | ||
697 | /* To be pedantically correct, we would check if the tarball | 696 | /* To be pedantically correct, we would check if the tarball |
698 | * is smaller than 20 tar blocks, and pad it if it was smaller, | 697 | * is smaller than 20 tar blocks, and pad it if it was smaller, |
@@ -700,16 +699,16 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | |||
700 | * so is considered a waste of space */ | 699 | * so is considered a waste of space */ |
701 | 700 | ||
702 | /* Close so the child process (if any) will exit */ | 701 | /* Close so the child process (if any) will exit */ |
703 | close(tbInfo.tarFd); | 702 | close(tbInfo->tarFd); |
704 | 703 | ||
705 | /* Hang up the tools, close up shop, head home */ | 704 | /* Hang up the tools, close up shop, head home */ |
706 | if (ENABLE_FEATURE_CLEAN_UP) | 705 | if (ENABLE_FEATURE_CLEAN_UP) |
707 | freeHardLinkInfo(&tbInfo.hlInfoHead); | 706 | freeHardLinkInfo(&tbInfo->hlInfoHead); |
708 | 707 | ||
709 | if (errorFlag) | 708 | if (errorFlag) |
710 | bb_error_msg("error exit delayed from previous errors"); | 709 | bb_error_msg("error exit delayed from previous errors"); |
711 | 710 | ||
712 | #if SEAMLESS_COMPRESSION | 711 | # if SEAMLESS_COMPRESSION |
713 | if (gzip) { | 712 | if (gzip) { |
714 | int status; | 713 | int status; |
715 | if (safe_waitpid(-1, &status, 0) == -1) | 714 | if (safe_waitpid(-1, &status, 0) == -1) |
@@ -718,21 +717,25 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | |||
718 | /* gzip was killed or has exited with nonzero! */ | 717 | /* gzip was killed or has exited with nonzero! */ |
719 | errorFlag = TRUE; | 718 | errorFlag = TRUE; |
720 | } | 719 | } |
721 | #endif | 720 | # endif |
722 | return errorFlag; | 721 | return errorFlag; |
723 | } | 722 | } |
723 | |||
724 | #else /* !FEATURE_TAR_CREATE */ | 724 | #else /* !FEATURE_TAR_CREATE */ |
725 | |||
725 | # define writeTarFile(...) 0 | 726 | # define writeTarFile(...) 0 |
727 | |||
726 | #endif | 728 | #endif |
727 | 729 | ||
728 | #if ENABLE_FEATURE_TAR_FROM | 730 | #if ENABLE_FEATURE_TAR_FROM |
729 | static llist_t *append_file_list_to_list(llist_t *list) | 731 | static llist_t *append_file_list_to_list(llist_t *list) |
730 | { | 732 | { |
731 | FILE *src_stream; | ||
732 | char *line; | ||
733 | llist_t *newlist = NULL; | 733 | llist_t *newlist = NULL; |
734 | 734 | ||
735 | while (list) { | 735 | while (list) { |
736 | FILE *src_stream; | ||
737 | char *line; | ||
738 | |||
736 | src_stream = xfopen_stdin(llist_pop(&list)); | 739 | src_stream = xfopen_stdin(llist_pop(&list)); |
737 | while ((line = xmalloc_fgetline(src_stream)) != NULL) { | 740 | while ((line = xmalloc_fgetline(src_stream)) != NULL) { |
738 | /* kill trailing '/' unless the string is just "/" */ | 741 | /* kill trailing '/' unless the string is just "/" */ |
@@ -758,7 +761,7 @@ static llist_t *append_file_list_to_list(llist_t *list) | |||
758 | //usage: IF_FEATURE_TAR_NOPRESERVE_TIME("m") | 761 | //usage: IF_FEATURE_TAR_NOPRESERVE_TIME("m") |
759 | //usage: "vO] " | 762 | //usage: "vO] " |
760 | //usage: "[-f TARFILE] [-C DIR] " | 763 | //usage: "[-f TARFILE] [-C DIR] " |
761 | //usage: IF_FEATURE_TAR_FROM("[-T FILE] [-X FILE] "IF_FEATURE_TAR_LONG_OPTIONS("[--exclude PATTERN] ")) | 764 | //usage: IF_FEATURE_TAR_FROM("[-T FILE] [-X FILE] "IF_FEATURE_TAR_LONG_OPTIONS("[--exclude PATTERN]... ")) |
762 | //usage: "[FILE]..." | 765 | //usage: "[FILE]..." |
763 | //usage:#define tar_full_usage "\n\n" | 766 | //usage:#define tar_full_usage "\n\n" |
764 | //usage: IF_FEATURE_TAR_CREATE("Create, extract, ") | 767 | //usage: IF_FEATURE_TAR_CREATE("Create, extract, ") |
@@ -1170,13 +1173,10 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1170 | if (base_dir) | 1173 | if (base_dir) |
1171 | xchdir(base_dir); | 1174 | xchdir(base_dir); |
1172 | 1175 | ||
1173 | //if (SEAMLESS_COMPRESSION) | ||
1174 | // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ | ||
1175 | // signal(SIGCHLD, check_errors_in_children); | ||
1176 | |||
1177 | #if ENABLE_FEATURE_TAR_CREATE | 1176 | #if ENABLE_FEATURE_TAR_CREATE |
1178 | /* Create an archive */ | 1177 | /* Create an archive */ |
1179 | if (opt & OPT_CREATE) { | 1178 | if (opt & OPT_CREATE) { |
1179 | struct TarBallInfo *tbInfo; | ||
1180 | # if SEAMLESS_COMPRESSION | 1180 | # if SEAMLESS_COMPRESSION |
1181 | const char *zipMode = NULL; | 1181 | const char *zipMode = NULL; |
1182 | if (opt & OPT_COMPRESS) | 1182 | if (opt & OPT_COMPRESS) |
@@ -1190,12 +1190,18 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1190 | if (opt & OPT_XZ) | 1190 | if (opt & OPT_XZ) |
1191 | zipMode = "xz"; | 1191 | zipMode = "xz"; |
1192 | # endif | 1192 | # endif |
1193 | tbInfo = xzalloc(sizeof(*tbInfo)); | ||
1194 | tbInfo->tarFd = tar_handle->src_fd; | ||
1195 | tbInfo->verboseFlag = verboseFlag; | ||
1196 | # if ENABLE_FEATURE_TAR_FROM | ||
1197 | tbInfo->excludeList = tar_handle->reject; | ||
1198 | # endif | ||
1193 | /* NB: writeTarFile() closes tar_handle->src_fd */ | 1199 | /* NB: writeTarFile() closes tar_handle->src_fd */ |
1194 | return writeTarFile(tar_handle->src_fd, verboseFlag, | 1200 | return writeTarFile(tbInfo, |
1195 | (opt & OPT_DEREFERENCE ? ACTION_FOLLOWLINKS : 0) | 1201 | (opt & OPT_DEREFERENCE ? ACTION_FOLLOWLINKS : 0) |
1196 | | (opt & OPT_NORECURSION ? 0 : ACTION_RECURSE), | 1202 | | (opt & OPT_NORECURSION ? 0 : ACTION_RECURSE), |
1197 | tar_handle->accept, | 1203 | tar_handle->accept, |
1198 | tar_handle->reject, zipMode); | 1204 | zipMode); |
1199 | } | 1205 | } |
1200 | #endif | 1206 | #endif |
1201 | 1207 | ||