---- On Mon, 09 Oct 2023 11:33:16 +0100  Roy Marples  wrote --- 
 >  ---- On Sun, 08 Oct 2023 21:58:54 +0100  Lloyd Parkes  wrote --- 
 >  > 
 >  > 
 >  > On 8/10/23 15:30, Lloyd Parkes wrote:
 >  > I found the problem. The syslog function in /libexec/dhcpcd-run-hooks 
 >  > tries to echo text to stdout/stderr and the shell script gets killed 
 >  > with SIGPIPE when it's being run in the background.
 >  > 
 >  > Commenting out the lines
 >  > 
 >  >          case "$lvl" in
 >  >          err|error)      echo "$interface: $*" >&2;;
 >  >          *)              echo "$interface: $*";;
 >  >          esac
 >  > 
 >  > allows the script to run correctly.
 >  > 
 >  > Adding the command 'trap "" PIPE' to /libexec/dhcpcd-run-hooks is 
 >  > another way that allows the script to run correctly.
 > 
 > That's interesting. So I'm looking at two bugs here then
 > 1) Why is SIGPIPE being raised in the first place
 > 2) Why is it not being captured as an error and logged by dhcpcd.
 > 
 > As best I can tell, even forcing stdout and stderr to /dev/null doesn't help 
 > here.
 > What else could this be?

2) is fixed by this patch.
Now dhcpcd correctly reports a broken pipe from running the script.

https://github.com/NetworkConfiguration/dhcpcd/commit/617a3ae207898a968bccd1e40a299fbfa6a4cc52
diff --git a/src/script.c b/src/script.c
index 2ef99e38..69297a46 100644
--- a/src/script.c
+++ b/src/script.c
@@ -681,6 +681,21 @@ send_interface(struct fd_list *fd, const struct interface 
*ifp, int af)
        return retval;
 }
 
+static int
+script_status(const char *script, int status)
+{
+
+       if (WIFEXITED(status)) {
+               if (WEXITSTATUS(status))
+                       logerrx("%s: %s: WEXITSTATUS %d",
+                           __func__, script, WEXITSTATUS(status));
+       } else if (WIFSIGNALED(status))
+               logerrx("%s: %s: %s",
+                   __func__, script, strsignal(WTERMSIG(status)));
+
+       return WEXITSTATUS(status);
+}
+
 static int
 script_run(struct dhcpcd_ctx *ctx, char **argv)
 {
@@ -699,13 +714,7 @@ script_run(struct dhcpcd_ctx *ctx, char **argv)
                                break;
                        }
                }
-               if (WIFEXITED(status)) {
-                       if (WEXITSTATUS(status))
-                               logerrx("%s: %s: WEXITSTATUS %d",
-                                   __func__, argv[0], WEXITSTATUS(status));
-               } else if (WIFSIGNALED(status))
-                       logerrx("%s: %s: %s",
-                           __func__, argv[0], strsignal(WTERMSIG(status)));
+               status = script_status(argv[0], status);
        }
 
        return WEXITSTATUS(status);
@@ -763,9 +772,13 @@ script_runreason(const struct interface *ifp, const char 
*reason)
 
 #ifdef PRIVSEP
        if (ctx->options & DHCPCD_PRIVSEP) {
-               if (ps_root_script(ctx,
-                   ctx->script_buf, (size_t)buflen) == -1)
+               ssize_t err;
+
+               err = ps_root_script(ctx, ctx->script_buf, (size_t)buflen);
+               if (err == -1)
                        logerr(__func__);
+               else
+                       script_status(ctx->script, (int)err);
                goto send_listeners;
        }
 #endif

Reply via email to