about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-02-02 05:29:17 +0000
committerLaurent Bercot <ska@appnovation.com>2023-02-02 05:29:17 +0000
commit9d55d49dad0f4cb90e6ff2f9b1c3bc46a6fcf05f (patch)
treeea63cf6dd496942aa194e864f37cc56229d596fb
parentedf81b0d16322e5d49ec22f394b669d9094daac1 (diff)
downloadexecline-9d55d49dad0f4cb90e6ff2f9b1c3bc46a6fcf05f.tar.gz
execline-9d55d49dad0f4cb90e6ff2f9b1c3bc46a6fcf05f.tar.xz
execline-9d55d49dad0f4cb90e6ff2f9b1c3bc46a6fcf05f.zip
Multicall improvements
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--package/deps.mak12
-rw-r--r--src/execline/deps-exe/posix-cd (renamed from src/posix/deps-exe/posix-cd)0
-rw-r--r--src/execline/deps-exe/posix-umask (renamed from src/posix/deps-exe/posix-umask)0
-rw-r--r--src/execline/eltest.c20
-rw-r--r--src/execline/envfile.c18
-rw-r--r--src/execline/fdreserve.c8
-rw-r--r--src/execline/forstdin.c25
-rw-r--r--src/execline/multisubstitute.c38
-rw-r--r--src/execline/posix-cd.c (renamed from src/posix/posix-cd.c)0
-rw-r--r--src/execline/posix-umask.c (renamed from src/posix/posix-umask.c)30
-rw-r--r--src/execline/posix-umask.txt (renamed from src/posix/posix-umask.txt)0
-rw-r--r--src/execline/trap.c41
-rwxr-xr-xtools/gen-multicall.sh1
13 files changed, 97 insertions, 96 deletions
diff --git a/package/deps.mak b/package/deps.mak
index fa81ab3..6c5b0b9 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -42,6 +42,8 @@ src/execline/multidefine.o src/execline/multidefine.lo: src/execline/multidefine
 src/execline/multisubstitute.o src/execline/multisubstitute.lo: src/execline/multisubstitute.c src/include/execline/execline.h src/include-local/exlsn.h
 src/execline/pipeline.o src/execline/pipeline.lo: src/execline/pipeline.c src/include/execline/execline.h
 src/execline/piperw.o src/execline/piperw.lo: src/execline/piperw.c
+src/execline/posix-cd.o src/execline/posix-cd.lo: src/execline/posix-cd.c
+src/execline/posix-umask.o src/execline/posix-umask.lo: src/execline/posix-umask.c
 src/execline/redirfd.o src/execline/redirfd.lo: src/execline/redirfd.c
 src/execline/runblock.o src/execline/runblock.lo: src/execline/runblock.c src/include/execline/execline.h
 src/execline/shift.o src/execline/shift.lo: src/execline/shift.c src/include/execline/execline.h
@@ -75,8 +77,6 @@ src/libexecline/exlsn_free.o src/libexecline/exlsn_free.lo: src/libexecline/exls
 src/libexecline/exlsn_importas.o src/libexecline/exlsn_importas.lo: src/libexecline/exlsn_importas.c src/include/execline/execline.h src/include-local/exlsn.h
 src/libexecline/exlsn_main.o src/libexecline/exlsn_main.lo: src/libexecline/exlsn_main.c src/include/execline/execline.h src/include-local/exlsn.h
 src/libexecline/exlsn_multidefine.o src/libexecline/exlsn_multidefine.lo: src/libexecline/exlsn_multidefine.c src/include/execline/execline.h src/include-local/exlsn.h
-src/posix/posix-cd.o src/posix/posix-cd.lo: src/posix/posix-cd.c
-src/posix/posix-umask.o src/posix/posix-umask.lo: src/posix/posix-umask.c
 
 background: EXTRA_LIBS := -lskarnet ${SPAWN_LIB}
 background: src/execline/background.o ${LIBEXECLINE}
@@ -158,6 +158,10 @@ pipeline: EXTRA_LIBS := -lskarnet ${SPAWN_LIB}
 pipeline: src/execline/pipeline.o ${LIBEXECLINE}
 piperw: EXTRA_LIBS := -lskarnet
 piperw: src/execline/piperw.o
