about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2020-11-25 00:01:25 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2020-11-25 00:01:25 +0000
commitd4ed432960c1bf54de426bdb53825c1c1b32112e (patch)
tree56d60d455db64cb63694edcd4525298a506175d7
parent02fa8ea0993971a90b0f8d11b882af1e6a86c273 (diff)
downloadexecline-d4ed432960c1bf54de426bdb53825c1c1b32112e.tar.gz
execline-d4ed432960c1bf54de426bdb53825c1c1b32112e.tar.xz
execline-d4ed432960c1bf54de426bdb53825c1c1b32112e.zip
Port to skalibs-2.9.4.0
-rw-r--r--src/execline/background.c11
-rw-r--r--src/execline/backtick.c6
-rw-r--r--src/execline/elgetopt.c16
-rw-r--r--src/execline/emptyenv.c14
-rw-r--r--src/execline/envfile.c5
-rw-r--r--src/execline/exec.c7
-rw-r--r--src/execline/execline-cd.c7
-rw-r--r--src/execline/execline-umask.c7
-rw-r--r--src/execline/execlineb.c10
-rw-r--r--src/execline/export.c8
-rw-r--r--src/execline/fdblock.c5
-rw-r--r--src/execline/fdclose.c5
-rw-r--r--src/execline/fdmove.c5
-rw-r--r--src/execline/fdreserve.c9
-rw-r--r--src/execline/fdswap.c5
-rw-r--r--src/execline/forbacktickx.c8
-rw-r--r--src/execline/forstdin.c3
-rw-r--r--src/execline/forx.c5
-rw-r--r--src/execline/getcwd.c7
-rw-r--r--src/execline/getpid.c12
-rw-r--r--src/execline/heredoc.c6
-rw-r--r--src/execline/homeof.c1
-rw-r--r--src/execline/if.c5
-rw-r--r--src/execline/ifelse.c8
-rw-r--r--src/execline/ifte.c5
-rw-r--r--src/execline/ifthenelse.c5
-rw-r--r--src/execline/loopwhilex.c3
-rw-r--r--src/execline/pipeline.c10
-rw-r--r--src/execline/piperw.c6
-rw-r--r--src/execline/redirfd.c4
-rw-r--r--src/execline/runblock.c14
-rw-r--r--src/execline/shift.c18
-rw-r--r--src/execline/trap.c2
-rw-r--r--src/execline/tryexec.c10
-rw-r--r--src/execline/unexport.c7
-rw-r--r--src/execline/wait.c5
-rw-r--r--src/execline/withstdinas.c10
-rw-r--r--src/libexecline/el_execsequence.c10
-rw-r--r--src/libexecline/el_substandrun_str.c6
-rw-r--r--src/posix/posix-cd.c8
-rw-r--r--src/posix/posix-umask.c6
41 files changed, 169 insertions, 135 deletions
diff --git a/src/execline/background.c b/src/execline/background.c
index e8def5b..8a301a4 100644
--- a/src/execline/background.c
+++ b/src/execline/background.c
@@ -1,13 +1,11 @@
 /* ISC license. */
 
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
+#include <skalibs/types.h>
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/env.h>
 #include <skalibs/djbunix.h>
-#include <skalibs/types.h>
+
 #include <execline/execline.h>
 
 #define USAGE "background [ -d ] { command... }"
@@ -46,8 +44,7 @@ int main (int argc, char const **argv, char const *const *envp)
       case -1: strerr_diefu1sys(111, "doublefork") ;
       case 0:
         PROG = "background (grandchild)" ;
-        pathexec0_run(argv, envp) ;
-        strerr_dieexec(errno == ENOENT ? 127 : 126, argv[0]) ;
+        xexec0_e(argv, envp) ;
     }
   }
   else
@@ -60,6 +57,6 @@ int main (int argc, char const **argv, char const *const *envp)
     char fmt[PID_FMT + 2] = "!=" ;
     size_t i = 2 ;
     i += pid_fmt(fmt+i, pid) ; fmt[i++] = 0 ;
-    xpathexec_r(argv + argc1 + 1, envp, env_len(envp), fmt, i) ;
+    xmexec_en(argv + argc1 + 1, envp, fmt, i, 1) ;
   }
 }
diff --git a/src/execline/backtick.c b/src/execline/backtick.c
index ea2399f..fa7403f 100644
--- a/src/execline/backtick.c
+++ b/src/execline/backtick.c
@@ -3,11 +3,13 @@
 #include <string.h>
 #include <sys/wait.h>
 #include <unistd.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/stralloc.h>
-#include <skalibs/env.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+
 #include <execline/execline.h>
 
 #define USAGE "backtick [ -i | -I | -D default ] [ -N | -n ] var { prog... } remainder..."
@@ -98,5 +100,5 @@ int main (int argc, char const **argv, char const *const *envp)
     if (chomp && (modif.s[modif.len - 2] == '\n'))
       modif.s[--modif.len - 1] = 0 ;
   }
-  xpathexec_r(argv + argc1 + 1, envp, env_len(envp), modif.s, modif.len) ;
+  xmexec_en(argv + argc1 + 1, envp, modif.s, modif.len, 1) ;
 }
diff --git a/src/execline/elgetopt.c b/src/execline/elgetopt.c
index 6a94fe9..7ed6d89 100644
--- a/src/execline/elgetopt.c
+++ b/src/execline/elgetopt.c
@@ -1,12 +1,14 @@
 /* ISC license. */
 
-#include <sys/types.h>
+#include <stdlib.h>
+
+#include <skalibs/types.h>
 #include <skalibs/sgetopt.h>
-#include <skalibs/env.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/env.h>
+#include <skalibs/exec.h>
 #include <skalibs/skamisc.h>
-#include <skalibs/types.h>
+
 #include <execline/execline.h>
 
 #define USAGE "elgetopt optstring prog..."
