blob: d6f5e62717caba6fd4339eeca71529c89488d1e2 [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/*
Denis Vlasenko059c9172007-11-12 02:13:12 +000011 * On MMU machine, the transform_prog is removed by macro magic
12 * in include/unarchive.h. On NOMMU, transformer is removed.
Denis Vlasenko211f7f82007-09-05 11:48:32 +000013 */
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),
Denis Vlasenko059c9172007-11-12 02:13:12 +000016 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) {
32 /* child process */
Denis Vlasenko847fa772008-01-28 22:45:43 +000033 close(fd_pipe[0]); /* We don't want to read from the parent */
Denis Vlasenkoea620772006-10-14 02:23:43 +000034 // FIXME: error check?
Denis Vlasenko211f7f82007-09-05 11:48:32 +000035#if BB_MMU
Denis Vlasenkoea620772006-10-14 02:23:43 +000036 transformer(src_fd, fd_pipe[1]);
Denis Vlasenko7e0fbf92007-09-04 19:33:22 +000037 if (ENABLE_FEATURE_CLEAN_UP) {
38 close(fd_pipe[1]); /* Send EOF */
39 close(src_fd);
40 }
Denis Vlasenkoea620772006-10-14 02:23:43 +000041 exit(0);
Denis Vlasenko211f7f82007-09-05 11:48:32 +000042#else
Denis Vlasenko059c9172007-11-12 02:13:12 +000043 {
44 char *argv[4];
45 xmove_fd(src_fd, 0);
46 xmove_fd(fd_pipe[1], 1);
47 argv[0] = (char*)transform_prog;
48 argv[1] = (char*)"-cf";
49 argv[2] = (char*)"-";
50 argv[3] = NULL;
51 BB_EXECVP(transform_prog, argv);
52 bb_perror_msg_and_die("exec failed");
53 }
Denis Vlasenko211f7f82007-09-05 11:48:32 +000054#endif
Denis Vlasenkoea620772006-10-14 02:23:43 +000055 /* notreached */
Glenn L McGrath5699b852003-11-15 23:19:05 +000056 }
Glenn L McGrath20872be2003-11-18 21:31:19 +000057
Glenn L McGrath5699b852003-11-15 23:19:05 +000058 /* parent process */
Glenn L McGrath20872be2003-11-18 21:31:19 +000059 close(fd_pipe[1]); /* Don't want to write to the child */
Glenn L McGrath5699b852003-11-15 23:19:05 +000060
Denis Vlasenko97a8dd32006-10-01 15:55:11 +000061 return fd_pipe[0];
Glenn L McGrath5699b852003-11-15 23:19:05 +000062}