aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO_config_nommu16
-rw-r--r--archival/libunarchive/open_transformer.c8
-rw-r--r--archival/tar.c190
3 files changed, 115 insertions, 99 deletions
diff --git a/TODO_config_nommu b/TODO_config_nommu
index 7fdec69bd..3cbe7f415 100644
--- a/TODO_config_nommu
+++ b/TODO_config_nommu
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.10.0.svn 3# Busybox version: 1.11.0.svn
4# Thu Mar 20 14:54:21 2008 4# Mon Apr 21 23:20:35 2008
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7 7
@@ -100,6 +100,7 @@ CONFIG_FEATURE_AR_LONG_FILENAMES=y
100CONFIG_BUNZIP2=y 100CONFIG_BUNZIP2=y
101CONFIG_BZIP2=y 101CONFIG_BZIP2=y
102CONFIG_CPIO=y 102CONFIG_CPIO=y
103CONFIG_FEATURE_CPIO_O=y
103CONFIG_DPKG=y 104CONFIG_DPKG=y
104CONFIG_DPKG_DEB=y 105CONFIG_DPKG_DEB=y
105CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY=y 106CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY=y
@@ -485,6 +486,7 @@ CONFIG_LOSETUP=y
485CONFIG_MDEV=y 486CONFIG_MDEV=y
486CONFIG_FEATURE_MDEV_CONF=y 487CONFIG_FEATURE_MDEV_CONF=y
487CONFIG_FEATURE_MDEV_RENAME=y 488CONFIG_FEATURE_MDEV_RENAME=y
489CONFIG_FEATURE_MDEV_RENAME_REGEXP=y
488CONFIG_FEATURE_MDEV_EXEC=y 490CONFIG_FEATURE_MDEV_EXEC=y
489CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y 491CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y
490CONFIG_MKSWAP=y 492CONFIG_MKSWAP=y
@@ -521,6 +523,7 @@ CONFIG_PIVOT_ROOT=y
521CONFIG_RDATE=y 523CONFIG_RDATE=y
522CONFIG_READPROFILE=y 524CONFIG_READPROFILE=y
523CONFIG_RTCWAKE=y 525CONFIG_RTCWAKE=y
526CONFIG_SCRIPT=y
524CONFIG_SETARCH=y 527CONFIG_SETARCH=y
525CONFIG_SWAPONOFF=y 528CONFIG_SWAPONOFF=y
526CONFIG_SWITCH_ROOT=y 529CONFIG_SWITCH_ROOT=y
@@ -559,6 +562,7 @@ CONFIG_DC=y
559# CONFIG_FEATURE_DEVFS is not set 562# CONFIG_FEATURE_DEVFS is not set
560CONFIG_EJECT=y 563CONFIG_EJECT=y
561CONFIG_FEATURE_EJECT_SCSI=y 564CONFIG_FEATURE_EJECT_SCSI=y
565CONFIG_FBSPLASH=y
562CONFIG_LAST=y 566CONFIG_LAST=y
563CONFIG_LESS=y 567CONFIG_LESS=y
564CONFIG_FEATURE_LESS_MAXLINES=9999999 568CONFIG_FEATURE_LESS_MAXLINES=9999999
@@ -577,6 +581,7 @@ CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA=y
577CONFIG_MAKEDEVS=y 581CONFIG_MAKEDEVS=y
578# CONFIG_FEATURE_MAKEDEVS_LEAF is not set 582# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
579CONFIG_FEATURE_MAKEDEVS_TABLE=y 583CONFIG_FEATURE_MAKEDEVS_TABLE=y
584CONFIG_MAN=y
580CONFIG_MICROCOM=y 585CONFIG_MICROCOM=y
581CONFIG_MOUNTPOINT=y 586CONFIG_MOUNTPOINT=y
582CONFIG_MT=y 587CONFIG_MT=y
@@ -584,9 +589,9 @@ CONFIG_RAIDAUTORUN=y
584CONFIG_READAHEAD=y 589CONFIG_READAHEAD=y
585CONFIG_RUNLEVEL=y 590CONFIG_RUNLEVEL=y
586CONFIG_RX=y 591CONFIG_RX=y
587CONFIG_SCRIPT=y
588CONFIG_STRINGS=y
589CONFIG_SETSID=y 592CONFIG_SETSID=y
593CONFIG_STRINGS=y
594CONFIG_SYMLINKS=y
590CONFIG_TASKSET=y 595CONFIG_TASKSET=y
591CONFIG_FEATURE_TASKSET_FANCY=y 596CONFIG_FEATURE_TASKSET_FANCY=y
592CONFIG_TIME=y 597CONFIG_TIME=y
@@ -603,6 +608,7 @@ CONFIG_ARP=y
603CONFIG_ARPING=y 608CONFIG_ARPING=y
604CONFIG_BRCTL=y 609CONFIG_BRCTL=y
605CONFIG_FEATURE_BRCTL_FANCY=y 610CONFIG_FEATURE_BRCTL_FANCY=y
611CONFIG_FEATURE_BRCTL_SHOW=y
606CONFIG_DNSD=y 612CONFIG_DNSD=y
607CONFIG_ETHER_WAKE=y 613CONFIG_ETHER_WAKE=y
608CONFIG_FAKEIDENTD=y 614CONFIG_FAKEIDENTD=y
@@ -751,6 +757,7 @@ CONFIG_WATCH=y
751# CONFIG_FEATURE_SH_IS_MSH is not set 757# CONFIG_FEATURE_SH_IS_MSH is not set
752CONFIG_FEATURE_SH_IS_NONE=y 758CONFIG_FEATURE_SH_IS_NONE=y
753# CONFIG_ASH is not set 759# CONFIG_ASH is not set
760# CONFIG_ASH_BASH_COMPAT is not set
754# CONFIG_ASH_JOB_CONTROL is not set 761# CONFIG_ASH_JOB_CONTROL is not set
755# CONFIG_ASH_READ_NCHARS is not set 762# CONFIG_ASH_READ_NCHARS is not set
756# CONFIG_ASH_READ_TIMEOUT is not set 763# CONFIG_ASH_READ_TIMEOUT is not set
@@ -780,6 +787,7 @@ CONFIG_MSH=y
780# 787#
781CONFIG_FEATURE_SH_EXTRA_QUIET=y 788CONFIG_FEATURE_SH_EXTRA_QUIET=y
782CONFIG_FEATURE_SH_STANDALONE=y 789CONFIG_FEATURE_SH_STANDALONE=y
790CONFIG_FEATURE_SH_NOFORK=y
783CONFIG_CTTYHACK=y 791CONFIG_CTTYHACK=y
784 792
785# 793#
diff --git a/archival/libunarchive/open_transformer.c b/archival/libunarchive/open_transformer.c
index 3c551de06..8fb860234 100644
--- a/archival/libunarchive/open_transformer.c
+++ b/archival/libunarchive/open_transformer.c
@@ -22,11 +22,13 @@ int open_transformer(int src_fd,
22 22
23#if BB_MMU 23#if BB_MMU
24 pid = fork(); 24 pid = fork();
25 if (pid == -1)
26 bb_perror_msg_and_die("can't fork");
25#else 27#else
26 pid = vfork(); 28 pid = vfork();
27#endif
28 if (pid == -1) 29 if (pid == -1)
29 bb_perror_msg_and_die("fork failed"); 30 bb_perror_msg_and_die("can't vfork");
31#endif
30 32
31 if (pid == 0) { 33 if (pid == 0) {
32 /* child process */ 34 /* child process */
@@ -49,7 +51,7 @@ int open_transformer(int src_fd,
49 argv[2] = (char*)"-"; 51 argv[2] = (char*)"-";
50 argv[3] = NULL; 52 argv[3] = NULL;
51 BB_EXECVP(transform_prog, argv); 53 BB_EXECVP(transform_prog, argv);
52 bb_perror_msg_and_die("exec failed"); 54 bb_perror_msg_and_die("can't exec %s", transform_prog);
53 } 55 }
54#endif 56#endif
55 /* notreached */ 57 /* notreached */
diff --git a/archival/tar.c b/archival/tar.c
index 0c90ac07e..0aa216c39 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -84,26 +84,26 @@ struct TarHeader { /* byte offset */
84*/ 84*/
85typedef struct HardLinkInfo HardLinkInfo; 85typedef struct HardLinkInfo HardLinkInfo;
86struct HardLinkInfo { 86struct HardLinkInfo {
87 HardLinkInfo *next; /* Next entry in list */ 87 HardLinkInfo *next; /* Next entry in list */
88 dev_t dev; /* Device number */ 88 dev_t dev; /* Device number */
89 ino_t ino; /* Inode number */ 89 ino_t ino; /* Inode number */
90 short linkCount; /* (Hard) Link Count */ 90 short linkCount; /* (Hard) Link Count */
91 char name[1]; /* Start of filename (must be last) */ 91 char name[1]; /* Start of filename (must be last) */
92}; 92};
93 93
94/* Some info to be carried along when creating a new tarball */ 94/* Some info to be carried along when creating a new tarball */
95typedef struct TarBallInfo TarBallInfo; 95typedef struct TarBallInfo TarBallInfo;
96struct TarBallInfo { 96struct TarBallInfo {
97 int tarFd; /* Open-for-write file descriptor 97 int tarFd; /* Open-for-write file descriptor
98 for the tarball */ 98 * for the tarball */
99 struct stat statBuf; /* Stat info for the tarball, letting 99 struct stat statBuf; /* Stat info for the tarball, letting
100 us know the inode and device that the 100 * us know the inode and device that the
101 tarball lives, so we can avoid trying 101 * tarball lives, so we can avoid trying
102 to include the tarball into itself */ 102 * to include the tarball into itself */
103 int verboseFlag; /* Whether to print extra stuff or not */ 103 int verboseFlag; /* Whether to print extra stuff or not */
104 const llist_t *excludeList; /* List of files to not include */ 104 const llist_t *excludeList; /* List of files to not include */
105 HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */ 105 HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */
106 HardLinkInfo *hlInfo; /* Hard Link Info for the current file */ 106 HardLinkInfo *hlInfo; /* Hard Link Info for the current file */
107}; 107};
108 108
109/* A nice enum with all the possible tar file content types */ 109/* A nice enum with all the possible tar file content types */
@@ -503,100 +503,104 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf,
503 return TRUE; 503 return TRUE;
504} 504}
505 505
506static int writeTarFile(const int tar_fd, const int verboseFlag,
507 const unsigned long dereferenceFlag, const llist_t *include,
508 const llist_t *exclude, const int gzip)
509{
510 pid_t gzipPid = 0;
511 int errorFlag = FALSE;
512 struct TarBallInfo tbInfo;
513
514 tbInfo.hlInfoHead = NULL;
515
516 fchmod(tar_fd, 0644);
517 tbInfo.tarFd = tar_fd;
518 tbInfo.verboseFlag = verboseFlag;
519
520 /* Store the stat info for the tarball's file, so
521 * can avoid including the tarball into itself.... */
522 if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)
523 bb_perror_msg_and_die("cannot stat tar file");
524
525#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2 506#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
526 if (gzip) { 507/* Don't inline: vfork scares gcc and pessimizes code */
508static void NOINLINE vfork_compressor(int tar_fd, int gzip)
509{
510 pid_t gzipPid;
527#if ENABLE_FEATURE_TAR_GZIP && ENABLE_FEATURE_TAR_BZIP2 511#if ENABLE_FEATURE_TAR_GZIP && ENABLE_FEATURE_TAR_BZIP2
528 const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2"; 512 const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2";
529#elif ENABLE_FEATURE_TAR_GZIP 513#elif ENABLE_FEATURE_TAR_GZIP
530 const char *zip_exec = "gzip"; 514 const char *zip_exec = "gzip";
531#else /* only ENABLE_FEATURE_TAR_BZIP2 */ 515#else /* only ENABLE_FEATURE_TAR_BZIP2 */
532 const char *zip_exec = "bzip2"; 516 const char *zip_exec = "bzip2";
533#endif 517#endif
534 // On Linux, vfork never unpauses parent early, although standard 518 // On Linux, vfork never unpauses parent early, although standard
535 // allows for that. Do we want to waste bytes checking for it? 519 // allows for that. Do we want to waste bytes checking for it?
536#define WAIT_FOR_CHILD 0 520#define WAIT_FOR_CHILD 0
537 volatile int vfork_exec_errno = 0; 521 volatile int vfork_exec_errno = 0;
538#if WAIT_FOR_CHILD 522 struct fd_pair gzipDataPipe;
539 struct fd_pair gzipStatusPipe;
540#endif
541 struct fd_pair gzipDataPipe;
542 xpiped_pair(gzipDataPipe);
543#if WAIT_FOR_CHILD 523#if WAIT_FOR_CHILD
544 xpiped_pair(gzipStatusPipe); 524 struct fd_pair gzipStatusPipe;
525 xpiped_pair(gzipStatusPipe);
545#endif 526#endif
527 xpiped_pair(gzipDataPipe);
546 528
547 signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ 529 signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
548 530
549#if defined(__GNUC__) && __GNUC__ 531#if defined(__GNUC__) && __GNUC__
550 /* Avoid vfork clobbering */ 532 /* Avoid vfork clobbering */
551 (void) &include; 533 (void) &zip_exec;
552 (void) &errorFlag;
553 (void) &zip_exec;
554#endif 534#endif
555 535
556 gzipPid = vfork(); 536 gzipPid = vfork();
557 if (gzipPid < 0) 537 if (gzipPid < 0)
558 bb_perror_msg_and_die("vfork gzip"); 538 bb_perror_msg_and_die("can't vfork");
559 539
560 if (gzipPid == 0) { 540 if (gzipPid == 0) {
561 /* child */ 541 /* child */
562 /* NB: close _first_, then move fds! */ 542 /* NB: close _first_, then move fds! */
563 close(gzipDataPipe.wr); 543 close(gzipDataPipe.wr);
564#if WAIT_FOR_CHILD 544#if WAIT_FOR_CHILD
565 close(gzipStatusPipe.rd); 545 close(gzipStatusPipe.rd);
566 /* gzipStatusPipe.wr will close only on exec - 546 /* gzipStatusPipe.wr will close only on exec -
567 * parent waits for this close to happen */ 547 * parent waits for this close to happen */
568 fcntl(gzipStatusPipe.wr, F_SETFD, FD_CLOEXEC); 548 fcntl(gzipStatusPipe.wr, F_SETFD, FD_CLOEXEC);
569#endif 549#endif
570 xmove_fd(gzipDataPipe.rd, 0); 550 xmove_fd(gzipDataPipe.rd, 0);
571 xmove_fd(tbInfo.tarFd, 1); 551 xmove_fd(tar_fd, 1);
572 /* exec gzip/bzip2 program/applet */ 552 /* exec gzip/bzip2 program/applet */
573 BB_EXECLP(zip_exec, zip_exec, "-f", NULL); 553 BB_EXECLP(zip_exec, zip_exec, "-f", NULL);
574 vfork_exec_errno = errno; 554 vfork_exec_errno = errno;
575 _exit(1); 555 _exit(1);
576 } 556 }
577 557
578 /* parent */ 558 /* parent */
579 xmove_fd(gzipDataPipe.wr, tbInfo.tarFd); 559 xmove_fd(gzipDataPipe.wr, tar_fd);
580 close(gzipDataPipe.rd); 560 close(gzipDataPipe.rd);
581#if WAIT_FOR_CHILD 561#if WAIT_FOR_CHILD
582 close(gzipStatusPipe.wr); 562 close(gzipStatusPipe.wr);
583 while (1) { 563 while (1) {
584 char buf; 564 char buf;
585 int n; 565 int n;
586 566
587 /* Wait until child execs (or fails to) */ 567 /* Wait until child execs (or fails to) */
588 n = full_read(gzipStatusPipe.rd, &buf, 1); 568 n = full_read(gzipStatusPipe.rd, &buf, 1);
589 if (n < 0 /* && errno == EAGAIN */) 569 if (n < 0 /* && errno == EAGAIN */)
590 continue; /* try it again */ 570 continue; /* try it again */
591 571 }
592 } 572 close(gzipStatusPipe.rd);
593 close(gzipStatusPipe.rd);
594#endif 573#endif
595 if (vfork_exec_errno) { 574 if (vfork_exec_errno) {
596 errno = vfork_exec_errno; 575 errno = vfork_exec_errno;
597 bb_perror_msg_and_die("cannot exec %s", zip_exec); 576 bb_perror_msg_and_die("cannot exec %s", zip_exec);
598 }
599 } 577 }
578}
579#endif /* ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2 */
580
581
582/* gcc 4.2.1 inlines it, making code bigger */
583static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
584 int dereferenceFlag, const llist_t *include,
585 const llist_t *exclude, int gzip)
586{
587 int errorFlag = FALSE;
588 struct TarBallInfo tbInfo;
589
590 tbInfo.hlInfoHead = NULL;
591
592 fchmod(tar_fd, 0644);
593 tbInfo.tarFd = tar_fd;
594 tbInfo.verboseFlag = verboseFlag;
595
596 /* Store the stat info for the tarball's file, so
597 * can avoid including the tarball into itself.... */
598 if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)
599 bb_perror_msg_and_die("cannot stat tar file");
600
601#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
602 if (gzip)
603 vfork_compressor(tbInfo.tarFd, gzip);
600#endif 604#endif
601 605
602 tbInfo.excludeList = exclude; 606 tbInfo.excludeList = exclude;
@@ -630,20 +634,22 @@ static int writeTarFile(const int tar_fd, const int verboseFlag,
630 if (errorFlag) 634 if (errorFlag)
631 bb_error_msg("error exit delayed from previous errors"); 635 bb_error_msg("error exit delayed from previous errors");
632 636
633 if (gzipPid) { 637#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
638 if (gzip) {
634 int status; 639 int status;
635 if (safe_waitpid(gzipPid, &status, 0) == -1) 640 if (safe_waitpid(-1, &status, 0) == -1)
636 bb_perror_msg("waitpid"); 641 bb_perror_msg("waitpid");
637 else if (!WIFEXITED(status) || WEXITSTATUS(status)) 642 else if (!WIFEXITED(status) || WEXITSTATUS(status))
638 /* gzip was killed or has exited with nonzero! */ 643 /* gzip was killed or has exited with nonzero! */
639 errorFlag = TRUE; 644 errorFlag = TRUE;
640 } 645 }
646#endif
641 return errorFlag; 647 return errorFlag;
642} 648}
643#else 649#else
644int writeTarFile(const int tar_fd, const int verboseFlag, 650int writeTarFile(int tar_fd, int verboseFlag,
645 const unsigned long dereferenceFlag, const llist_t *include, 651 int dereferenceFlag, const llist_t *include,
646 const llist_t *exclude, const int gzip); 652 const llist_t *exclude, int gzip);
647#endif /* FEATURE_TAR_CREATE */ 653#endif /* FEATURE_TAR_CREATE */
648 654
649#if ENABLE_FEATURE_TAR_FROM 655#if ENABLE_FEATURE_TAR_FROM