@@ -15,7 +17,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
 {
   size_t envlen = env_len(envp) ;
   stralloc modif = STRALLOC_ZERO ;
-  char const *x = env_get2(envp, "#") ;
+  char const *x = getenv("#") ;
   unsigned int n, nbak ;
 
   PROG = "elgetopt" ;
@@ -31,7 +33,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
     {
       char fmt[UINT_FMT] ;
       fmt[uint_fmt(fmt, i)] = 0 ;
-      args[i] = env_get2(envp, fmt) ;
+      args[i] = getenv(fmt) ;
       if (!args[i]) strerr_dienotset(100, fmt) ;
     }
     args[n] = 0 ;
@@ -62,7 +64,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
     char const *v[envlen] ;
     if (el_pushenv(&satmp, envp, envlen, list, 1) < 0) goto err ;
     if (!env_make(v, envlen, satmp.s, satmp.len)) goto err ;
-    xpathexec_r(argv+2, v, envlen, modif.s, modif.len) ;
+    xmexec_fm(argv+2, v, envlen, modif.s, modif.len) ;
   }
 err:
   strerr_diefu1sys(111, "update environment") ;
diff --git a/src/execline/emptyenv.c b/src/execline/emptyenv.c
index 7f6ef59..ccc96e5 100644
--- a/src/execline/emptyenv.c
+++ b/src/execline/emptyenv.c
@@ -1,13 +1,15 @@
 /* ISC license. */
 
 #include <string.h>
+
 #include <skalibs/gccattributes.h>
 #include <skalibs/bytestr.h>
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/stralloc.h>
 #include <skalibs/env.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+
 #include <execline/execline.h>
 
 #define USAGE "emptyenv [ -p | -c | -o | -P ] prog..."
@@ -16,7 +18,7 @@ static void cleanupenv (char const *const *, char const *const *) gccattr_noretu
 static void cleanupenv (char const *const *argv, char const *const *envp)
 {
   stralloc sa = STRALLOC_ZERO ;
-  if (!pathexec_env("!", 0) || !pathexec_env("?", 0)) goto err ;
+  if (!env_mexec("!", 0) || !env_mexec("?", 0)) goto err ;
   for (; *envp ; envp++)
   {
     char const *s = *envp ;
@@ -28,11 +30,11 @@ static void cleanupenv (char const *const *argv, char const *const *envp)
      || ((s[0] >= '0') && (s[0] <= '9')))
       if (!stralloc_catb(&sa, s, str_chr(s, '='))
        || !stralloc_0(&sa)
-       || !pathexec_env(sa.s, 0))
+       || !env_mexec(sa.s, 0))
         goto err ;
   }
   stralloc_free(&sa) ;
-  xpathexec(argv) ;
+  xmexec_e(argv, envp) ;
 err:
   strerr_diefu1sys(111, "clean up environment") ;
 }
@@ -70,7 +72,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
           newenv[0] = *envp ;
           break ;
         }
-    xpathexec_run(argv[0], argv, newenv) ;
+    xexec_e(argv, newenv) ;
   }
   else
   {
@@ -83,7 +85,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
       char const *v[envlen - n + 1] ;
       if (!env_make(v, envlen-n, sa.s, sa.len)) strerr_diefu1sys(111, "env_make") ;
       v[envlen-n] = 0 ;
-      xpathexec_run(argv[0], argv, v) ;
+      xexec_e(argv, v) ;
     }
   }
 }
diff --git a/src/execline/envfile.c b/src/execline/envfile.c
index aff5964..555e464 100644
--- a/src/execline/envfile.c
+++ b/src/execline/envfile.c
@@ -13,6 +13,7 @@
 #include <skalibs/env.h>
 #include <skalibs/stralloc.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "envfile [ -i | -I ] file prog..."
 #define dieusage() strerr_dieusage(100, USAGE)
@@ -132,7 +133,7 @@ static inline void parse_config (char const *file, buffer *b, stralloc *sa)
   }
 }
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   stralloc modif = STRALLOC_ZERO ;
   int fd ;
@@ -179,5 +180,5 @@ int main (int argc, char const *const *argv, char const *const *envp)
     parse_config(name, &b, &modif) ;
     fd_close(fd) ;
   }
-  xpathexec_r(argv + 1, envp, env_len(envp), modif.s, modif.len) ;
+  xmexec_m(argv + 1, modif.s, modif.len) ;
 }
diff --git a/src/execline/exec.c b/src/execline/exec.c
index 28c9fd8..494716f 100644
--- a/src/execline/exec.c
+++ b/src/execline/exec.c
@@ -1,9 +1,10 @@
 /* ISC license. */
 
 #include <string.h>
-#include <skalibs/djbunix.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
+#include <skalibs/exec.h>
 
 #define USAGE "exec [ -c ] [ -l ] [ -a argv0 ] prog..."
 
@@ -41,7 +42,7 @@ int main (int argc, char const **argv, char const *const *envp)
     dashed[0] = '-' ;
     memcpy(dashed+1, argv[0], n+1) ;
     argv[0] = (char const *)dashed ;
-    xpathexec_run(executable, argv, envp) ;
+    xexec_ae(executable, argv, envp) ;
   }
-  else xpathexec_run(executable, argv, envp) ;
+  else xexec_ae(executable, argv, envp) ;
 }
diff --git a/src/execline/execline-cd.c b/src/execline/execline-cd.c
index 8f308f3..80ddec0 100644
--- a/src/execline/execline-cd.c
+++ b/src/execline/execline-cd.c
@@ -1,16 +1,17 @@
 /* ISC license. */
 
 #include <unistd.h>
+
 #include <skalibs/strerr2.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "cd path prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   PROG = "execline-cd" ;
   if (argc < 3) strerr_dieusage(100, USAGE) ;
   if (chdir(argv[1]) == -1)
     strerr_diefu2sys(111, "chdir to ", argv[1]) ;
-  xpathexec_run(argv[2], argv+2, envp) ;
+  xexec(argv+2) ;
 }
diff --git a/src/execline/execline-umask.c b/src/execline/execline-umask.c
index a7888a6..d7eeb5b 100644
--- a/src/execline/execline-umask.c
+++ b/src/execline/execline-umask.c
@@ -1,18 +1,19 @@
 /* ISC license. */
 
 #include <sys/stat.h>
