--- trunk/mkinitrd-magellan/busybox/archival/libunarchive/open_transformer.c 2009/04/24 18:32:46 815 +++ trunk/mkinitrd-magellan/busybox/archival/libunarchive/open_transformer.c 2009/04/24 18:33:46 816 @@ -3,42 +3,62 @@ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ -#include -#include - #include "libbb.h" - #include "unarchive.h" /* transformer(), more than meets the eye */ -int open_transformer(int src_fd, - USE_DESKTOP(long long) int (*transformer)(int src_fd, int dst_fd)) +/* + * On MMU machine, the transform_prog is removed by macro magic + * in include/unarchive.h. On NOMMU, transformer is removed. + */ +void FAST_FUNC open_transformer(int fd, + USE_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), + const char *transform_prog) { - int fd_pipe[2]; + struct fd_pair fd_pipe; int pid; - if (pipe(fd_pipe) != 0) { - bb_perror_msg_and_die("can't create pipe"); - } + xpiped_pair(fd_pipe); +#if BB_MMU pid = fork(); - if (pid == -1) { - bb_perror_msg_and_die("fork failed"); - } + if (pid == -1) + bb_perror_msg_and_die("vfork" + 1); +#else + pid = vfork(); + if (pid == -1) + bb_perror_msg_and_die("vfork"); +#endif if (pid == 0) { /* child process */ - close(fd_pipe[0]); /* We don't wan't to read from the parent */ + close(fd_pipe.rd); /* we don't want to read from the parent */ // FIXME: error check? - transformer(src_fd, fd_pipe[1]); - close(fd_pipe[1]); /* Send EOF */ - close(src_fd); - exit(0); +#if BB_MMU + transformer(fd, fd_pipe.wr); + if (ENABLE_FEATURE_CLEAN_UP) { + close(fd_pipe.wr); /* send EOF */ + close(fd); + } + /* must be _exit! bug was actually seen here */ + _exit(EXIT_SUCCESS); +#else + { + char *argv[4]; + xmove_fd(fd, 0); + xmove_fd(fd_pipe.wr, 1); + argv[0] = (char*)transform_prog; + argv[1] = (char*)"-cf"; + argv[2] = (char*)"-"; + argv[3] = NULL; + BB_EXECVP(transform_prog, argv); + bb_perror_msg_and_die("can't exec %s", transform_prog); + } +#endif /* notreached */ } /* parent process */ - close(fd_pipe[1]); /* Don't want to write to the child */ - - return fd_pipe[0]; + close(fd_pipe.wr); /* don't want to write to the child */ + xmove_fd(fd_pipe.rd, fd); }