aboutsummaryrefslogtreecommitdiff
path: root/archival/tar.c
diff options
context:
space:
mode:
Diffstat (limited to 'archival/tar.c')
-rw-r--r--archival/tar.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/archival/tar.c b/archival/tar.c
index d6ca6c1e0..23ea02b5d 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -119,6 +119,9 @@
119#include "libbb.h" 119#include "libbb.h"
120#include "common_bufsiz.h" 120#include "common_bufsiz.h"
121#include "bb_archive.h" 121#include "bb_archive.h"
122#if ENABLE_PLATFORM_MINGW32
123# include "BB_VER.h"
124#endif
122/* FIXME: Stop using this non-standard feature */ 125/* FIXME: Stop using this non-standard feature */
123#ifndef FNM_LEADING_DIR 126#ifndef FNM_LEADING_DIR
124# define FNM_LEADING_DIR 0 127# define FNM_LEADING_DIR 0
@@ -161,11 +164,13 @@ typedef struct TarBallInfo {
161# endif 164# endif
162 HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */ 165 HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */
163 HardLinkInfo *hlInfo; /* Hard Link Info for the current file */ 166 HardLinkInfo *hlInfo; /* Hard Link Info for the current file */
167#if ENABLE_PLATFORM_POSIX || ENABLE_FEATURE_EXTRA_FILE_DATA
164//TODO: save only st_dev + st_ino 168//TODO: save only st_dev + st_ino
165 struct stat tarFileStatBuf; /* Stat info for the tarball, letting 169 struct stat tarFileStatBuf; /* Stat info for the tarball, letting
166 * us know the inode and device that the 170 * us know the inode and device that the
167 * tarball lives, so we can avoid trying 171 * tarball lives, so we can avoid trying
168 * to include the tarball into itself */ 172 * to include the tarball into itself */
173#endif
169} TarBallInfo; 174} TarBallInfo;
170 175
171/* A nice enum with all the possible tar file content types */ 176/* A nice enum with all the possible tar file content types */
@@ -506,15 +511,21 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
506 } 511 }
507 } 512 }
508 513
514#if ENABLE_PLATFORM_POSIX || ENABLE_FEATURE_EXTRA_FILE_DATA
509 /* It is a bad idea to store the archive we are in the process of creating, 515 /* It is a bad idea to store the archive we are in the process of creating,
510 * so check the device and inode to be sure that this particular file isn't 516 * so check the device and inode to be sure that this particular file isn't
511 * the new tarball */ 517 * the new tarball */
512 if (tbInfo->tarFileStatBuf.st_dev == statbuf->st_dev 518 if (tbInfo->tarFileStatBuf.st_dev == statbuf->st_dev
513 && tbInfo->tarFileStatBuf.st_ino == statbuf->st_ino 519 && tbInfo->tarFileStatBuf.st_ino == statbuf->st_ino
520# if ENABLE_FEATURE_EXTRA_FILE_DATA
521 /* ignore invalid inode numbers */
522 && statbuf->st_ino != 0
523# endif
514 ) { 524 ) {
515 bb_error_msg("%s: file is the archive; skipping", fileName); 525 bb_error_msg("%s: file is the archive; skipping", fileName);
516 return TRUE; 526 return TRUE;
517 } 527 }
528#endif
518 529
519# if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS 530# if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS
520 if (strlen(header_name) >= NAME_SIZE) { 531 if (strlen(header_name) >= NAME_SIZE) {
@@ -568,7 +579,7 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
568 return TRUE; 579 return TRUE;
569} 580}
570 581
571# if SEAMLESS_COMPRESSION 582# if SEAMLESS_COMPRESSION && !ENABLE_PLATFORM_MINGW32
572/* Don't inline: vfork scares gcc and pessimizes code */ 583/* Don't inline: vfork scares gcc and pessimizes code */
573static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) 584static void NOINLINE vfork_compressor(int tar_fd, const char *gzip)
574{ 585{
@@ -645,6 +656,10 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip)
645} 656}
646# endif /* SEAMLESS_COMPRESSION */ 657# endif /* SEAMLESS_COMPRESSION */
647 658
659# if ENABLE_PLATFORM_MINGW32
660# define vfork_compressor(f, g) mingw_fork_compressor((f), (g), "w")
661# endif
662
648 663
649# if !SEAMLESS_COMPRESSION 664# if !SEAMLESS_COMPRESSION
650/* Do not pass gzip flag to writeTarFile() */ 665/* Do not pass gzip flag to writeTarFile() */
@@ -659,16 +674,21 @@ static NOINLINE int writeTarFile(
659 const char *gzip) 674 const char *gzip)
660{ 675{
661 int errorFlag = FALSE; 676 int errorFlag = FALSE;
677# if SEAMLESS_COMPRESSION && ENABLE_PLATFORM_MINGW32
678 pid_t pid = 0;
679# endif
662 680
663 /*tbInfo->hlInfoHead = NULL; - already is */ 681 /*tbInfo->hlInfoHead = NULL; - already is */
664 682
683# if ENABLE_PLATFORM_POSIX || ENABLE_FEATURE_EXTRA_FILE_DATA
665 /* Store the stat info for the tarball's file, so 684 /* Store the stat info for the tarball's file, so
666 * can avoid including the tarball into itself.... */ 685 * can avoid including the tarball into itself.... */
667 xfstat(tbInfo->tarFd, &tbInfo->tarFileStatBuf, "can't stat tar file"); 686 xfstat(tbInfo->tarFd, &tbInfo->tarFileStatBuf, "can't stat tar file");
687# endif
668 688
669# if SEAMLESS_COMPRESSION 689# if SEAMLESS_COMPRESSION
670 if (gzip) 690 if (gzip)
671 vfork_compressor(tbInfo->tarFd, gzip); 691 IF_PLATFORM_MINGW32(pid = )vfork_compressor(tbInfo->tarFd, gzip);
672# endif 692# endif
673 693
674 /* Read the directory/files and iterate over them one at a time */ 694 /* Read the directory/files and iterate over them one at a time */
@@ -702,7 +722,11 @@ static NOINLINE int writeTarFile(
702# if SEAMLESS_COMPRESSION 722# if SEAMLESS_COMPRESSION
703 if (gzip) { 723 if (gzip) {
704 int status; 724 int status;
725# if !ENABLE_PLATFORM_MINGW32
705 if (safe_waitpid(-1, &status, 0) == -1) 726 if (safe_waitpid(-1, &status, 0) == -1)
727# else
728 if (safe_waitpid(pid, &status, 0) == -1)
729# endif
706 bb_simple_perror_msg("waitpid"); 730 bb_simple_perror_msg("waitpid");
707 else if (!WIFEXITED(status) || WEXITSTATUS(status)) 731 else if (!WIFEXITED(status) || WEXITSTATUS(status))
708 /* gzip was killed or has exited with nonzero! */ 732 /* gzip was killed or has exited with nonzero! */