+
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "umask value prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   unsigned int m ;
   PROG = "execline-umask" ;
   if (argc < 3) strerr_dieusage(100, USAGE) ;
   if (!uint_oscan(argv[1], &m)) strerr_dieusage(100, USAGE) ;
   umask(m) ;
-  xpathexec_run(argv[2], argv+2, envp) ;
+  xexec(argv+2) ;
 }
diff --git a/src/execline/execlineb.c b/src/execline/execlineb.c
index 7397be5..5a4bad8 100644
--- a/src/execline/execlineb.c
+++ b/src/execline/execlineb.c
@@ -12,7 +12,9 @@
 #include <skalibs/genalloc.h>
 #include <skalibs/env.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 #include <skalibs/skamisc.h>
+
 #include <execline/execline.h>
 #include "exlsn.h"
 
@@ -111,7 +113,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
     int fd ;
     if (!argc--) strerr_dieusage(100, USAGE) ;
     dollar0 = *argv++ ;
-    fd = open_readb(dollar0) ;
+    fd = openb_read(dollar0) ;
     if (fd < 0) strerr_diefu3sys(111, "open ", dollar0, " for reading") ;
     buffer_init(&b, &fd_readv, fd, buf, BUFFER_INSIZE) ;
     nc = el_parse_from_buffer(&sa, &b) ;
@@ -194,12 +196,12 @@ int main (int argc, char const *const *argv, char const *const *envp)
       if (el_pushenv(&satmp, envp, envlen, list, 11) < 0
        || !env_make(w, envlen, satmp.s, satmp.len))
         goto errenv ;
-      xpathexec_r(v, w, envlen, modif.s, modif.len) ;
+      xmexec_fm(v, w, envlen, modif.s, modif.len) ;
     }
     else if (modif.len)
-      xpathexec_r(v, envp, env_len(envp), modif.s, modif.len) ;
+      xmexec_em(v, envp, modif.s, modif.len) ;
     else
-      xpathexec_run(v[0], v, envp) ;
+      xexec_e(v, envp) ;
   }
  errenv:
   strerr_diefu1sys(111, "update environment") ;  
diff --git a/src/execline/export.c b/src/execline/export.c
index fde3adf..7b306c7 100644
--- a/src/execline/export.c
+++ b/src/execline/export.c
@@ -1,13 +1,13 @@
 /* ISC license. */
 
 #include <string.h>
+
 #include <skalibs/strerr2.h>
-#include <skalibs/env.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "export variable value prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   size_t len1 ;
   PROG = "export" ;
@@ -21,6 +21,6 @@ int main (int argc, char const *const *argv, char const *const *envp)
     memcpy(fmt, argv[1], len1) ;
     fmt[len1] = '=' ;
     memcpy(fmt + len1 + 1, argv[2], len2 + 1) ;
-    xpathexec_r(argv+3, envp, env_len(envp), fmt, len1 + len2 + 2) ;
+    xmexec_n(argv+3, fmt, len1 + len2 + 2, 1) ;
   }
 }
diff --git a/src/execline/fdblock.c b/src/execline/fdblock.c
index 0e912d0..589ab28 100644
--- a/src/execline/fdblock.c
+++ b/src/execline/fdblock.c
@@ -4,10 +4,11 @@
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "fdblock [ -n ] fd prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   unsigned int fd ;
   int block = 1 ;
@@ -29,5 +30,5 @@ int main (int argc, char const *const *argv, char const *const *envp)
   if ((argc < 2) || !uint0_scan(argv[0], &fd)) strerr_dieusage(100, USAGE) ;
   if ((block ? ndelay_off(fd) : ndelay_on(fd)) < 0)
     strerr_diefu1sys(111, block ? "ndelay_off" : "ndelay_on") ;
-  xpathexec_run(argv[1], argv+1, envp) ;
+  xexec(argv+1) ;
 }
diff --git a/src/execline/fdclose.c b/src/execline/fdclose.c
index e74c772..94972f3 100644
--- a/src/execline/fdclose.c
+++ b/src/execline/fdclose.c
@@ -3,14 +3,15 @@
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "fdclose fd prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   unsigned int fd ;
   PROG = "fdclose" ;
   if ((argc < 3) || !uint0_scan(argv[1], &fd)) strerr_dieusage(100, USAGE) ;
   fd_close(fd) ;
-  xpathexec_run(argv[2], argv+2, envp) ;
+  xexec(argv+2) ;
 }
diff --git a/src/execline/fdmove.c b/src/execline/fdmove.c
index 41e2cf1..a9904d0 100644
--- a/src/execline/fdmove.c
+++ b/src/execline/fdmove.c
@@ -4,10 +4,11 @@
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "fdmove [ -c ] to from prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   unsigned int to, from ;
   int flagcopy = 0 ;
@@ -30,5 +31,5 @@ int main (int argc, char const *const *argv, char const *const *envp)
     strerr_dieusage(100, USAGE) ;
   if ((flagcopy ? fd_copy(to, from) : fd_move(to, from)) == -1)
     strerr_diefu4sys(111, "move fd ", argv[1], " to fd ", argv[0]) ;
-  xpathexec_run(argv[2], argv+2, envp) ;
+  xexec(argv+2) ;
 }
diff --git a/src/execline/fdreserve.c b/src/execline/fdreserve.c
index 2c3fc15..f389b32 100644
--- a/src/execline/fdreserve.c
+++ b/src/execline/fdreserve.c
@@ -2,10 +2,11 @@
 
 #include <unistd.h>
 #include <sys/resource.h>
+
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/env.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "fdreserve n prog..."
 
@@ -22,7 +23,7 @@ unsigned int doit (char *modif, unsigned int i, int fd)
   return pos ;
 }
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   unsigned int n ;
   PROG = "fdreserve" ;
@@ -44,7 +45,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
           strerr_diefu1sys(111, "reserve fds") ;
       if (n & 1)
       {
-        int lastfd = open_read("/dev/null") ;
+        int lastfd = openb_read("/dev/null") ;
         if (lastfd < 0)
           strerr_diefu1sys(111, "reserve last fd") ;
         fd_close(lastfd) ;
@@ -58,6 +59,6 @@ int main (int argc, char const *const *argv, char const *const *envp)
         j += doit(modif + j, (i<<1)|1, fd[i][1]) ;
       }
     }
