tar: move vfork into separate function (smaller code)
open_transformer: more informative error messages

function                                             old     new   delta
vfork_compressor                                       -     210    +210
writeTarFile                                         547     299    -248
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/1 up/down: 210/-248)          Total: -38 bytes

diff --git a/archival/tar.c b/archival/tar.c
index 0c90ac0..0aa216c 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -84,26 +84,26 @@
 */
 typedef struct HardLinkInfo HardLinkInfo;
 struct HardLinkInfo {
-	HardLinkInfo *next;	/* Next entry in list */
-	dev_t dev;			/* Device number */
-	ino_t ino;			/* Inode number */
-	short linkCount;	/* (Hard) Link Count */
-	char name[1];		/* Start of filename (must be last) */
+	HardLinkInfo *next;     /* Next entry in list */
+	dev_t dev;              /* Device number */
+	ino_t ino;              /* Inode number */
+	short linkCount;        /* (Hard) Link Count */
+	char name[1];           /* Start of filename (must be last) */
 };
 
 /* Some info to be carried along when creating a new tarball */
 typedef struct TarBallInfo TarBallInfo;
 struct TarBallInfo {
-	int tarFd;				/* Open-for-write file descriptor
-							   for the tarball */
-	struct stat statBuf;	/* Stat info for the tarball, letting
-							   us know the inode and device that the
-							   tarball lives, so we can avoid trying
-							   to include the tarball into itself */
-	int verboseFlag;		/* Whether to print extra stuff or not */
-	const llist_t *excludeList;	/* List of files to not include */
-	HardLinkInfo *hlInfoHead;	/* Hard Link Tracking Information */
-	HardLinkInfo *hlInfo;	/* Hard Link Info for the current file */
+	int tarFd;                      /* Open-for-write file descriptor
+	                                 * for the tarball */
+	struct stat statBuf;            /* Stat info for the tarball, letting
+	                                 * us know the inode and device that the
+	                                 * tarball lives, so we can avoid trying
+	                                 * to include the tarball into itself */
+	int verboseFlag;                /* Whether to print extra stuff or not */
+	const llist_t *excludeList;     /* List of files to not include */
+	HardLinkInfo *hlInfoHead;       /* Hard Link Tracking Information */
+	HardLinkInfo *hlInfo;           /* Hard Link Info for the current file */
 };
 
 /* A nice enum with all the possible tar file content types */
@@ -503,11 +503,87 @@
 	return TRUE;
 }
 
