blob: f8f587e8d3992b5c67b18846ea0c7d038c0c7b72 [file] [log] [blame]
"Robert P. J. Day"63fc1a92006-07-02 19:47:05 +00001/* vi: set sw=4 ts=4: */
Glenn L McGrath5699b852003-11-15 23:19:05 +00002/*
Bernhard Reutner-Fischercfb53df2006-04-02 21:50:01 +00003 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Glenn L McGrath5699b852003-11-15 23:19:05 +00004 */
5
Glenn L McGrath5699b852003-11-15 23:19:05 +00006#include "libbb.h"
Bernhard Reutner-Fischercfb53df2006-04-02 21:50:01 +00007#include "unarchive.h"
8
Glenn L McGrath5699b852003-11-15 23:19:05 +00009/* transformer(), more than meets the eye */
Denis Vlasenko211f7f82007-09-05 11:48:32 +000010/*
11 * On MMU machine, the transform_prog and ... are stripped
12 * by a macro in include/unarchive.h. On NOMMU, transformer is stripped.
13 */
Denis Vlasenko97a8dd32006-10-01 15:55:11 +000014int open_transformer(int src_fd,
Denis Vlasenko211f7f82007-09-05 11:48:32 +000015 USE_DESKTOP(long long) int (*transformer)(int src_fd, int dst_fd),
16 const char *transform_prog, ...)
Glenn L McGrath5699b852003-11-15 23:19:05 +000017{
18 int fd_pipe[2];
19 int pid;
20
Denis Vlasenko5a6aedd2007-05-26 16:44:20 +000021 xpipe(fd_pipe);
Glenn L McGrath5699b852003-11-15 23:19:05 +000022
Denis Vlasenko211f7f82007-09-05 11:48:32 +000023#if BB_MMU
Glenn L McGrath5699b852003-11-15 23:19:05 +000024 pid = fork();
Denis Vlasenko211f7f82007-09-05 11:48:32 +000025#else
26 pid = vfork();
27#endif
28 if (pid == -1)
Denis Vlasenkoea620772006-10-14 02:23:43 +000029 bb_perror_msg_and_die("fork failed");
Glenn L McGrath5699b852003-11-15 23:19:05 +000030
31 if (pid == 0) {
Denis Vlasenko211f7f82007-09-05 11:48:32 +000032#if !BB_MMU
33 va_list ap;
34#endif
Glenn L McGrath5699b852003-11-15 23:19:05 +000035 /* child process */
Denis Vlasenkoea620772006-10-14 02:23:43 +000036 close(fd_pipe[0]); /* We don't wan't to read from the parent */
37 // FIXME: error check?
Denis Vlasenko211f7f82007-09-05 11:48:32 +000038#if BB_MMU
Denis Vlasenkoea620772006-10-14 02:23:43 +000039 transformer(src_fd, fd_pipe[1]);
Denis Vlasenko7e0fbf92007-09-04 19:33:22 +000040 if (ENABLE_FEATURE_CLEAN_UP) {
41 close(fd_pipe[1]); /* Send EOF */
42 close(src_fd);
43 }
Denis Vlasenkoea620772006-10-14 02:23:43 +000044 exit(0);
Denis Vlasenko211f7f82007-09-05 11:48:32 +000045#else
46 xmove_fd(src_fd, 0);
47 xmove_fd(fd_pipe[1], 1);
48 va_start(ap, transform_prog);
49 BB_EXECVP(transform_prog, ap);
50 bb_perror_and_die("exec failed");
51#endif
Denis Vlasenkoea620772006-10-14 02:23:43 +000052 /* notreached */
Glenn L McGrath5699b852003-11-15 23:19:05 +000053 }
Glenn L McGrath20872be2003-11-18 21:31:19 +000054
Glenn L McGrath5699b852003-11-15 23:19:05 +000055 /* parent process */
Glenn L McGrath20872be2003-11-18 21:31:19 +000056 close(fd_pipe[1]); /* Don't want to write to the child */
Glenn L McGrath5699b852003-11-15 23:19:05 +000057
Denis Vlasenko97a8dd32006-10-01 15:55:11 +000058 return fd_pipe[0];
Glenn L McGrath5699b852003-11-15 23:19:05 +000059}