chiark / gitweb /
prefork-interp: Protocol work
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 15 Aug 2022 19:10:44 +0000 (20:10 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 21 Aug 2022 20:21:10 +0000 (21:21 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
cprogs/prefork-interp.c
perl/Prefork.pm

index c62f00ae2b69841ab7e4eb00abf9f150c60346d8..2e773d23ae9210c0f36b461959494429bc0ac92e 100644 (file)
@@ -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");
index bb39265b905f8c04b01dec568df50f3041275888..10c7ec1a70d7b477300285b990ec9b7111136136 100644 (file)
@@ -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;