3 |
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
4 |
*/ |
*/ |
5 |
|
|
|
#include <stdlib.h> |
|
|
#include <unistd.h> |
|
|
|
|
6 |
#include "libbb.h" |
#include "libbb.h" |
|
|
|
7 |
#include "unarchive.h" |
#include "unarchive.h" |
8 |
|
|
9 |
/* transformer(), more than meets the eye */ |
/* transformer(), more than meets the eye */ |
10 |
int open_transformer(int src_fd, |
/* |
11 |
USE_DESKTOP(long long) int (*transformer)(int src_fd, int dst_fd)) |
* On MMU machine, the transform_prog is removed by macro magic |
12 |
|
* in include/unarchive.h. On NOMMU, transformer is removed. |
13 |
|
*/ |
14 |
|
void FAST_FUNC open_transformer(int fd, |
15 |
|
USE_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), |
16 |
|
const char *transform_prog) |
17 |
{ |
{ |
18 |
int fd_pipe[2]; |
struct fd_pair fd_pipe; |
19 |
int pid; |
int pid; |
20 |
|
|
21 |
if (pipe(fd_pipe) != 0) { |
xpiped_pair(fd_pipe); |
|
bb_perror_msg_and_die("can't create pipe"); |
|
|
} |
|
22 |
|
|
23 |
|
#if BB_MMU |
24 |
pid = fork(); |
pid = fork(); |
25 |
if (pid == -1) { |
if (pid == -1) |
26 |
bb_perror_msg_and_die("fork failed"); |
bb_perror_msg_and_die("vfork" + 1); |
27 |
} |
#else |
28 |
|
pid = vfork(); |
29 |
|
if (pid == -1) |
30 |
|
bb_perror_msg_and_die("vfork"); |
31 |
|
#endif |
32 |
|
|
33 |
if (pid == 0) { |
if (pid == 0) { |
34 |
/* child process */ |
/* child process */ |
35 |
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 */ |
36 |
// FIXME: error check? |
// FIXME: error check? |
37 |
transformer(src_fd, fd_pipe[1]); |
#if BB_MMU |
38 |
close(fd_pipe[1]); /* Send EOF */ |
transformer(fd, fd_pipe.wr); |
39 |
close(src_fd); |
if (ENABLE_FEATURE_CLEAN_UP) { |
40 |
exit(0); |
close(fd_pipe.wr); /* send EOF */ |
41 |
|
close(fd); |
42 |
|
} |
43 |
|
/* must be _exit! bug was actually seen here */ |
44 |
|
_exit(EXIT_SUCCESS); |
45 |
|
#else |
46 |
|
{ |
47 |
|
char *argv[4]; |
48 |
|
xmove_fd(fd, 0); |
49 |
|
xmove_fd(fd_pipe.wr, 1); |
50 |
|
argv[0] = (char*)transform_prog; |
51 |
|
argv[1] = (char*)"-cf"; |
52 |
|
argv[2] = (char*)"-"; |
53 |
|
argv[3] = NULL; |
54 |
|
BB_EXECVP(transform_prog, argv); |
55 |
|
bb_perror_msg_and_die("can't exec %s", transform_prog); |
56 |
|
} |
57 |
|
#endif |
58 |
/* notreached */ |
/* notreached */ |
59 |
} |
} |
60 |
|
|
61 |
/* parent process */ |
/* parent process */ |
62 |
close(fd_pipe[1]); /* Don't want to write to the child */ |
close(fd_pipe.wr); /* don't want to write to the child */ |
63 |
|
xmove_fd(fd_pipe.rd, fd); |
|
return fd_pipe[0]; |
|
64 |
} |
} |