-    xpathexec_r(argv+2, envp, env_len(envp), modif, j) ;
+    xmexec_n(argv+2, modif, j, n) ;
   }
 }
diff --git a/src/execline/fdswap.c b/src/execline/fdswap.c
index 57cf4f6..7a82061 100644
--- a/src/execline/fdswap.c
+++ b/src/execline/fdswap.c
@@ -3,15 +3,16 @@
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "fdswap fd1 fd2 prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   unsigned int fd1, fd2 ;
   PROG = "fdswap" ;
   if ((argc < 4) || !uint0_scan(argv[1], &fd1) || !uint0_scan(argv[2], &fd2))
     strerr_dieusage(100, USAGE) ;
   if (fd_move2(fd1, fd2, fd2, fd1) < 0) strerr_diefu1sys(111, "swap fds") ;
-  xpathexec_run(argv[3], argv+3, envp) ;
+  xexec(argv+3) ;
 }
diff --git a/src/execline/forbacktickx.c b/src/execline/forbacktickx.c
index 3e07442..1f3a0f1 100644
--- a/src/execline/forbacktickx.c
+++ b/src/execline/forbacktickx.c
@@ -3,17 +3,19 @@
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
+
 #include <skalibs/types.h>
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+
 #include <execline/config.h>
 #include <execline/execline.h>
 
 #define USAGE "forbacktickx [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -N | -n ] [ -C | -c ] [ -0 | -d delim ] var { backtickcmd... } command..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   char const *delim = "\n" ;
   char const *codes = 0 ;
@@ -108,6 +110,6 @@ int main (int argc, char const *const *argv, char const *const *envp)
     }
     while (argv[i]) newargv[m++] = argv[i++] ;
     newargv[m++] = 0 ;
-    xpathexec_run(newargv[0], newargv, envp) ;
+    xexec(newargv) ;
   }
 }
diff --git a/src/execline/forstdin.c b/src/execline/forstdin.c
index d57406a..336aaa4 100644
--- a/src/execline/forstdin.c
+++ b/src/execline/forstdin.c
@@ -1,6 +1,5 @@
 /* ISC license. */
 
-#include <sys/types.h>
 #include <string.h>
 #include <errno.h>
 
@@ -129,7 +128,7 @@ int main (int argc, char const **argv, char const *const *envp)
       }
       eofcode = 0 ;
       if (!stralloc_0(&modif)) strerr_diefu1sys(111, "stralloc_0") ;
-      if (!env_merge(newenv, envlen+2, envp, envlen, modif.s, modif.len))
+      if (!env_mergen(newenv, envlen+2, envp, envlen, modif.s, modif.len, 1))
         strerr_diefu1sys(111, "merge environment") ;
       if (pids.s) sig_block(SIGCHLD) ;
       pid = el_spawn0(argv[1], argv + 1, newenv) ;
diff --git a/src/execline/forx.c b/src/execline/forx.c
index 8312704..be03794 100644
--- a/src/execline/forx.c
+++ b/src/execline/forx.c
@@ -1,7 +1,7 @@
 /* ISC license. */
 
-#include <sys/wait.h>
 #include <string.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/bytestr.h>
 #include <skalibs/strerr2.h>
@@ -9,6 +9,7 @@
 #include <skalibs/djbunix.h>
 #include <skalibs/skamisc.h>
 #include <skalibs/types.h>
+
 #include <execline/config.h>
 #include <execline/execline.h>
 
@@ -96,7 +97,7 @@ int main (int argc, char const **argv, char const *const *envp)
       modif[varlen] = '=' ;
       memcpy(modif + varlen + 1, argv[i], vallen) ;
       modif[varlen + vallen + 1] = 0 ;
-      if (!env_merge(newenv, envlen + 2, envp, envlen, modif, varlen + vallen + 2))
+      if (!env_mergen(newenv, envlen + 2, envp, envlen, modif, varlen + vallen + 2, 1))
         strerr_diefu1sys(111, "build new environment") ;
       pid = el_spawn0(argv[argc1+1], argv + argc1 + 1, newenv) ;
       if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1+1]) ;
diff --git a/src/execline/getcwd.c b/src/execline/getcwd.c
index 0548aa8..d41bd5a 100644
--- a/src/execline/getcwd.c
+++ b/src/execline/getcwd.c
@@ -1,14 +1,15 @@
 /* ISC license. */
 
 #include <string.h>
+
 #include <skalibs/strerr2.h>
-#include <skalibs/env.h>
 #include <skalibs/stralloc.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "getcwd variable prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   stralloc sa = STRALLOC_ZERO ;
   PROG = "getcwd" ;
@@ -19,5 +20,5 @@ int main (int argc, char const *const *argv, char const *const *envp)
     strerr_diefu1sys(111, "stralloc_catb") ;
   if (sagetcwd(&sa) < 0) strerr_diefu1sys(111, "getcwd") ;
   if (!stralloc_0(&sa)) strerr_diefu1sys(111, "stralloc_catb") ;
-  xpathexec_r(argv + 2, envp, env_len(envp), sa.s, sa.len) ;
+  xmexec_n(argv + 2, sa.s, sa.len, 1) ;
 }
diff --git a/src/execline/getpid.c b/src/execline/getpid.c
index 0272b16..06c4aaf 100644
--- a/src/execline/getpid.c
+++ b/src/execline/getpid.c
@@ -2,14 +2,14 @@
 
 #include <string.h>
 #include <unistd.h>
+
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/env.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "getpid variable prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   size_t len ;
   PROG = "getpid" ;
@@ -19,10 +19,10 @@ int main (int argc, char const *const *argv, char const *const *envp)
     strerr_dief2x(100, "invalid variable name: ", argv[1]) ;
   {
     size_t i = len+1 ;
-    char fmt[UINT_FMT + len + 2] ;
+    char fmt[PID_FMT + len + 2] ;
     memcpy(fmt, argv[1], len) ;
     fmt[len] = '=' ;
-    i += uint_fmt(fmt+i, getpid()) ; fmt[i++] = 0 ;
-    xpathexec_r(argv+2, envp, env_len(envp), fmt, i) ;
+    i += pid_fmt(fmt+i, getpid()) ; fmt[i++] = 0 ;
+    xmexec_n(argv+2, fmt, i, 1) ;
   }
 }
