[PATCH] Add adoption to trap

From: Carlos Eduardo <carana2099_at_gmail.com>
Date: Sat, 4 May 2024 16:58:21 -0300

With this patch, trap(1) is able to accept an existing PID as prog...,
if given the new -P option.

I'm sending this as patch because the only scenario where this does
something that isn't feasible with execline's current wait(1) command or
the original interface to trap is if you use Linux or Free/DragonFly BSD's
subreaper functionality to reuse trap as a turbo-fghack that forwards
signals and tracks the exit code of the forked-off daemon instead of
the short-lived daemonizer.

The code may not be OS-specific, but the top use-case is.

Signed-off-by: Carlos Eduardo <carana2099_at_gmail.com>
---
 src/execline/trap.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/src/execline/trap.c b/src/execline/trap.c
index ba1b25a..1a4aa60 100644
--- a/src/execline/trap.c
+++ b/src/execline/trap.c
_at__at_ -18,7 +18,7 _at__at_
 
 #include <execline/execline.h>
 
-#define USAGE "trap [ -x ] { signal { cmdline } ... } prog..."
+#define USAGE "trap [ -x ] [ -P ] { signal { cmdline } ... } prog..."
 #define dieusage() strerr_dieusage(100, USAGE) ;
 
 static inline void trap_action (unsigned int i, char const *const *envp, size_t envlen, pid_t *pids, char const *const **argvs)
_at__at_ -50,7 +50,7 _at__at_ int main (int argc, char const **argv, char const *const *envp)
   size_t envlen = env_len(envp) ;
   iopause_fd x = { .events = IOPAUSE_READ } ;
   sigset_t full, set ;
-  int xfersigs = 0 ;
+  int xfersigs = 0, adopt = 0 ;
   unsigned int argc1 ;
   unsigned int i = 0 ;
   PROG = "trap" ;
_at__at_ -59,11 +59,12 _at__at_ int main (int argc, char const **argv, char const *const *envp)
     subgetopt l = SUBGETOPT_ZERO ;
     for (;;)
     {
-      int opt = subgetopt_r(argc, argv, "xt:", &l) ;
+      int opt = subgetopt_r(argc, argv, "xP", &l) ;
       if (opt == -1) break ;
       switch (opt)
       {
         case 'x' : xfersigs = 1 ; break ;
+        case 'P' : adopt = 1 ; break ;
         default : dieusage() ;
       }
     }
_at__at_ -121,8 +122,23 _at__at_ int main (int argc, char const **argv, char const *const *envp)
   if (x.fd == -1) strerr_diefu1sys(111, "selfpipe_init") ;
   if (!selfpipe_trapset(&set)) strerr_diefu1sys(111, "trap signals") ;
 
-  pids[SKALIBS_NSIG] = cspawn(argv[argc1 + 1], argv + argc1 + 1, envp, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
-  if (!pids[SKALIBS_NSIG]) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ;
+  if (!adopt)
+  {
+    pids[SKALIBS_NSIG] = cspawn(argv[argc1 + 1], argv + argc1 + 1, envp, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0) ;
+    if (!pids[SKALIBS_NSIG]) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ;
+  } else {
+    int status;
+    if (argc > argc1 + 2)
+      dieusage();
+    if (!pid_scan(argv[argc1 + 1], &pids[SKALIBS_NSIG]))
+      strerr_dieinvalid(100, "PID");
+    switch (waitpid_nointr(pids[SKALIBS_NSIG], &status, WNOHANG))
+    {
+      case -1: strerr_dief2sys(111, "invalid ", "PID") ;
+      case 0 : break ;
+      default : return wait_estatus(status) ;
+    }
+  }
 
  loop:
   if (iopause_g(&x, 1, 0) < 0) strerr_diefu1sys(111, "iopause") ;
-- 
2.44.0
Received on Sat May 04 2024 - 21:58:21 CEST

This archive was generated by hypermail 2.4.0 : Sat May 04 2024 - 21:59:38 CEST