prepare_data(len, buf, s, sl+1);
}
-static void prepare_message(size_t *len, char **buf) {
+static void prepare_string_list(size_t *len, char **buf,
+ const char *const *list) {
const char *s;
+ const char *const *p;
+
+ size_t count = 0;
+ for (p = list; (s = *p++); ) count++;
+ char *count_s = m_asprintf("%zd", count);
- const char *const *p = (void*)environ;
- while ((s = *p++)) {
- if (strchr(s, '='))
- prepare_string(len, buf, s);
- }
-
- prepare_string(len, buf, "");
+ prepare_string(len, buf, count_s);
+ for (p = list; (s = *p++); ) prepare_string(len, buf, s);
+}
- p = executor_argv;
- while ((s = *p++))
- prepare_string(len, buf, s);
+static void prepare_message(size_t *len, char **buf) {
+ prepare_string_list(len, buf, (const char* const*)environ);
+ prepare_string_list(len, buf, executor_argv);
}
static void send_fd(int payload_fd) {
send_fd(1);
send_fd(2);
- size_t len = 4;
+ size_t len = 0;
prepare_message(&len, 0);
- char *m = malloc(len);
- if (!m) diee("failed to allocate for message");
+
+ char *m = xmalloc(len + 4);
char *p = m;
- prepare_length(0, &p, len - 4);
+ prepare_length(0, &p, len);
prepare_message(0, &p);
- assert(p == m + len);
+ assert(p == m + len + 4);
ssize_t sr = fwrite(p, len, 1, call_sock);
if (sr != 1) diee("write request");
# Returns in the executor process
sub become_monitor () {
+ close LISTEN;
+ eval { protocol_exchange(); 1; }
+ or fail_log("protocol exchange failed: $@");
+
my $child = fork // fail_log("fork executor: $!");
if (!$child) {
#---- executor ----
open ::STDOUT, ">& $call_fds[1]" or fail_log("dup for fd1");
open ::STDERR, ">& $call_fds[2]" or fail_log("dup for fd2");
close_call_fds();
+ $! = 0;
return;
}
_exit(0);
}
-sub forked_monitor () {
- close LISTEN;
- eval { protocol_exchange(); 1; }
- or fail_log("protocol exchange failed: $@");
- return become_monitor();
-}
-
sub close_call_fds () {
foreach (@call_fds) {
- next if $_ <= 2;
POSIX::close($_);
}
close CALL;
}
sub protocol_exchange () {
- protocol_write("\n");
+ my $greeting = "PFI\n\0\0\0\0";
+ protocol_write($greeting);
@call_fds = map {
my $r;
$child = fork // fail_log("fork for accepted call failed: $!");
if (!$child) {
#---- monitor [1] ----
- forked_monitor();
+ become_monitor();
}
close(CALL);
$errcount = 0;