From 7db62ef1ca46a3891d2701b1b0607be16c7c5a5f Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 15 Aug 2022 20:10:44 +0100 Subject: [PATCH] prefork-interp: Protocol work Signed-off-by: Ian Jackson --- cprogs/prefork-interp.c | 34 ++++++++++++++++++---------------- perl/Prefork.pm | 18 ++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cprogs/prefork-interp.c b/cprogs/prefork-interp.c index c62f00a..2e773d2 100644 --- a/cprogs/prefork-interp.c +++ b/cprogs/prefork-interp.c @@ -188,20 +188,22 @@ static void prepare_string(size_t *len, char **buf, const char *s) { 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) { @@ -254,14 +256,14 @@ static void send_request(void) { 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"); diff --git a/perl/Prefork.pm b/perl/Prefork.pm index bb39265..10c7ec1 100644 --- a/perl/Prefork.pm +++ b/perl/Prefork.pm @@ -36,6 +36,10 @@ sub server_quit ($) { # 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 ---- @@ -43,6 +47,7 @@ sub become_monitor () { 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; } @@ -54,16 +59,8 @@ sub become_monitor () { _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; @@ -93,7 +90,8 @@ sub protocol_read_fail ($) { } sub protocol_exchange () { - protocol_write("\n"); + my $greeting = "PFI\n\0\0\0\0"; + protocol_write($greeting); @call_fds = map { my $r; @@ -223,7 +221,7 @@ sub initialisation_complete { $child = fork // fail_log("fork for accepted call failed: $!"); if (!$child) { #---- monitor [1] ---- - forked_monitor(); + become_monitor(); } close(CALL); $errcount = 0; -- 2.30.2