+posix-cd: EXTRA_LIBS := -lskarnet
+posix-cd: src/execline/posix-cd.o
+posix-umask: EXTRA_LIBS := -lskarnet
+posix-umask: src/execline/posix-umask.o
 redirfd: EXTRA_LIBS := -lskarnet
 redirfd: src/execline/redirfd.o
 runblock: EXTRA_LIBS := -lskarnet
@@ -183,7 +187,3 @@ libexecline.so.xyzzy: EXTRA_LIBS := -lskarnet
 libexecline.so.xyzzy: src/libexecline/el_execsequence.lo src/libexecline/el_getstrict.lo src/libexecline/el_modif_and_exec.lo src/libexecline/el_modif_and_spawn.lo src/libexecline/el_parse.lo src/libexecline/el_parse_from_buffer.lo src/libexecline/el_parse_from_string.lo src/libexecline/el_popenv.lo src/libexecline/el_pushenv.lo src/libexecline/el_semicolon.lo src/libexecline/el_spawn0.lo src/libexecline/el_spawn1.lo src/libexecline/el_substandrun.lo src/libexecline/el_substandrun_str.lo src/libexecline/el_substitute.lo src/libexecline/el_transform.lo src/libexecline/el_vardupl.lo src/libexecline/exlsn_define.lo src/libexecline/exlsn_elglob.lo src/libexecline/exlsn_importas.lo src/libexecline/exlsn_multidefine.lo src/libexecline/exlsn_exlp.lo src/libexecline/exlsn_main.lo src/libexecline/exlsn_free.lo src/libexecline/exlp.lo
 execline: EXTRA_LIBS := -lskarnet ${SPAWN_LIB} ${MAYBEPTHREAD_LIB}
 execline: src/multicall/execline.o ${LIBEXECLINE} ${LIBNSSS}
-posix-cd: EXTRA_LIBS := -lskarnet
-posix-cd: src/posix/posix-cd.o
-posix-umask: EXTRA_LIBS := -lskarnet
-posix-umask: src/posix/posix-umask.o
diff --git a/src/posix/deps-exe/posix-cd b/src/execline/deps-exe/posix-cd
index e7187fe..e7187fe 100644
--- a/src/posix/deps-exe/posix-cd
+++ b/src/execline/deps-exe/posix-cd
diff --git a/src/posix/deps-exe/posix-umask b/src/execline/deps-exe/posix-umask
index e7187fe..e7187fe 100644
--- a/src/posix/deps-exe/posix-umask
+++ b/src/execline/deps-exe/posix-umask
diff --git a/src/execline/eltest.c b/src/execline/eltest.c
index 93ff0b4..34321c5 100644
--- a/src/execline/eltest.c
+++ b/src/execline/eltest.c
@@ -11,7 +11,7 @@
 #include <skalibs/strerr.h>
 #include <skalibs/djbunix.h>
 
-enum opnum
+enum eltest_opnum_e
 {
   T_NOT,
   T_AND,
@@ -58,25 +58,25 @@ enum opnum
   T_MATCH
 } ;
 
-struct token
+struct eltest_token_s
 {
   char const *string ;
-  enum opnum op ;
+  enum eltest_opnum_e op ;
   unsigned int type ;
 } ;
 
-struct node
+struct eltest_node_s
 {
-  enum opnum op ;
+  enum eltest_opnum_e op ;
   unsigned int type ;
   unsigned int arg1 ;
   unsigned int arg2 ;
   char const *data ;
 } ;
 