diff --git a/src/execline/heredoc.c b/src/execline/heredoc.c
index d28d765..15e7ae1 100644
--- a/src/execline/heredoc.c
+++ b/src/execline/heredoc.c
@@ -2,17 +2,19 @@
 
 #include <string.h>
 #include <unistd.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/bytestr.h>
 #include <skalibs/types.h>
 #include <skalibs/allreadwrite.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "heredoc [ -d ] fd string command..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   int df = 0 ;
   PROG = "heredoc" ;
@@ -55,5 +57,5 @@ int main (int argc, char const *const *argv, char const *const *envp)
     if (fd_move(fdr, fd[0]) == -1)
       strerr_diefu2sys(111, "read on fd ", argv[0]) ;
   }
-  xpathexec_run(argv[2], argv+2, envp) ;
+  xexec(argv+2) ;
 }
diff --git a/src/execline/homeof.c b/src/execline/homeof.c
index 40463da..1f4d6eb 100644
--- a/src/execline/homeof.c
+++ b/src/execline/homeof.c
@@ -1,6 +1,5 @@
 /* ISC license. */
 
-#include <sys/types.h>
 #include <pwd.h>
 #include <errno.h>
 #include <skalibs/buffer.h>
diff --git a/src/execline/if.c b/src/execline/if.c
index 037d4a2..a37ecbc 100644
--- a/src/execline/if.c
+++ b/src/execline/if.c
@@ -1,10 +1,13 @@
 /* ISC license. */
 
 #include <sys/wait.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+
 #include <execline/execline.h>
 
 #define USAGE "if [ -n ] [ -X ] [ -t | -x exitcode ] { command... }"
@@ -47,5 +50,5 @@ int main (int argc, char const **argv, char const *const *envp)
     strerr_dief2x(128 + WTERMSIG(wstat), "child crashed with signal ", fmt) ;
   }
   if (not == !wait_estatus(wstat)) return e ;
-  xpathexec0_run(argv+argc1+1, envp) ;
+  xexec0_e(argv+argc1+1, envp) ;
 }
diff --git a/src/execline/ifelse.c b/src/execline/ifelse.c
index eb10feb..6346268 100644
--- a/src/execline/ifelse.c
+++ b/src/execline/ifelse.c
@@ -1,11 +1,13 @@
 /* ISC license. */
 
-#include <sys/types.h>
 #include <sys/wait.h>
+
+#include <skalibs/types.h>
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
-#include <skalibs/types.h>
+#include <skalibs/exec.h>
+
 #include <execline/execline.h>
 
 #define USAGE "ifelse [ -n ] [ -X ] { command-if } { command-then... } command-else..."
@@ -49,5 +51,5 @@ int main (int argc, char const **argv, char const *const *envp)
     strerr_dief2x(128 + WTERMSIG(wstat), "child crashed with signal ", fmt) ;
   }
   if (not != !wait_estatus(wstat)) argv[argc2] = 0 ; else argv += argc2+1 ;
-  xpathexec0_run(argv, envp) ;
+  xexec0_e(argv, envp) ;
 }
diff --git a/src/execline/ifte.c b/src/execline/ifte.c
index 786621c..d263a4a 100644
--- a/src/execline/ifte.c
+++ b/src/execline/ifte.c
@@ -1,10 +1,13 @@
 /* ISC license. */
 
 #include <sys/wait.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+
 #include <execline/execline.h>
 
 #define USAGE "ifte [ -X ] [ -n ] { command-then... } { command-else... } command-if..."
@@ -53,5 +56,5 @@ int main (int argc, char const **argv, char const *const *envp)
     argv[argc2] = 0 ;
   }
   else argv[argc1] = 0 ;
-  xpathexec0_run(argv, envp) ;
+  xexec0_e(argv, envp) ;
 }
diff --git a/src/execline/ifthenelse.c b/src/execline/ifthenelse.c
index f0d75f9..332bc4c 100644
--- a/src/execline/ifthenelse.c
+++ b/src/execline/ifthenelse.c
@@ -1,11 +1,12 @@
 /* ISC license. */
 
-#include <sys/types.h>
 #include <sys/wait.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+
 #include <execline/execline.h>
 
 #define USAGE "ifthenelse [ -X ] { command-if... } { command-then... } { command-else... } [ remainder... ]"
@@ -64,7 +65,7 @@ int main (int argc, char const **argv, char const *const *envp)
       unsigned int i = 0 ;
       for (; remainder[i] ; i++) argv[argc2+i] = remainder[i] ;
       argv[argc2+i] = 0 ;
-      xpathexec0_run(argv, envp) ;
+      xexec0_e(argv, envp) ;
     }
     else
     {
diff --git a/src/execline/loopwhilex.c b/src/execline/loopwhilex.c
index 38ca6e0..93a71e0 100644
--- a/src/execline/loopwhilex.c
+++ b/src/execline/loopwhilex.c
@@ -1,11 +1,10 @@
 /* ISC license. */
 
-#include <sys/types.h>
-#include <sys/wait.h>
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/types.h>
 #include <skalibs/djbunix.h>
+
 #include <execline/execline.h>
 
 #define USAGE "loopwhilex [ -n ] [ -o okcode,okcode,... | -x exitcode,exitcode,... ] prog..."
diff --git a/src/execline/pipeline.c b/src/execline/pipeline.c
index f61c35b..d3e99dd 100644
--- a/src/execline/pipeline.c
+++ b/src/execline/pipeline.c
@@ -1,13 +1,14 @@
 /* ISC license. */
 
-#include <sys/types.h>
 #include <unistd.h>
 #include <errno.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/env.h>
+#include <skalibs/exec.h>
 #include <skalibs/djbunix.h>
+
 #include <execline/execline.h>
 
 #define USAGE "pipeline [ -d ] [ -r | -w ] { command... } command..."
@@ -52,8 +53,7 @@ int main (int argc, char const **argv, char const *const *envp)
           PROG = "pipeline (grandchild)" ;
           fd_close(p[w]) ;
           if (fd_move(!w, p[!w]) < 0) strerr_diefu1sys(111, "fd_move") ;
-          pathexec0_run(argv, envp) ;
-          strerr_dieexec(errno == ENOENT ? 127 : 126, argv[0]) ;
+          xexec0_e(argv, envp) ;
       }
       fd_close(p[!w]) ;
       fd = p[w] ;
