supervision - discussion about system services, daemon supervision, init, runlevel management, and tools such as s6 and runit
 help / color / mirror / Atom feed
* [PATCH] Add adoption to trap
@ 2024-05-04 19:58 Carlos Eduardo
  0 siblings, 0 replies; only message in thread
From: Carlos Eduardo @ 2024-05-04 19:58 UTC (permalink / raw)
  To: supervision; +Cc: Carlos Eduardo

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@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
@@ -18,7 +18,7 @@
 
 #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)
@@ -50,7 +50,7 @@ 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" ;
@@ -59,11 +59,12 @@ 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() ;
       }
     }
@@ -121,8 +122,23 @@ 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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-05-04 19:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-04 19:58 [PATCH] Add adoption to trap Carlos Eduardo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).