aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-12-17 12:51:58 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-12-17 12:51:58 +0100
commitb0e7cb4c3f1bd9872444711ebc44258430156cad (patch)
treec129fc2f71354fcfc9ac2f77f018ddf1a73b36e1
parentb6237c0657074e8a61b2123601df36389659b603 (diff)
downloadbusybox-w32-b0e7cb4c3f1bd9872444711ebc44258430156cad.tar.gz
busybox-w32-b0e7cb4c3f1bd9872444711ebc44258430156cad.tar.bz2
busybox-w32-b0e7cb4c3f1bd9872444711ebc44258430156cad.zip
mail: deobfuscate launch_helper()
13 bytes are not worth the risk of doing something iffy after vfork(). Let's have much clearer code there. function old new delta launch_helper 175 188 +13 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--mailutils/mail.c56
1 files changed, 27 insertions, 29 deletions
diff --git a/mailutils/mail.c b/mailutils/mail.c
index 9735d48f6..7e9efdbfa 100644
--- a/mailutils/mail.c
+++ b/mailutils/mail.c
@@ -10,35 +10,35 @@
10#include "libbb.h" 10#include "libbb.h"
11#include "mail.h" 11#include "mail.h"
12 12
13// generic signal handler 13// common signal handler
14static void signal_handler(int signo) 14static void signal_handler(int signo)
15{ 15{
16#define err signo
17 if (SIGALRM == signo) { 16 if (SIGALRM == signo) {
18 bb_simple_error_msg_and_die("timed out"); 17 bb_simple_error_msg_and_die("timed out");
19 } 18 }
20 19
21 // SIGCHLD. reap zombies 20 // SIGCHLD. reap the zombie if we expect one
22 if (safe_waitpid(G.helper_pid, &err, WNOHANG) > 0) { 21 if (G.helper_pid == 0)
23 if (WIFSIGNALED(err)) 22 return;
24 bb_error_msg_and_die("helper killed by signal %u", WTERMSIG(err)); 23#define status signo
25 if (WIFEXITED(err)) { 24 if (safe_waitpid(G.helper_pid, &status, WNOHANG) > 0) {
26 G.helper_pid = 0; 25 G.helper_pid = 0;
27 if (WEXITSTATUS(err)) 26 if (WIFSIGNALED(status))
28 bb_error_msg_and_die("helper exited (%u)", WEXITSTATUS(err)); 27 bb_error_msg_and_die("helper killed by signal %u", WTERMSIG(status));
29 } 28 if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
29 bb_error_msg_and_die("helper exited (%u)", WEXITSTATUS(status));
30 } 30 }
31#undef err 31#undef status
32} 32}
33 33
34void FAST_FUNC launch_helper(const char **argv) 34void FAST_FUNC launch_helper(const char **argv)
35{ 35{
36 // setup vanilla unidirectional pipes interchange 36 pid_t pid;
37 int i; 37 struct fd_pair child_out;
38 int pipes[4]; 38 struct fd_pair child_in;
39 39
40 xpipe(pipes); 40 xpiped_pair(child_out);
41 xpipe(pipes + 2); 41 xpiped_pair(child_in);
42 42
43 // NB: handler must be installed before vfork 43 // NB: handler must be installed before vfork
44 bb_signals(0 44 bb_signals(0
@@ -46,25 +46,23 @@ void FAST_FUNC launch_helper(const char **argv)
46 + (1 << SIGALRM) 46 + (1 << SIGALRM)
47 , signal_handler); 47 , signal_handler);
48 48
49 G.helper_pid = xvfork(); 49 G.helper_pid = pid = xvfork();
50 50 if (pid == 0) {
51 i = (!G.helper_pid) * 2; // for parent:0, for child:2
52 close(pipes[i + 1]); // 1 or 3 - closing one write end
53 close(pipes[2 - i]); // 2 or 0 - closing one read end
54 xmove_fd(pipes[i], STDIN_FILENO); // 0 or 2 - using other read end
55 xmove_fd(pipes[3 - i], STDOUT_FILENO); // 3 or 1 - using other write end
56 // End result:
57 // parent stdout [3] -> child stdin [2]
58 // child stdout [1] -> parent stdin [0]
59
60 if (!G.helper_pid) {
61 // child 51 // child
52 close(child_in.wr);
53 close(child_out.rd);
54 xmove_fd(child_in.rd, STDIN_FILENO);
55 xmove_fd(child_out.wr, STDOUT_FILENO);
62 // if parent dies, get SIGTERM 56 // if parent dies, get SIGTERM
63 prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); 57 prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0);
64 // try to execute connection helper 58 // try to execute connection helper
65 // NB: SIGCHLD & SIGALRM revert to SIG_DFL on exec 59 // NB: SIGCHLD & SIGALRM revert to SIG_DFL on exec
66 BB_EXECVP_or_die((char**)argv); 60 BB_EXECVP_or_die((char**)argv);
67 } 61 }
62 close(child_out.wr);
63 close(child_in.rd);
64 xmove_fd(child_out.rd, STDIN_FILENO);
65 xmove_fd(child_in.wr, STDOUT_FILENO);
68 66
69 // parent goes on 67 // parent goes on
70} 68}