@@ -69,7 +69,7 @@ int main (int argc, char const **argv, char const *const *envp)
       char fmt[PID_FMT + 2] = "!=" ;
       size_t i = 2 ;
       i += pid_fmt(fmt+i, pid) ; fmt[i++] = 0 ;
-      xpathexec_r(argv + argc1 + 1, envp, env_len(envp), fmt, i) ;
+      xmexec_en(argv + argc1 + 1, envp, fmt, i, 1) ;
     }
   }
 }
diff --git a/src/execline/piperw.c b/src/execline/piperw.c
index 7f576e5..769fdc8 100644
--- a/src/execline/piperw.c
+++ b/src/execline/piperw.c
@@ -1,13 +1,15 @@
 /* ISC license. */
 
 #include <unistd.h>
+
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "piperw fdr fdw prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   int fdr, fdw ;
   int p[2] ;
@@ -24,5 +26,5 @@ int main (int argc, char const *const *argv, char const *const *envp)
    || (fd_move(fdr, p[0]) == -1)
    || (fd_move(fdw, p[1]) == -1))
     strerr_diefu1sys(111, "move fds") ;
-  xpathexec_run(argv[3], argv+3, envp) ;
+  xexec(argv+3) ;
 }
diff --git a/src/execline/redirfd.c b/src/execline/redirfd.c
index a34eaf7..6801239 100644
--- a/src/execline/redirfd.c
+++ b/src/execline/redirfd.c
@@ -11,7 +11,7 @@
 #define USAGE "redirfd -[ r | w | u | a | x ] [ -n ] [ -b ] fd file prog..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   int fd, fd2 ;
   unsigned int flags = 0 ;
@@ -61,5 +61,5 @@ int main (int argc, char const *const *argv, char const *const *envp)
     if (((flags & O_NONBLOCK) ? ndelay_off(fd) : ndelay_on(fd)) < 0)
       strerr_diefu1sys(111, "change blocking mode") ;
   }
-  xpathexec_run(argv[2], argv+2, envp) ;
+  xexec(argv+2) ;
 }
diff --git a/src/execline/runblock.c b/src/execline/runblock.c
index 330c074..6414415 100644
--- a/src/execline/runblock.c
+++ b/src/execline/runblock.c
@@ -1,6 +1,6 @@
 /* ISC license. */
 
-#include <sys/types.h>
+#include <stdlib.h>
 
 #include <skalibs/sgetopt.h>
 #include <skalibs/types.h>
@@ -44,7 +44,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
   if (!uint0_scan(*argv++, &n) || (!n && !flagr)) dieusage() ;
 
   {
-    char const *x = env_get2(envp, "#") ;
+    char const *x = getenv("#") ;
     if (!x) strerr_dienotset(100, "#") ;
     if (!uint0_scan(x, &sharp)) strerr_dieinvalid(100, "#") ;
   }
@@ -61,7 +61,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
         char fmt[UINT_FMT] ;
         if (++m > sharp) strerr_dief1x(100, "too few arguments") ;
         fmt[uint_fmt(fmt, m)] = 0 ;
-        x = env_get2(envp, fmt) ;
+        x = getenv(fmt) ;
         if (!x) strerr_dienotset(100, fmt) ;
         if ((x[0] == EXECLINE_BLOCK_END_CHAR) && (!EXECLINE_BLOCK_END_CHAR || !x[1])) break ;
         if ((x[0] != EXECLINE_BLOCK_QUOTE_CHAR) && strict)
@@ -96,7 +96,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
       char const *x ;
       char fmt[UINT_FMT] ;
       fmt[uint_fmt(fmt, m)] = 0 ;
-      x = env_get2(envp, fmt) ;
+      x = getenv(fmt) ;
       if (!x) strerr_dienotset(100, fmt) ;
       genalloc_append(char const *, &v, &x) ;
     }
@@ -110,7 +110,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
       char fmt[UINT_FMT] ;
       if (++m > sharp) strerr_dief1x(100, "too few arguments") ;
       fmt[uint_fmt(fmt, m)] = 0 ;
-      x = env_get2(envp, fmt) ;
+      x = getenv(fmt) ;
       if (!x) strerr_dienotset(100, fmt) ;
       if ((x[0] == EXECLINE_BLOCK_END_CHAR) && (!EXECLINE_BLOCK_END_CHAR || !x[1])) break ;
       if (x[0] != EXECLINE_BLOCK_QUOTE_CHAR)
@@ -139,7 +139,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
   }
 
   if (flagnopop)  /* exec now */
-    xpathexec_run(genalloc_s(char const *, &v)[0], genalloc_s(char const *, &v), envp) ;
+    xexec_e(genalloc_s(char const *, &v), envp) ;
   else  /* popenv, then exec */
   {
     char const *list[11] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "#" } ;
@@ -152,7 +152,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
       if (!env_make(w, envlen - popped, satmp.s, satmp.len))
         strerr_diefu1sys(111, "env_make") ;
       w[envlen - popped] = 0 ;
-      xpathexec_run(genalloc_s(char const *, &v)[0], genalloc_s(char const *, &v), w) ;
+      xexec_e(genalloc_s(char const *, &v), w) ;
     }
   }
 }
diff --git a/src/execline/shift.c b/src/execline/shift.c
index 0e1ed39..7c36f5b 100644
--- a/src/execline/shift.c
+++ b/src/execline/shift.c
@@ -1,16 +1,18 @@
 /* ISC license. */
 
+#include <stdlib.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/types.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/env.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+
 #include <execline/execline.h>
 
 #define USAGE "shift [ -n arg# ] [ -b block# ] prog..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   unsigned int strict = el_getstrict() ;
   unsigned int b = 0 ;