-static int writeTarFile(const int tar_fd, const int verboseFlag,
-	const unsigned long dereferenceFlag, const llist_t *include,
-	const llist_t *exclude, const int gzip)
+#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
+/* Don't inline: vfork scares gcc and pessimizes code */
+static void NOINLINE vfork_compressor(int tar_fd, int gzip)
 {
-	pid_t gzipPid = 0;
+	pid_t gzipPid;
+#if ENABLE_FEATURE_TAR_GZIP && ENABLE_FEATURE_TAR_BZIP2
+	const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2";
+#elif ENABLE_FEATURE_TAR_GZIP
+	const char *zip_exec = "gzip";
+#else /* only ENABLE_FEATURE_TAR_BZIP2 */
+	const char *zip_exec = "bzip2";
+#endif
+	// 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;
+#if WAIT_FOR_CHILD
+	struct fd_pair gzipStatusPipe;
+	xpiped_pair(gzipStatusPipe);
+#endif
+	xpiped_pair(gzipDataPipe);
+
+	signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
+
+#if defined(__GNUC__) && __GNUC__
+	/* Avoid vfork clobbering */
+	(void) &zip_exec;
+#endif
+
+	gzipPid = vfork();
+	if (gzipPid < 0)
+		bb_perror_msg_and_die("can't vfork");
+
+	if (gzipPid == 0) {
+		/* child */
+		/* NB: close _first_, then move fds! */
+		close(gzipDataPipe.wr);
+#if WAIT_FOR_CHILD
+		close(gzipStatusPipe.rd);
+		/* gzipStatusPipe.wr will close only on exec -
+		 * parent waits for this close to happen */
+		fcntl(gzipStatusPipe.wr, F_SETFD, FD_CLOEXEC);
+#endif
+		xmove_fd(gzipDataPipe.rd, 0);
+		xmove_fd(tar_fd, 1);
+		/* exec gzip/bzip2 program/applet */
+		BB_EXECLP(zip_exec, zip_exec, "-f", NULL);
+		vfork_exec_errno = errno;
+		_exit(1);
+	}
+
+	/* parent */
+	xmove_fd(gzipDataPipe.wr, tar_fd);
+	close(gzipDataPipe.rd);
+#if WAIT_FOR_CHILD
+	close(gzipStatusPipe.wr);
+	while (1) {
+		char buf;
+		int n;
+
+		/* Wait until child execs (or fails to) */
+		n = full_read(gzipStatusPipe.rd, &buf, 1);
+		if (n < 0 /* && errno == EAGAIN */)
+			continue;	/* try it again */
+	}
+	close(gzipStatusPipe.rd);
+#endif
+	if (vfork_exec_errno) {
+		errno = vfork_exec_errno;
+		bb_perror_msg_and_die("cannot exec %s", zip_exec);
+	}
+}
+#endif /* ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2 */
+
+
+/* gcc 4.2.1 inlines it, making code bigger */
+static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
+	int dereferenceFlag, const llist_t *include,
+	const llist_t *exclude, int gzip)
+{
 	int errorFlag = FALSE;
 	struct TarBallInfo tbInfo;
 
@@ -523,80 +599,8 @@
 		bb_perror_msg_and_die("cannot stat tar file");
 
 #if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
-	if (gzip) {
-#if ENABLE_FEATURE_TAR_GZIP && ENABLE_FEATURE_TAR_BZIP2
-		const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2";
-#elif ENABLE_FEATURE_TAR_GZIP
-		const char *zip_exec = "gzip";
-#else /* only ENABLE_FEATURE_TAR_BZIP2 */
-		const char *zip_exec = "bzip2";
-#endif
-	// 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;
-#if WAIT_FOR_CHILD
-		struct fd_pair gzipStatusPipe;
-#endif
-		struct fd_pair gzipDataPipe;
-		xpiped_pair(gzipDataPipe);
-#if WAIT_FOR_CHILD
-		xpiped_pair(gzipStatusPipe);
-#endif
-
-		signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
-
-#if defined(__GNUC__) && __GNUC__
-		/* Avoid vfork clobbering */
-		(void) &include;
-		(void) &errorFlag;
-		(void) &zip_exec;
-#endif
-
-		gzipPid = vfork();
-		if (gzipPid < 0)
-			bb_perror_msg_and_die("vfork gzip");
-
-		if (gzipPid == 0) {
-			/* child */
-			/* NB: close _first_, then move fds! */
-			close(gzipDataPipe.wr);
-#if WAIT_FOR_CHILD
-			close(gzipStatusPipe.rd);
-			/* gzipStatusPipe.wr will close only on exec -
-			 * parent waits for this close to happen */
-			fcntl(gzipStatusPipe.wr, F_SETFD, FD_CLOEXEC);
-#endif
-			xmove_fd(gzipDataPipe.rd, 0);
-			xmove_fd(tbInfo.tarFd, 1);
-			/* exec gzip/bzip2 program/applet */
-			BB_EXECLP(zip_exec, zip_exec, "-f", NULL);
-			vfork_exec_errno = errno;
-			_exit(1);
-		}
-
-		/* parent */
-		xmove_fd(gzipDataPipe.wr, tbInfo.tarFd);
-		close(gzipDataPipe.rd);
-#if WAIT_FOR_CHILD
-		close(gzipStatusPipe.wr);
-		while (1) {
-			char buf;
-			int n;
-
-			/* Wait until child execs (or fails to) */
-			n = full_read(gzipStatusPipe.rd, &buf, 1);
-			if (n < 0 /* && errno == EAGAIN */)
-				continue;	/* try it again */
-
-		}
-		close(gzipStatusPipe.rd);
-#endif
-		if (vfork_exec_errno) {
-			errno = vfork_exec_errno;
-			bb_perror_msg_and_die("cannot exec %s", zip_exec);
-		}
-	}
+	if (gzip)
+		vfork_compressor(tbInfo.tarFd, gzip);
 #endif
 
 	tbInfo.excludeList = exclude;
@@ -630,20 +634,22 @@
 	if (errorFlag)
 		bb_error_msg("error exit delayed from previous errors");
 
-	if (gzipPid) {
+#if ENABLE_FEATURE_TAR_GZIP || ENABLE_FEATURE_TAR_BZIP2
+	if (gzip) {
 		int status;
-		if (safe_waitpid(gzipPid, &status, 0) == -1)
+		if (safe_waitpid(-1, &status, 0) == -1)
 			bb_perror_msg("waitpid");
 		else if (!WIFEXITED(status) || WEXITSTATUS(status))
 			/* gzip was killed or has exited with nonzero! */
 			errorFlag = TRUE;
 	}
+#endif
 	return errorFlag;
 }
 #else
-int writeTarFile(const int tar_fd, const int verboseFlag,
-	const unsigned long dereferenceFlag, const llist_t *include,
-	const llist_t *exclude, const int gzip);
+int writeTarFile(int tar_fd, int verboseFlag,
+	int dereferenceFlag, const llist_t *include,
+	const llist_t *exclude, int gzip);
 #endif /* FEATURE_TAR_CREATE */
 
 #if ENABLE_FEATURE_TAR_FROM