-static unsigned int eltest_lex (struct node *tree, char const *const *argv)
+static unsigned int eltest_lex (struct eltest_node_s *tree, char const *const *argv)
 {
-  static struct token const tokens[46] =
+  static struct eltest_token_s const tokens[46] =
   {
     { "-n", T_NONZERO, 2 },
     { "-z", T_ZERO, 2 },
@@ -149,7 +149,7 @@ static unsigned int eltest_lex (struct node *tree, char const *const *argv)
   return pos ;
 }
 
-static unsigned int eltest_parse (struct node *tree, unsigned int n)
+static unsigned int eltest_parse (struct eltest_node_s *tree, unsigned int n)
 {
   static char const table[9][13] =
   {
@@ -278,7 +278,7 @@ static unsigned int eltest_parse (struct node *tree, unsigned int n)
   return stack[1] ;
 }
 
-static int eltest_run (struct node const *tree, unsigned int root)
+static int eltest_run (struct eltest_node_s const *tree, unsigned int root)
 {
   switch (tree[root].op)
   {
@@ -498,7 +498,7 @@ errorint:
 
 int main (int argc, char const *const *argv)
 {
-  struct node tree[argc+2] ;
+  struct eltest_node_s tree[argc+2] ;
   if (argc <= 1) return 1 ;
   PROG = "eltest" ;
   return !eltest_run(tree, eltest_parse(tree, eltest_lex(tree, argv+1))) ;
diff --git a/src/execline/envfile.c b/src/execline/envfile.c
index 3b95c54..100e1ee 100644
--- a/src/execline/envfile.c
+++ b/src/execline/envfile.c
@@ -19,7 +19,7 @@
 #define dieusage() strerr_dieusage(100, USAGE)
 #define dienomem() strerr_diefu1sys(111, "stralloc_catb")
 
-static void scanoct (stralloc *sa, size_t pos)
+static void envfile_scanoct (stralloc *sa, size_t pos)
 {
   unsigned int u ;
   if (!stralloc_0(sa)) dienomem() ;
@@ -28,7 +28,7 @@ static void scanoct (stralloc *sa, size_t pos)
   sa->len = pos+1 ;
 }
 
-static inline uint8_t cclass (char c)
+static inline uint8_t envfile_cclass (char c)
 {
   switch (c)
   {
@@ -75,7 +75,7 @@ static inline uint8_t cclass (char c)
   }
 }
 
-static inline char next (char const *file, buffer *b)
+static inline char envfile_next (char const *file, buffer *b)
 {
   char c ;
   ssize_t r = buffer_get(b, &c, 1) ;
@@ -84,7 +84,7 @@ static inline char next (char const *file, buffer *b)
   return c ;
 }
 
-static inline void parse_config (char const *file, buffer *b, stralloc *sa)
+static inline void envfile_parse_config (char const *file, buffer *b, stralloc *sa)
 {
   static uint16_t const table[14][14] =
   {
@@ -108,10 +108,10 @@ static inline void parse_config (char const *file, buffer *b, stralloc *sa)
   uint8_t state = 0 ;
   while (state < 14)
   {
-    char c = next(file, b) ;
-    uint16_t what = table[state][cclass(c)] ;
+    char c = envfile_next(file, b) ;
+    uint16_t what = table[state][envfile_cclass(c)] ;
     state = what & 0x0f ;
-    if (what & 0x0400) scanoct(sa, mark) ;
+    if (what & 0x0400) envfile_scanoct(sa, mark) ;
     if (what & 0x0100) mark = sa->len ;
     if (what & 0x1000) c = 7 + byte_chr("abtnvfr", 7, c) ;
     if (what & 0x0010) if (!stralloc_catb(sa, &c, 1)) dienomem() ;
@@ -123,7 +123,7 @@ static inline void parse_config (char const *file, buffer *b, stralloc *sa)
       sa->s[sa->len-2] = (fmtscan_num(sa->s[sa->len-2], 16) << 4) + fmtscan_num(sa->s[sa->len-1], 16) ;
       sa->len-- ;
     }
-    if (what & 0x0800) scanoct(sa, mark) ;
+    if (what & 0x0800) envfile_scanoct(sa, mark) ;
   }
   if (state > 14)
   {
@@ -177,7 +177,7 @@ int main (int argc, char const *const *argv)
     buffer b ;
     char buf[BUFFER_INSIZE] ;
     buffer_init(&b, &buffer_read, fd, buf, BUFFER_INSIZE) ;
-    parse_config(name, &b, &modif) ;
+    envfile_parse_config(name, &b, &modif) ;
     fd_close(fd) ;
   }
   xmexec_m(argv + 1, modif.s, modif.len) ;
diff --git a/src/execline/fdreserve.c b/src/execline/fdreserve.c
index 15ee25a..5d18377 100644
--- a/src/execline/fdreserve.c
+++ b/src/execline/fdreserve.c
@@ -12,7 +12,7 @@
 
 #define MAXFDS 1024
 
-unsigned int doit (char *modif, unsigned int i, int fd)
+unsigned int fdreserve_doit (char *modif, unsigned int i, int fd)
 {
   unsigned int pos = 2 ;
   modif[0] = 'F' ; modif[1] = 'D' ;
@@ -49,14 +49,14 @@ int main (int argc, char const *const *argv)
         if (lastfd < 0)
           strerr_diefu1sys(111, "reserve last fd") ;
         fd_close(lastfd) ;
-        j += doit(modif + j, n-1, lastfd) ;
+        j += fdreserve_doit(modif + j, n-1, lastfd) ;
       }
       for (i = 0 ; i < (n>>1) ; i++)
       {
         fd_close(fd[i][0]) ;
         fd_close(fd[i][1]) ;
-        j += doit(modif + j, i<<1, fd[i][0]) ;
-        j += doit(modif + j, (i<<1)|1, fd[i][1]) ;
+        j += fdreserve_doit(modif + j, i<<1, fd[i][0]) ;
+        j += fdreserve_doit(modif + j, (i<<1)|1, fd[i][1]) ;
       }
     }
     xmexec_n(argv+2, modif, j, n) ;
diff --git a/src/execline/forstdin.c b/src/execline/forstdin.c
index e365866..b023640 100644
--- a/src/execline/forstdin.c
+++ b/src/execline/forstdin.c
@@ -19,7 +19,7 @@
 #define USAGE "forstdin [ -E | -e ] [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -N | -n ] [ -C | -c ] [ -0 | -d delim ] var command..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
-static genalloc forstdin_pids = GENALLOC_ZERO ; /* pid_t */
+static genalloc *forstdin_pids_p = 0 ;  /* minimize bss/data */
 
 static int fs_isok (unsigned short *tab, unsigned int n, int code)
 {
@@ -30,8 +30,8 @@ static int fs_isok (unsigned short *tab, unsigned int n, int code)
 
 static void parallel_sigchld_handler (int sig)
 {
-  pid_t *tab = genalloc_s(pid_t, &forstdin_pids) ;
-  size_t len = genalloc_len(pid_t, &forstdin_pids) ;
+  pid_t *tab = genalloc_s(pid_t, forstdin_pids_p) ;
+  size_t len = genalloc_len(pid_t, forstdin_pids_p) ;
   int wstat ;
   for (;;)
   {
@@ -39,12 +39,13 @@ static void parallel_sigchld_handler (int sig)
     if (r <= 0) break ;
     tab[r-1] = tab[--len] ;
   }
-  genalloc_setlen(pid_t, &forstdin_pids, len) ;
+  genalloc_setlen(pid_t, forstdin_pids_p, len) ;
   (void)sig ;
 }
 
 int main (int argc, char const **argv)
 {
+  genalloc pids = GENALLOC_ZERO ;
   stralloc value = STRALLOC_ZERO ;
   char const *delim = "\n" ;
   size_t delimlen = 1 ;
@@ -52,6 +53,8 @@ int main (int argc, char const **argv)
   unsigned short okcodes[256] ;
   int crunch = 0, chomp = 1, not = 1, eofcode = 1, doimport = 0 ;
   PROG = "forstdin" ;
+  forstdin_pids_p = &pids ;
+
   {
     subgetopt l = SUBGETOPT_ZERO ;
     for (;;)
@@ -62,7 +65,7 @@ int main (int argc, char const **argv)
       {
         case 'p' :
         {
-          if (!genalloc_ready(pid_t, &forstdin_pids, 1))
+          if (!genalloc_ready(pid_t, &pids, 1))
             strerr_diefu1sys(111, "genalloc_ready") ;
           break ;
         }
@@ -90,7 +93,7 @@ int main (int argc, char const **argv)
   if (argc < 2) dieusage() ;
   if (!argv[0][0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ;
 
-  if (forstdin_pids.s)
+  if (pids.s)
   {
     if (!sig_catch(SIGCHLD, &parallel_sigchld_handler))
       strerr_diefu1sys(111, "install SIGCHLD handler") ;
@@ -122,12 +125,12 @@ int main (int argc, char const **argv)
     }
     eofcode = 0 ;
     if (!stralloc_0(&value)) strerr_diefu1sys(111, "stralloc_0") ;
-    if (forstdin_pids.s) sig_block(SIGCHLD) ;
+    if (pids.s) sig_block(SIGCHLD) ;
     pid = el_modif_and_spawn(argv + 1, argv[0], value.s, doimport) ;
     if (!pid) strerr_diefu2sys(111, "spawn ", argv[1]) ;
-    if (forstdin_pids.s)
+    if (pids.s)
     {
-      if (!genalloc_append(pid_t, &forstdin_pids, &pid))
+      if (!genalloc_append(pid_t, &pids, &pid))
         strerr_diefu1sys(111, "genalloc_append") ;
       sig_unblock(SIGCHLD) ;
     }
@@ -140,14 +143,14 @@ int main (int argc, char const **argv)
         return wait_estatus(wstat) ;
     }
   }
-  if (forstdin_pids.s)
+  if (pids.s)
   {
     sigset_t empty ;
     sigemptyset(&empty) ;
     sig_block(SIGCHLD) ;
     for (;;)
     {
-      if (!forstdin_pids.len) break ;
+      if (!pids.len) break ;
       sigsuspend(&empty) ;
     }
   }
diff --git a/src/execline/multisubstitute.c b/src/execline/multisubstitute.c
index 7e1eb91..da4e222 100644
--- a/src/execline/multisubstitute.c
+++ b/src/execline/multisubstitute.c
@@ -7,28 +7,26 @@
 
 #define USAGE "see http://skarnet.org/software/execline/multisubstitute.html"
 
-static char const *const commands[] =
-{
-  "define",
-  "importas",
-  "elglob",
-  "elgetpositionals",
-  "multidefine",
-  0
-} ;
-
-static exls_func_ref const functions[] =
-{
-  &exlsn_define,
-  &exlsn_importas,
-  &exlsn_elglob,
-  &exlsn_exlp,
-  &exlsn_multidefine,
-  0
-} ;
-
 int main (int argc, char const **argv, char const *const *envp)
 {
+  static char const *const commands[] =
+  {
+    "define",
+    "importas",
+    "elglob",
+    "elgetpositionals",
+    "multidefine",
+    0
+  } ;
+  static exls_func_ref const functions[] =
+  {
+    &exlsn_define,
+    &exlsn_importas,
+    &exlsn_elglob,
+    &exlsn_exlp,
+    &exlsn_multidefine,
+    0
+  } ;
   exlsn_t info = EXLSN_ZERO ;
   int argc1 ;
   PROG = "multisubstitute" ;
diff --git a/src/posix/posix-cd.c b/src/execline/posix-cd.c
index e9bfd35..e9bfd35 100644
--- a/src/posix/posix-cd.c
+++ b/src/execline/posix-cd.c
diff --git a/src/posix/posix-umask.c b/src/execline/posix-umask.c
index 8785bed..69f4b08 100644
--- a/src/posix/posix-umask.c
+++ b/src/execline/posix-umask.c
@@ -19,7 +19,7 @@
 
  /* well, unlike posix-cd, at least this one was fun to write */
 
-static inline int output (int sym)
+static inline int pu_output (int sym)
 {
   mode_t mode = umask(0) ;
   size_t m = 0 ;
@@ -43,13 +43,13 @@ static inline int output (int sym)
   return 0 ;
 }
 
-static void diesyntax (char const *) gccattr_noreturn ;
-static void diesyntax (char const *s)
+static void pu_diesyntax (char const *) gccattr_noreturn ;
+static void pu_diesyntax (char const *s)
 {
   strerr_dief3x(101, "internal parsing error: bad ", s, ". Please submit a bug-report.") ;
 }
 
-static inline uint8_t cclass (char c)
+static inline uint8_t pu_cclass (char c)
 {
  /* char tables may be more efficient, but this is way more readable */
   switch (c)
@@ -73,7 +73,7 @@ static inline uint8_t cclass (char c)
   }
 }
 
-static inline uint8_t who_value (char c)
+static inline uint8_t pu_who_value (char c)
 {
   switch (c)
   {
@@ -84,11 +84,11 @@ static inline uint8_t who_value (char c)
     case '+' : /* shortcut for when who is empty */
     case '-' :
     case '=' : return 7 ;
-    default : diesyntax("who") ;
+    default : pu_diesyntax("who") ;
   }
 }
 
-static inline uint8_t perm_value (char c)
+static inline uint8_t pu_perm_value (char c)
 {
   switch (c)
   {
@@ -98,11 +98,11 @@ static inline uint8_t perm_value (char c)
     case 'X' : return 1 ;
     case 's' :
     case 't' : return 0 ;
-    default : diesyntax("perm") ;
+    default : pu_diesyntax("perm") ;
   }
 }
 
-static inline unsigned int parsemode (char const *s)
+static inline unsigned int pu_parsemode (char const *s)
 {
   static uint16_t const table[5][7] =
   {
@@ -121,11 +121,11 @@ static inline unsigned int parsemode (char const *s)
   while (state < 5)
   {
     char c = *s++ ;
-    uint16_t what = table[state][cclass(c)] ;
+    uint16_t what = table[state][pu_cclass(c)] ;
     state = what & 7 ;
-    if (what & 0x020) who |= who_value(c) ;
+    if (what & 0x020) who |= pu_who_value(c) ;
     if (what & 0x080) perm = modes[byte_chr("ogu", 3, c)] ;
-    if (what & 0x100) perm |= perm_value(c) ;
+    if (what & 0x100) perm |= pu_perm_value(c) ;
     if (what & 0x800)
     {
       unsigned int i = 3 ;
@@ -135,7 +135,7 @@ static inline unsigned int parsemode (char const *s)
           case '-' : modes[i] &= ~perm ; break ;
           case '+' : modes[i] |= perm ; break ;
           case '=' : modes[i] = perm ; break ;
-          default : diesyntax("op") ;
+          default : pu_diesyntax("op") ;
         }
     }
     if (what & 0x040) op = c ;
@@ -167,8 +167,8 @@ int main (int argc, char const **argv)
     }
     argc -= l.ind ; argv += l.ind ;
   }
-  if (!argc) return output(sym) ;
-  if (!uint0_oscan(argv[0], &mode)) mode = ~parsemode(argv[0]) ;
+  if (!argc) return pu_output(sym) ;
+  if (!uint0_oscan(argv[0], &mode)) mode = ~pu_parsemode(argv[0]) ;
   umask(mode & 00777) ;
   xexec0(argv+1) ;
 }
diff --git a/src/posix/posix-umask.txt b/src/execline/posix-umask.txt
index 5bf49a2..5bf49a2 100644
--- a/src/posix/posix-umask.txt
+++ b/src/execline/posix-umask.txt
diff --git a/src/execline/trap.c b/src/execline/trap.c
index 630f865..52541ca 100644
--- a/src/execline/trap.c
+++ b/src/execline/trap.c
@@ -20,34 +20,33 @@
 #define USAGE "trap [ -x ] { signal { cmdline } ... } prog..."
 #define dieusage() strerr_dieusage(100, USAGE) ;
 
-static pid_t trap_pids[SKALIBS_NSIG + 1] ;
-static char const *const *trap_argvs[SKALIBS_NSIG] ; /* initted with 0s */
-
-static inline void action (unsigned int i, char const *const *envp, size_t envlen)
+static inline void trap_action (unsigned int i, char const *const *envp, size_t envlen, pid_t *pids, char const *const **argvs)
 {
-  if (trap_argvs[i])
+  if (argvs[i])
   {
-    if (!trap_pids[i])
+    if (!pids[i])
     {
       char const *newenvp[envlen + 3] ;
       char modif[9 + PID_FMT + UINT_FMT] = "!=" ;
       size_t m = 2 ;
-      m += pid_fmt(modif + m, trap_pids[SKALIBS_NSIG]) ;
+      m += pid_fmt(modif + m, pids[SKALIBS_NSIG]) ;
       modif[m++] = 0 ;
       memcpy(modif + m, "SIGNAL=", 7) ; m += 7 ;
       m += uint_fmt(modif + m, i) ;
       modif[m++] = 0 ;
       if (!env_mergen(newenvp, envlen + 3, envp, envlen, modif, m, 2))
         strerr_diefu1sys(111, "adjust environment for child") ;
-      trap_pids[i] = child_spawn0(trap_argvs[i][0], trap_argvs[i], newenvp) ;
-      if (!trap_pids[i]) strerr_diefu2sys(111, "spawn ", trap_argvs[i][0]) ;
+      pids[i] = child_spawn0(argvs[i][0], argvs[i], newenvp) ;
+      if (!pids[i]) strerr_diefu2sys(111, "spawn ", argvs[i][0]) ;
     }
   }
-  else kill(trap_pids[SKALIBS_NSIG], i) ;
+  else kill(pids[SKALIBS_NSIG], i) ;
 }
 
 int main (int argc, char const **argv, char const *const *envp)
 {
+  pid_t pids[SKALIBS_NSIG + 1] ;
+  char const *const *argvs[SKALIBS_NSIG] = { 0 } ;
   size_t envlen = env_len(envp) ;
   iopause_fd x = { .events = IOPAUSE_READ } ;
   sigset_t full, set ;
@@ -89,10 +88,10 @@ int main (int argc, char const **argv, char const *const *envp)
     argc2 = el_semicolon(argv + ++i) ;
     if (i + argc2 >= argc1)
       strerr_dief3x(100, "unterminated", " internal block for directive ", argv[i-1]) ;
-    if (trap_argvs[sig])
+    if (argvs[sig])
       strerr_dief3x(100, "duplicate", " directive: ", argv[i-1]) ;
     if (!sig || (sig != SIGCHLD && sigismember(&full, sig) > 0))
-      trap_argvs[sig] = argv + i ;
+      argvs[sig] = argv + i ;
     else
     {
       char fmt[UINT_FMT] ;
@@ -103,10 +102,10 @@ int main (int argc, char const **argv, char const *const *envp)
     i += argc2 + 1 ;
   }
 
-  if (trap_argvs[0])
+  if (argvs[0])
     for (i = 1 ; i < SKALIBS_NSIG ; i++)
-      if (!trap_argvs[i] && sigismember(&full, i) > 0)
-        trap_argvs[i] = trap_argvs[0] ;
+      if (!argvs[i] && sigismember(&full, i) > 0)
+        argvs[i] = argvs[0] ;
 
   if (xfersigs) set = full ;
   else
@@ -114,7 +113,7 @@ int main (int argc, char const **argv, char const *const *envp)
     sigemptyset(&set) ;
     sigaddset(&set, SIGCHLD) ;
     for (i = 1 ; i < SKALIBS_NSIG ; i++)
-      if (trap_argvs[i])
+      if (argvs[i])
         sigaddset(&set, i) ;
   }
 
@@ -122,8 +121,8 @@ int main (int argc, char const **argv, char const *const *envp)
   if (x.fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
   if (!selfpipe_trapset(&set)) strerr_diefu1sys(111, "trap signals") ;
 
-  trap_pids[SKALIBS_NSIG] = child_spawn0(argv[argc1 + 1], argv + argc1 + 1, envp) ;
-  if (!trap_pids[SKALIBS_NSIG]) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ;
+  pids[SKALIBS_NSIG] = child_spawn0(argv[argc1 + 1], argv + argc1 + 1, envp) ;
+  if (!pids[SKALIBS_NSIG]) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ;
 
  loop:
   if (iopause_g(&x, 1, 0) < 0) strerr_diefu1sys(111, "iopause") ;
@@ -138,16 +137,16 @@ int main (int argc, char const **argv, char const *const *envp)
         for (;;)
         {
           int wstat ;
-          ssize_t id = wait_pids_nohang(trap_pids, SKALIBS_NSIG + 1, &wstat) ;
+          ssize_t id = wait_pids_nohang(pids, SKALIBS_NSIG + 1, &wstat) ;
           if (id < 0 && errno != ECHILD)
             strerr_diefu1sys(111, "wait") ;
           if (id <= 0) break ;
-          trap_pids[id - 1] = 0 ;
+          pids[id - 1] = 0 ;
           if (id == SKALIBS_NSIG + 1) return wait_estatus(wstat) ;
         }
         break ;
       default :
-        action(r, envp, envlen) ;
+        trap_action(r, envp, envlen, pids, argvs) ;
     }
   }
 }
diff --git a/tools/gen-multicall.sh b/tools/gen-multicall.sh
index d9b03d3..6ef6322 100755
--- a/tools/gen-multicall.sh
+++ b/tools/gen-multicall.sh
@@ -49,6 +49,7 @@ for i in `ls -1 src/execline/deps-exe` ; do
   echo
   echo '#undef USAGE'
   echo '#undef dieusage'
+  echo '#undef dienomem'
 done
 
 cat <<EOF