@@ -42,7 +44,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
   if (!argc) dieusage() ;
   if (i) i = 0 ; else n = 1 ;
   {
-    char const *x = env_get2(envp, "#") ;
+    char const *x = getenv("#") ;
     if (!x) strerr_dienotset(100, "#") ;
     if (!uint0_scan(x, &sharp)) strerr_dieinvalid(100, "#") ;
   }
@@ -83,7 +85,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
         fmti[uint_fmt(fmt, i)] = 0 ;
         strerr_diefu6x(100, "shift", " block ", fmti, ": too few arguments (", fmt, ")") ;
       }
-      x = env_get2(envp, fmt) ;
+      x = getenv(fmt) ;
       if (!x) strerr_dienotset(100, fmt) ;
       if ((x[0] == EXECLINE_BLOCK_END_CHAR) && (!EXECLINE_BLOCK_END_CHAR || !x[1])) break ;
       if ((x[0] != EXECLINE_BLOCK_QUOTE_CHAR) && strict)
@@ -107,15 +109,15 @@ int main (int argc, char const *const *argv, char const *const *envp)
     unsigned int i = 1 ;
     char fmt[UINT_FMT] ;
     fmt[uint_fmt(fmt, sharp - n)] = 0 ;
-    if (!pathexec_env("#", fmt)) strerr_diefu1sys(111, "pathexec_env") ;
+    if (!env_mexec("#", fmt)) strerr_diefu1sys(111, "env_mexec") ;
     for (; i <= sharp ; i++)
     {
       char fmu[UINT_FMT] ;
       fmt[uint_fmt(fmt, i)] = 0 ;
       fmu[uint_fmt(fmu, i + n)] = 0 ;
-      if (!pathexec_env(fmt, i <= (sharp - n) ? env_get2(envp, fmu) : 0))
+      if (!env_mexec(fmt, i <= (sharp - n) ? getenv(fmu) : 0))
         strerr_diefu1sys(111, "pathexec_env") ;
     }
   }
-  xpathexec(argv) ;
+  xmexec(argv) ;
 }
diff --git a/src/execline/trap.c b/src/execline/trap.c
index 0eec7db..c79698b 100644
--- a/src/execline/trap.c
+++ b/src/execline/trap.c
@@ -37,7 +37,7 @@ static inline void action (unsigned int i, char const *const *envp, size_t envle
       memcpy(modif + m, "SIGNAL=", 7) ; m += 7 ;
       m += uint_fmt(modif + m, i) ;
       modif[m++] = 0 ;
-      if (!env_merge(newenvp, envlen + 3, envp, envlen, modif, m))
+      if (!env_mergen(newenvp, envlen + 3, envp, envlen, modif, m, 2))
         strerr_diefu1sys(111, "adjust environment for child") ;
       pids[i] = child_spawn0(argvs[i][0], argvs[i], newenvp) ;
       if (!pids[i]) strerr_diefu2sys(111, "spawn ", argvs[i][0]) ;
diff --git a/src/execline/tryexec.c b/src/execline/tryexec.c
index f35312f..36e72cd 100644
--- a/src/execline/tryexec.c
+++ b/src/execline/tryexec.c
@@ -1,9 +1,11 @@
 /* ISC license. */
 
 #include <string.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+
 #include <execline/execline.h>
 
 #define USAGE "tryexec [ -n ] [ -c ] [ -l ] [ -a argv0 ] { command... } remainder..."
@@ -54,9 +56,9 @@ int main (int argc, char const **argv, char const *const *envp)
     dashed[0] = '-' ;
     memcpy(dashed+1, dom[0], n+1) ;
     dom[0] = dashed ;
-    pathexec_run(executable, dom, dom_envp) ;
+    exec_ae(executable, dom, dom_envp) ;
   }
-  else pathexec_run(executable, dom, dom_envp) ;
+  else exec_ae(executable, dom, dom_envp) ;
 
-  xpathexec0_run(sub, envp) ;
+  xexec0_e(sub, envp) ;
 }
diff --git a/src/execline/unexport.c b/src/execline/unexport.c
index 0ef46d2..6504a97 100644
--- a/src/execline/unexport.c
+++ b/src/execline/unexport.c
@@ -1,13 +1,14 @@
 /* ISC license. */
 
 #include <string.h>
+
 #include <skalibs/strerr2.h>
 #include <skalibs/env.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "unexport variable prog..."
 
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
 {
   size_t len ;
   PROG = "unexport" ;
@@ -15,5 +16,5 @@ int main (int argc, char const *const *argv, char const *const *envp)
   len = strlen(argv[1]) ;
   if (memchr(argv[1], '=', len))
     strerr_dief2x(100, "invalid variable name: ", argv[1]) ;
-  xpathexec_r(argv+2, envp, env_len(envp), argv[1], len+1) ;
+  xmexec_n(argv+2, argv[1], len+1, 1) ;
 }
diff --git a/src/execline/wait.c b/src/execline/wait.c
index 726cd52..0cf8d03 100644
--- a/src/execline/wait.c
+++ b/src/execline/wait.c
@@ -15,6 +15,7 @@
 #include <skalibs/djbunix.h>
 #include <skalibs/selfpipe.h>
 #include <skalibs/iopause.h>
+#include <skalibs/exec.h>
 
 #include <execline/execline.h>
 
@@ -107,7 +108,7 @@ static inline int mainloop (tain_t *deadline, int insist, actfunc_t_ref f, pid_t
   return res ;
 }
 
-int main (int argc, char const **argv, char const *const *envp)
+int main (int argc, char const **argv)
 {
   tain_t tto ;
   int argc1 ;
@@ -162,5 +163,5 @@ int main (int argc, char const **argv, char const *const *envp)
   }
 
   if (!hasblock) return r ;
-  xpathexec0_run(argv + argc1 + 1, envp) ;
+  xexec0(argv + argc1 + 1) ;
 }
diff --git a/src/execline/withstdinas.c b/src/execline/withstdinas.c
index 2dfcdf4..467b68b 100644
--- a/src/execline/withstdinas.c
+++ b/src/execline/withstdinas.c
@@ -1,18 +1,17 @@
 /* ISC license. */
 
-#include <sys/types.h>
-#include <sys/wait.h>
 #include <string.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/stralloc.h>
-#include <skalibs/env.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "withstdinas [ -i | -I | -D default ] [ -N | -n ] var remainder..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
-int main (int argc, char const **argv, char const *const *envp)
+int main (int argc, char const **argv)
 {
   subgetopt_t localopt = SUBGETOPT_ZERO ;
   stralloc modif = STRALLOC_ZERO ;
@@ -67,6 +66,5 @@ int main (int argc, char const **argv, char const *const *envp)
     if (chomp && (modif.s[modif.len - 2] == '\n'))
       modif.s[--modif.len - 1] = 0 ;
   }
-  if (!argv[1]) return 0 ;
-  xpathexec_r(argv + 1, envp, env_len(envp), modif.s, modif.len) ;
+  xmexec0_n(argv + 1, modif.s, modif.len, 1) ;
 }
diff --git a/src/libexecline/el_execsequence.c b/src/libexecline/el_execsequence.c
index 797aeb5..debf527 100644
--- a/src/libexecline/el_execsequence.c
+++ b/src/libexecline/el_execsequence.c
@@ -3,10 +3,11 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <skalibs/djbunix.h>
-#include <skalibs/env.h>
-#include <skalibs/strerr2.h>
 #include <skalibs/types.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+
 #include <execline/execline.h>
 
 void el_execsequence (char const *const *argv1, char const *const *argv2, char const *const *envp)
@@ -28,6 +29,5 @@ void el_execsequence (char const *const *argv1, char const *const *argv2, char c
     j += uint_fmt(fmt + j, wait_status(wstat)) ;
   }
   fmt[j++] = 0 ;
-  if (!argv2[0]) _exit(0) ;
-  xpathexec_r(argv2, envp, env_len(envp), fmt, j) ;
+  xmexec0_en(argv2, envp, fmt, j, 1) ;
 }
diff --git a/src/libexecline/el_substandrun_str.c b/src/libexecline/el_substandrun_str.c
index 3f6b8e3..5786bc6 100644
--- a/src/libexecline/el_substandrun_str.c
+++ b/src/libexecline/el_substandrun_str.c
@@ -1,11 +1,13 @@
 /* ISC license. */
 
 #include <unistd.h>
-#include <skalibs/djbunix.h>
+
+#include <skalibs/exec.h>
 #include <skalibs/env.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/stralloc.h>
 #include <skalibs/genalloc.h>
+
 #include <execline/execline.h>
 #include "exlsn.h"
 
@@ -20,6 +22,6 @@ void el_substandrun_str (stralloc *src, size_t srcbase, char const *const *envp,
     char const *v[r + 1] ;
     if (!env_make(v, r, dst.s, dst.len)) strerr_diefu1sys(111, "env_make") ;
     v[r] = 0 ;
-    xpathexec_r(v, envp, env_len(envp), info->modifs.s, info->modifs.len) ;
+    xmexec_em(v, envp, info->modifs.s, info->modifs.len) ;
   }
 }
diff --git a/src/posix/posix-cd.c b/src/posix/posix-cd.c
index b4d2005..cbeea5b 100644
--- a/src/posix/posix-cd.c
+++ b/src/posix/posix-cd.c
@@ -91,7 +91,7 @@ int main (int argc, char const **argv, char const *const *envp)
     size_t sabase = sa.len ;
     if (sagetcwd(&sa) < 0) strerr_diefu1sys(111, "getcwd") ;
     if (!stralloc_0(&sa)) dienomem() ;
-    if (!pathexec_env("OLDPWD", sa.s + sabase)) dienomem() ;
+    if (!env_mexec("OLDPWD", sa.s + sabase)) dienomem() ;
     sa.len = sabase ;
   }
 
@@ -114,7 +114,7 @@ int main (int argc, char const **argv, char const *const *envp)
       stralloc_free(&sa) ;
       sa = tmp ;
     }
-    if (!pathexec_env("PWD", sa.s)) dienomem() ;
+    if (!env_mexec("PWD", sa.s)) dienomem() ;
 #ifdef PATH_MAX
     if (sa.len > PATH_MAX && strlen(where) < PATH_MAX && x && *x)
     {
@@ -144,7 +144,7 @@ int main (int argc, char const **argv, char const *const *envp)
     sa.len = 0 ;
     if (sagetcwd(&sa) < 0) strerr_diefu1sys(111, "getcwd") ;
     if (!stralloc_0(&sa)) dienomem() ;
-    if (!pathexec_env("PWD", sa.s)) dienomem() ;
+    if (!env_mexec("PWD", sa.s)) dienomem() ;
   }
   
   if (dopwd)
@@ -154,5 +154,5 @@ int main (int argc, char const **argv, char const *const *envp)
       strerr_diefu1sys(111, "write to stdout") ;
   }
 
-  xpathexec0(argv) ;
+  xmexec0(argv) ;
 }
diff --git a/src/posix/posix-umask.c b/src/posix/posix-umask.c
index b4b9b4b..16d7f4f 100644
--- a/src/posix/posix-umask.c
+++ b/src/posix/posix-umask.c
@@ -10,7 +10,7 @@
 #include <skalibs/sgetopt.h>
 #include <skalibs/buffer.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
 
 #define USAGE "posix-umask [ -S ] [ mask ] [ prog... ]"
 #define dieusage() strerr_dieusage(100, USAGE)
@@ -146,7 +146,7 @@ static inline unsigned int parsemode (char const *s)
   return ((unsigned int)modes[2] << 6) | ((unsigned int)modes[1] << 3) | modes[0] ;
 }
 
-int main (int argc, char const **argv, char const *const *envp)
+int main (int argc, char const **argv)
 {
   int sym = 0 ;
   unsigned int mode ;
@@ -170,5 +170,5 @@ int main (int argc, char const **argv, char const *const *envp)
   if (!argc) return output(sym) ;
   if (!uint0_oscan(argv[0], &mode)) mode = ~parsemode(argv[0]) ;
   umask(mode & 00777) ;
-  xpathexec0_run(argv+1, envp) ;
+  xexec0(argv+1) ;
 }