about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2024-04-30 19:09:43 +0000
committerLaurent Bercot <ska@appnovation.com>2024-04-30 19:09:43 +0000
commit02926ee3447b1ea0d04b53b8fcb08d8b1a4deec5 (patch)
treef0cffb716e9ba61382795b460203df506e13ed4b
parent944a9d260a41b30f32730ccb12b3f5dafb507b7d (diff)
downloadskalibs-02926ee3447b1ea0d04b53b8fcb08d8b1a4deec5.tar.gz
skalibs-02926ee3447b1ea0d04b53b8fcb08d8b1a4deec5.tar.xz
skalibs-02926ee3447b1ea0d04b53b8fcb08d8b1a4deec5.zip
Add mspawn functions to cspawn.h; move everything to libenvexec
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--Makefile4
-rw-r--r--package/deps.mak26
-rw-r--r--src/include/skalibs/cspawn.h55
-rw-r--r--src/include/skalibs/env.h4
-rw-r--r--src/include/skalibs/stddjb.h2
-rw-r--r--src/libenvexec/child_spawn.c (renamed from src/libstddjb/child_spawn.c)0
-rw-r--r--src/libenvexec/child_spawn0.c (renamed from src/libstddjb/child_spawn0.c)0
-rw-r--r--src/libenvexec/child_spawn1_internal.c (renamed from src/libstddjb/child_spawn1_internal.c)0
-rw-r--r--src/libenvexec/child_spawn1_pipe.c (renamed from src/libstddjb/child_spawn1_pipe.c)0
-rw-r--r--src/libenvexec/child_spawn1_socket.c (renamed from src/libstddjb/child_spawn1_socket.c)0
-rw-r--r--src/libenvexec/child_spawn2.c (renamed from src/libstddjb/child_spawn2.c)0
-rw-r--r--src/libenvexec/child_spawn3.c (renamed from src/libstddjb/child_spawn3.c)0
-rw-r--r--src/libenvexec/cspawn-internal.h (renamed from src/libstddjb/cspawn-internal.h)0
-rw-r--r--src/libenvexec/cspawn.c (renamed from src/libstddjb/cspawn.c)0
-rw-r--r--src/libenvexec/env_merge.c24
-rw-r--r--src/libenvexec/env_mergen.c31
-rw-r--r--src/libenvexec/gcspawn.c (renamed from src/libstddjb/gcspawn.c)0
-rw-r--r--src/libenvexec/gmspawn_afn.c11
-rw-r--r--src/libenvexec/mspawn_af.c17
-rw-r--r--src/libenvexec/mspawn_afm.c9
-rw-r--r--src/libenvexec/mspawn_afn.c11
-rw-r--r--src/libenvexec/xmspawn_af.c13
-rw-r--r--src/libenvexec/xmspawn_afm.c13
-rw-r--r--src/libenvexec/xmspawn_afn.c13
24 files changed, 185 insertions, 48 deletions
diff --git a/Makefile b/Makefile
index 812438e..278ee88 100644
--- a/Makefile
+++ b/Makefile
@@ -12,8 +12,6 @@ ifeq "" "$(strip $(filter $(make_need), $(firstword $(sort $(make_need) $(MAKE_V
 $(error Your make ($(MAKE_VERSION)) is too old. You need $(make_need) or newer)
 endif
 
-CC = $(error Please use ./configure first)
-
 -include config.mak
 include package/deps.mak
 
@@ -52,7 +50,7 @@ ALL_INCLUDES := $(sort $(BUILT_INCLUDES) $(wildcard src/include/$(package)/*.h))
 ALL_SYSDEPS := $(wildcard $(sysdeps)/*)
 ALL_DATA := $(wildcard src/etc/*)
 
-all: $(ALL_LIBS) $(ALL_INCLUDES) $(ALL_SYSDEPS) $(ALL_DATA)
+all: config.mak $(ALL_LIBS) $(ALL_INCLUDES) $(ALL_SYSDEPS) $(ALL_DATA)
 
 clean:
 	@exec rm -f $(ALL_LIBS) $(ALL_BINS) $(ALL_SOBJS) $(ALL_DOBJS) $(BUILT_INCLUDES)
diff --git a/package/deps.mak b/package/deps.mak
index bec13ce..4d420c5 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -115,6 +115,14 @@ src/libdatastruct/gensetdyn_iter_withcancel.o src/libdatastruct/gensetdyn_iter_w
 src/libdatastruct/gensetdyn_new.o src/libdatastruct/gensetdyn_new.lo: src/libdatastruct/gensetdyn_new.c src/include/skalibs/genalloc.h src/include/skalibs/gensetdyn.h
 src/libdatastruct/gensetdyn_ready.o src/libdatastruct/gensetdyn_ready.lo: src/libdatastruct/gensetdyn_ready.c src/include/skalibs/genalloc.h src/include/skalibs/gensetdyn.h src/include/skalibs/stralloc.h
 src/libdatastruct/gensetdyn_zero.o src/libdatastruct/gensetdyn_zero.lo: src/libdatastruct/gensetdyn_zero.c src/include/skalibs/gensetdyn.h
+src/libenvexec/child_spawn.o src/libenvexec/child_spawn.lo: src/libenvexec/child_spawn.c src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/types.h
+src/libenvexec/child_spawn0.o src/libenvexec/child_spawn0.lo: src/libenvexec/child_spawn0.c src/include/skalibs/cspawn.h
+src/libenvexec/child_spawn1_internal.o src/libenvexec/child_spawn1_internal.lo: src/libenvexec/child_spawn1_internal.c src/libenvexec/cspawn-internal.h src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h
+src/libenvexec/child_spawn1_pipe.o src/libenvexec/child_spawn1_pipe.lo: src/libenvexec/child_spawn1_pipe.c src/libenvexec/cspawn-internal.h src/include/skalibs/cspawn.h
+src/libenvexec/child_spawn1_socket.o src/libenvexec/child_spawn1_socket.lo: src/libenvexec/child_spawn1_socket.c src/libenvexec/cspawn-internal.h src/include/skalibs/cspawn.h src/include/skalibs/socket.h
+src/libenvexec/child_spawn2.o src/libenvexec/child_spawn2.lo: src/libenvexec/child_spawn2.c src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h
+src/libenvexec/child_spawn3.o src/libenvexec/child_spawn3.lo: src/libenvexec/child_spawn3.c src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/types.h
+src/libenvexec/cspawn.o src/libenvexec/cspawn.lo: src/libenvexec/cspawn.c src/include/skalibs/allreadwrite.h src/include/skalibs/config.h src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/exec.h src/include/skalibs/nonposix.h src/include/skalibs/selfpipe.h src/include/skalibs/sig.h src/include/skalibs/sysdeps.h
 src/libenvexec/env_addmodif.o src/libenvexec/env_addmodif.lo: src/libenvexec/env_addmodif.c src/include/skalibs/env.h src/include/skalibs/stralloc.h
 src/libenvexec/env_dump.o src/libenvexec/env_dump.lo: src/libenvexec/env_dump.c src/include/skalibs/bytestr.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/nonposix.h src/include/skalibs/unix-transactional.h
 src/libenvexec/env_get.o src/libenvexec/env_get.lo: src/libenvexec/env_get.c src/include/skalibs/posixplz.h
@@ -123,7 +131,6 @@ src/libenvexec/env_len.o src/libenvexec/env_len.lo: src/libenvexec/env_len.c src
 src/libenvexec/env_make.o src/libenvexec/env_make.lo: src/libenvexec/env_make.c src/include/skalibs/env.h
 src/libenvexec/env_merg.o src/libenvexec/env_merg.lo: src/libenvexec/env_merg.c src/include/skalibs/env.h
 src/libenvexec/env_merge.o src/libenvexec/env_merge.lo: src/libenvexec/env_merge.c src/include/skalibs/bytestr.h src/include/skalibs/env.h
-src/libenvexec/env_mergen.o src/libenvexec/env_mergen.lo: src/libenvexec/env_mergen.c src/include/skalibs/bytestr.h src/include/skalibs/env.h
 src/libenvexec/env_mergn.o src/libenvexec/env_mergn.lo: src/libenvexec/env_mergn.c src/include/skalibs/env.h
 src/libenvexec/env_string.o src/libenvexec/env_string.lo: src/libenvexec/env_string.c src/include/skalibs/env.h src/include/skalibs/stralloc.h
 src/libenvexec/envalloc_0.o src/libenvexec/envalloc_0.lo: src/libenvexec/envalloc_0.c src/include/skalibs/envalloc.h src/include/skalibs/genalloc.h
@@ -135,12 +142,17 @@ src/libenvexec/envdir_clamp.o src/libenvexec/envdir_clamp.lo: src/libenvexec/env
 src/libenvexec/envdir_noclamp.o src/libenvexec/envdir_noclamp.lo: src/libenvexec/envdir_noclamp.c src/include/skalibs/buffer.h src/include/skalibs/bytestr.h src/include/skalibs/direntry.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/libenvexec/envdir-internal.h src/include/skalibs/skamisc.h src/include/skalibs/stralloc.h
 src/libenvexec/exec0_ae.o src/libenvexec/exec0_ae.lo: src/libenvexec/exec0_ae.c src/include/skalibs/exec.h
 src/libenvexec/exec_ae.o src/libenvexec/exec_ae.lo: src/libenvexec/exec_ae.c src/include/skalibs/config.h src/include/skalibs/exec.h src/include/skalibs/posixplz.h
+src/libenvexec/gcspawn.o src/libenvexec/gcspawn.lo: src/libenvexec/gcspawn.c src/include/skalibs/allreadwrite.h src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/types.h
+src/libenvexec/gmspawn_afn.o src/libenvexec/gmspawn_afn.lo: src/libenvexec/gmspawn_afn.c src/include/skalibs/cspawn.h src/include/skalibs/env.h
 src/libenvexec/mexec0_af.o src/libenvexec/mexec0_af.lo: src/libenvexec/mexec0_af.c src/include/skalibs/exec.h
 src/libenvexec/mexec0_afm.o src/libenvexec/mexec0_afm.lo: src/libenvexec/mexec0_afm.c src/include/skalibs/exec.h
 src/libenvexec/mexec0_afn.o src/libenvexec/mexec0_afn.lo: src/libenvexec/mexec0_afn.c src/include/skalibs/exec.h
 src/libenvexec/mexec_af.o src/libenvexec/mexec_af.lo: src/libenvexec/mexec_af.c src/include/skalibs/env.h src/include/skalibs/exec.h src/include/skalibs/stralloc.h
 src/libenvexec/mexec_afm.o src/libenvexec/mexec_afm.lo: src/libenvexec/mexec_afm.c src/include/skalibs/bytestr.h src/include/skalibs/exec.h
 src/libenvexec/mexec_afn.o src/libenvexec/mexec_afn.lo: src/libenvexec/mexec_afn.c src/include/skalibs/env.h src/include/skalibs/exec.h
+src/libenvexec/mspawn_af.o src/libenvexec/mspawn_af.lo: src/libenvexec/mspawn_af.c src/include/skalibs/cspawn.h src/include/skalibs/env.h src/include/skalibs/stralloc.h
+src/libenvexec/mspawn_afm.o src/libenvexec/mspawn_afm.lo: src/libenvexec/mspawn_afm.c src/include/skalibs/bytestr.h src/include/skalibs/cspawn.h
+src/libenvexec/mspawn_afn.o src/libenvexec/mspawn_afn.lo: src/libenvexec/mspawn_afn.c src/include/skalibs/cspawn.h src/include/skalibs/env.h
 src/libenvexec/xexec0_ae.o src/libenvexec/xexec0_ae.lo: src/libenvexec/xexec0_ae.c src/include/skalibs/exec.h
 src/libenvexec/xexec_ae.o src/libenvexec/xexec_ae.lo: src/libenvexec/xexec_ae.c src/include/skalibs/exec.h src/include/skalibs/strerr.h
 src/libenvexec/xexecvep.o src/libenvexec/xexecvep.lo: src/libenvexec/xexecvep.c src/include/skalibs/exec.h src/include/skalibs/posixplz.h src/include/skalibs/strerr.h
@@ -151,6 +163,9 @@ src/libenvexec/xmexec0_afn.o src/libenvexec/xmexec0_afn.lo: src/libenvexec/xmexe
 src/libenvexec/xmexec_af.o src/libenvexec/xmexec_af.lo: src/libenvexec/xmexec_af.c src/include/skalibs/exec.h src/include/skalibs/strerr.h
 src/libenvexec/xmexec_afm.o src/libenvexec/xmexec_afm.lo: src/libenvexec/xmexec_afm.c src/include/skalibs/exec.h src/include/skalibs/strerr.h
 src/libenvexec/xmexec_afn.o src/libenvexec/xmexec_afn.lo: src/libenvexec/xmexec_afn.c src/include/skalibs/exec.h src/include/skalibs/strerr.h
+src/libenvexec/xmspawn_af.o src/libenvexec/xmspawn_af.lo: src/libenvexec/xmspawn_af.c src/include/skalibs/cspawn.h src/include/skalibs/strerr.h
+src/libenvexec/xmspawn_afm.o src/libenvexec/xmspawn_afm.lo: src/libenvexec/xmspawn_afm.c src/include/skalibs/cspawn.h src/include/skalibs/strerr.h
+src/libenvexec/xmspawn_afn.o src/libenvexec/xmspawn_afn.lo: src/libenvexec/xmspawn_afn.c src/include/skalibs/cspawn.h src/include/skalibs/strerr.h
 src/libposixplz/doublefork.o src/libposixplz/doublefork.lo: src/libposixplz/doublefork.c src/include/skalibs/allreadwrite.h src/include/skalibs/djbunix.h src/include/skalibs/posixplz.h src/include/skalibs/uint64.h
 src/libposixplz/execvep.o src/libposixplz/execvep.lo: src/libposixplz/execvep.c src/libposixplz/posixplz-internal.h src/include/skalibs/posixplz.h
 src/libposixplz/execvep_internal.o src/libposixplz/execvep_internal.lo: src/libposixplz/execvep_internal.c src/include/skalibs/bytestr.h src/include/skalibs/posixplz.h
@@ -304,15 +319,7 @@ src/libstddjb/cdbmake_addv.o src/libstddjb/cdbmake_addv.lo: src/libstddjb/cdbmak
 src/libstddjb/cdbmake_finish.o src/libstddjb/cdbmake_finish.lo: src/libstddjb/cdbmake_finish.c src/include/skalibs/buffer.h src/libstddjb/cdbmake-internal.h src/include/skalibs/cdbmake.h src/include/skalibs/diuint32.h src/include/skalibs/genalloc.h src/include/skalibs/uint32.h
 src/libstddjb/cdbmake_posplus.o src/libstddjb/cdbmake_posplus.lo: src/libstddjb/cdbmake_posplus.c src/libstddjb/cdbmake-internal.h
 src/libstddjb/cdbmake_start.o src/libstddjb/cdbmake_start.lo: src/libstddjb/cdbmake_start.c src/include/skalibs/buffer.h src/include/skalibs/cdbmake.h src/include/skalibs/genalloc.h
-src/libstddjb/child_spawn.o src/libstddjb/child_spawn.lo: src/libstddjb/child_spawn.c src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/types.h
-src/libstddjb/child_spawn0.o src/libstddjb/child_spawn0.lo: src/libstddjb/child_spawn0.c src/include/skalibs/cspawn.h
-src/libstddjb/child_spawn1_internal.o src/libstddjb/child_spawn1_internal.lo: src/libstddjb/child_spawn1_internal.c src/libstddjb/cspawn-internal.h src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h
-src/libstddjb/child_spawn1_pipe.o src/libstddjb/child_spawn1_pipe.lo: src/libstddjb/child_spawn1_pipe.c src/libstddjb/cspawn-internal.h src/include/skalibs/cspawn.h
-src/libstddjb/child_spawn1_socket.o src/libstddjb/child_spawn1_socket.lo: src/libstddjb/child_spawn1_socket.c src/libstddjb/cspawn-internal.h src/include/skalibs/cspawn.h src/include/skalibs/socket.h
-src/libstddjb/child_spawn2.o src/libstddjb/child_spawn2.lo: src/libstddjb/child_spawn2.c src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h
-src/libstddjb/child_spawn3.o src/libstddjb/child_spawn3.lo: src/libstddjb/child_spawn3.c src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/types.h
 src/libstddjb/coe.o src/libstddjb/coe.lo: src/libstddjb/coe.c src/include/skalibs/djbunix.h src/include/skalibs/fcntl.h
-src/libstddjb/cspawn.o src/libstddjb/cspawn.lo: src/libstddjb/cspawn.c src/include/skalibs/allreadwrite.h src/include/skalibs/config.h src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/exec.h src/include/skalibs/nonposix.h src/include/skalibs/selfpipe.h src/include/skalibs/sig.h src/include/skalibs/sysdeps.h
 src/libstddjb/deepsleepuntil.o src/libstddjb/deepsleepuntil.lo: src/libstddjb/deepsleepuntil.c src/include/skalibs/iopause.h src/include/skalibs/tai.h
 src/libstddjb/devino_cmp.o src/libstddjb/devino_cmp.lo: src/libstddjb/devino_cmp.c src/include/skalibs/devino.h
 src/libstddjb/dir_close.o src/libstddjb/dir_close.lo: src/libstddjb/dir_close.c src/include/skalibs/direntry.h
@@ -345,7 +352,6 @@ src/libstddjb/filecopy_suffix.o src/libstddjb/filecopy_suffix.lo: src/libstddjb/
 src/libstddjb/filecopy_unsafe.o src/libstddjb/filecopy_unsafe.lo: src/libstddjb/filecopy_unsafe.c src/include/skalibs/djbunix.h src/include/skalibs/fcntl.h
 src/libstddjb/fmtscan_asc.o src/libstddjb/fmtscan_asc.lo: src/libstddjb/fmtscan_asc.c src/include/skalibs/fmtscan.h
 src/libstddjb/fmtscan_num.o src/libstddjb/fmtscan_num.lo: src/libstddjb/fmtscan_num.c src/include/skalibs/fmtscan.h
-src/libstddjb/gcspawn.o src/libstddjb/gcspawn.lo: src/libstddjb/gcspawn.c src/include/skalibs/allreadwrite.h src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/types.h
 src/libstddjb/genalloc_deepfree.o src/libstddjb/genalloc_deepfree.lo: src/libstddjb/genalloc_deepfree.c src/include/skalibs/genalloc.h src/include/skalibs/stralloc.h
 src/libstddjb/genwrite_flush_bufalloc.o src/libstddjb/genwrite_flush_bufalloc.lo: src/libstddjb/genwrite_flush_bufalloc.c src/include/skalibs/bufalloc.h src/include/skalibs/genwrite.h
 src/libstddjb/genwrite_flush_buffer.o src/libstddjb/genwrite_flush_buffer.lo: src/libstddjb/genwrite_flush_buffer.c src/include/skalibs/buffer.h src/include/skalibs/genwrite.h
diff --git a/src/include/skalibs/cspawn.h b/src/include/skalibs/cspawn.h
index 061fbfb..0d8dd50 100644
--- a/src/include/skalibs/cspawn.h
+++ b/src/include/skalibs/cspawn.h
@@ -90,4 +90,59 @@ extern pid_t child_spawn (char const *, char const *const *, char const *const *
 
 extern pid_t gcspawn (char const *, char const *const *, char const *const *, uint16_t, cspawn_fileaction const *, size_t) ;
 
+
+ /* mexec (see skalibs/exec.h), but with cspawn instead */
+
+extern int env_mspawn (char const *, char const *) ;
+
+extern pid_t mspawn_afn (char const *, char const *const *, char const *const *, size_t, char const *, size_t, size_t, uint16_t, cspawn_fileaction const *, size_t) ;
+extern pid_t mspawn_afm (char const *, char const *const *, char const *const *, size_t, char const *, size_t, uint16_t, cspawn_fileaction const *, size_t) ;
+extern pid_t mspawn_af (char const *, char const *const *, char const *const *, size_t, uint16_t, cspawn_fileaction const *, size_t) ;
+
+#define mspawn_aen(file, argv, envp, modif, modiflen, modifn, flags, fa, n) mspawn_afn(file, argv, envp, env_len(envp), modif, modiflen, modifn, flags, fa, n)
+#define mspawn_aem(file, argv, envp, modif, modiflen, flags, fa, n) mspawn_afm(file, argv, envp, env_len(envp), modif, modiflen, flags, fa, n)
+#define mspawn_ae(file, argv, envp, flags, fa, n) mspawn_af(file, argv, (envp), env_len(envp), flags, fa, n)
+
+#define mspawn_an(file, argv, modif, modiflen, modifn, flags, fa, n) mspawn_aen(file, argv, (char const *const *)environ, modif, modiflen, modifn, flags, fa, n)
+#define mspawn_am(file, argv, modif, modiflen, flags, fa, n) mspawn_aem(file, argv, (char const *const *)environ, modif, modiflen, flaga, fa, n)
+#define mspawn_a(file, argv, flags, fa, n) mspawn_ae(file, (argv), (char const *const *)environ, flags, fa, n)
+
+#define mspawn_fn(argv, envp, envlen, modif, modiflen, modifn, flags, fa, n) mspawn_afn((argv)[0], (argv), envp, envlen, modif, modiflen, modifn, flags, fa, n)
+#define mspawn_fm(argv, envp, envlen, modif, modiflen, flags, fa, n) mspawn_afm((argv)[0], (argv), envp, envlen, modif, modiflen, flags, fa, n)
+#define mspawn_f(argv, envp, envlen, flags, fa, n) mspawn_af((argv)[0], (argv), envp, envlen, flags, fa, n)
+
+#define mspawn_en(argv, envp, modif, modiflen, modifn, flags, fa, n) mspawn_aen((argv)[0], (argv), envp, modif, modiflen, modifn, flags, fa, n)
+#define mspawn_em(argv, envp, modif, modiflen, flags, fa, n) mspawn_aem((argv)[0], (argv), envp, modif, modiflen, flags, fa, n)
+#define mspawn_e(argv, envp, flags, fa, n) mspawn_ae((argv)[0], (argv), envp, flags, fa, n)
+
+#define mspawn_n(argv, modif, modiflen, modifn, flags, fa, n) mspawn_an((argv)[0], (argv), modif, modiflen, modifn, flags, fa, n)
+#define mspawn_m(argv, modif, modiflen, flags, fa, n) mspawn_am((argv)[0], (argv), modif, modiflen, flags, fa, n)
+#define mspawn(argv, flags, fa, n) mspawn_a((argv)[0], (argv), flags, fa, n)
+
+extern pid_t xmspawn_afn (char const *, char const *const *, char const *const *, size_t, char const *, size_t, size_t, uint16_t, cspawn_fileaction const *, size_t) ;
+extern pid_t xmspawn_afm (char const *, char const *const *, char const *const *, size_t, char const *, size_t, uint16_t, cspawn_fileaction const *, size_t) ;
+extern pid_t xmspawn_af (char const *, char const *const *, char const *const *, size_t, uint16_t, cspawn_fileaction const *, size_t) ;
+
+#define xmspawn_aen(file, argv, envp, modif, modiflen, modifn, flags, fa, n) xmspawn_afn(file, argv, envp, env_len(envp), modif, modiflen, modifn, flags, fa, n)
+#define xmspawn_aem(file, argv, envp, modif, modiflen, flags, fa, n) xmspawn_afm(file, argv, envp, env_len(envp), modif, modiflen, flags, fa, n)
+#define xmspawn_ae(file, argv, envp, flags, fa, n) xmspawn_af(file, argv, envp, env_len(envp), flags, fa, n)
+
+#define xmspawn_an(file, argv, modif, modiflen, modifn, flags, fa, n) xmspawn_aen(file, argv, (char const *const *)environ, modif, modiflen, modifn, flags, fa, n)
+#define xmspawn_am(file, argv, modif, modiflen, flags, fa, n) xmspawn_aem(file, argv, (char const *const *)environ, modif, modiflen, flags, fa, n)
+#define xmspawn_a(file, argv, flags, fa, n) xmspawn_ae(file, argv, (char const *const *)environ, flags, fa, n)
+
+#define xmspawn_fn(argv, envp, envlen, modif, modiflen, modifn, flags, fa, n) xmspawn_afn((argv)[0], (argv), envp, envlen, modif, modiflen, modifn, flags, fa, n)
+#define xmspawn_fm(argv, envp, envlen, modif, modiflen, flags, fa, n) xmspawn_afm((argv)[0], (argv), envp, envlen, modif, modiflen, flags, fa, n)
+#define xmspawn_f(argv, envp, envlen, flags, fa, n) xmspawn_af((argv)[0], (argv), envp, envlen, flags, fa, n)
+
+#define xmspawn_en(argv, envp, modif, modiflen, modifn, flags, fa, n) xmspawn_aen((argv)[0], (argv), envp, modif, modiflen, modifn, flags, fa, n)
+#define xmspawn_em(argv, envp, modif, modiflen, flags, fa, n) xmspawn_aem((argv)[0], (argv), envp, modif, modiflen, flags, fa, n)
+#define xmspawn_e(argv, envp, flags, fa, n) xmspawn_ae((argv)[0], (argv), envp, flags, fa, n)
+
+#define xmspawn_n(argv, modif, modiflen, modifn, flags, fa, n) xmspawn_an((argv)[0], (argv), modif, modiflen, modifn, flags, fa, n)
+#define xmspawn_m(argv, modif, modiflen, flags, fa, n) xmspawn_am((argv)[0], (argv), modif, modiflen, flags, fa, n)
+#define xmspawn(argv, flags, fa, n) xmspawn_a((argv)[0], (argv), flags, fa, n)
+
+extern pid_t gmspawn_afn (char const *, char const *const *, char const *const *, size_t, char const *, size_t, size_t, uint16_t, cspawn_fileaction const *, size_t) ;
+
 #endif
diff --git a/src/include/skalibs/env.h b/src/include/skalibs/env.h
index 5e17dfa..e5dfd1d 100644
--- a/src/include/skalibs/env.h
+++ b/src/include/skalibs/env.h
@@ -17,10 +17,10 @@ extern int env_addmodif (stralloc *, char const *, char const *) ;
 extern int env_make (char const **, size_t, char const *, size_t) ;
 extern int env_string (stralloc *, char const *const *, size_t) ;
 
-extern size_t env_mergen (char const **, size_t, char const *const *, size_t, char const *, size_t, size_t) ;
+extern size_t env_merg (char const **, size_t, char const *const *, char const *, size_t) ;
 extern size_t env_merge (char const **, size_t, char const *const *, size_t, char const *, size_t) ;
+#define env_mergen(v, vmax, envp, envlen, modifs, modiflen, modifn) env_merge(v, vmax, envp, envlen, modifs, modiflen)
 extern size_t env_mergn (char const **, size_t, char const *const *, char const *, size_t, size_t) ;
-extern size_t env_merg (char const **, size_t, char const *const *, char const *, size_t) ;
 
 #define SKALIBS_ENVDIR_VERBATIM 0x01
 #define SKALIBS_ENVDIR_NOCHOMP 0x02
diff --git a/src/include/skalibs/stddjb.h b/src/include/skalibs/stddjb.h
index d241de8..ab5bcaf 100644
--- a/src/include/skalibs/stddjb.h
+++ b/src/include/skalibs/stddjb.h
@@ -20,7 +20,6 @@
 #include <skalibs/cbuffer.h>
 #include <skalibs/cdb.h>
 #include <skalibs/cdbmake.h>
-#include <skalibs/cspawn.h>
 #include <skalibs/devino.h>
 #include <skalibs/direntry.h>
 #include <skalibs/diuint32.h>
@@ -31,6 +30,7 @@
 #include <skalibs/envalloc.h>
 #include <skalibs/env.h>
 #include <skalibs/exec.h>
+#include <skalibs/cspawn.h>
 #include <skalibs/fmtscan.h>
 #include <skalibs/functypes.h>
 #include <skalibs/gccattributes.h>
diff --git a/src/libstddjb/child_spawn.c b/src/libenvexec/child_spawn.c
index 164f1b2..164f1b2 100644
--- a/src/libstddjb/child_spawn.c
+++ b/src/libenvexec/child_spawn.c
diff --git a/src/libstddjb/child_spawn0.c b/src/libenvexec/child_spawn0.c
index b1353b6..b1353b6 100644
--- a/src/libstddjb/child_spawn0.c
+++ b/src/libenvexec/child_spawn0.c
diff --git a/src/libstddjb/child_spawn1_internal.c b/src/libenvexec/child_spawn1_internal.c
index e65b588..e65b588 100644
--- a/src/libstddjb/child_spawn1_internal.c
+++ b/src/libenvexec/child_spawn1_internal.c
diff --git a/src/libstddjb/child_spawn1_pipe.c b/src/libenvexec/child_spawn1_pipe.c
index a31e091..a31e091 100644
--- a/src/libstddjb/child_spawn1_pipe.c
+++ b/src/libenvexec/child_spawn1_pipe.c
diff --git a/src/libstddjb/child_spawn1_socket.c b/src/libenvexec/child_spawn1_socket.c
index 684842e..684842e 100644
--- a/src/libstddjb/child_spawn1_socket.c
+++ b/src/libenvexec/child_spawn1_socket.c
diff --git a/src/libstddjb/child_spawn2.c b/src/libenvexec/child_spawn2.c
index f287c0b..f287c0b 100644
--- a/src/libstddjb/child_spawn2.c
+++ b/src/libenvexec/child_spawn2.c
diff --git a/src/libstddjb/child_spawn3.c b/src/libenvexec/child_spawn3.c
index 75551d2..75551d2 100644
--- a/src/libstddjb/child_spawn3.c
+++ b/src/libenvexec/child_spawn3.c
diff --git a/src/libstddjb/cspawn-internal.h b/src/libenvexec/cspawn-internal.h
index 0e5efc7..0e5efc7 100644
--- a/src/libstddjb/cspawn-internal.h
+++ b/src/libenvexec/cspawn-internal.h
diff --git a/src/libstddjb/cspawn.c b/src/libenvexec/cspawn.c
index 683a0a3..683a0a3 100644
--- a/src/libstddjb/cspawn.c
+++ b/src/libenvexec/cspawn.c
diff --git a/src/libenvexec/env_merge.c b/src/libenvexec/env_merge.c
index ac3e17c..b6281ee 100644
--- a/src/libenvexec/env_merge.c
+++ b/src/libenvexec/env_merge.c
@@ -1,9 +1,31 @@
 /* ISC license. */
 
+#include <string.h>
+#include <errno.h>
+
 #include <skalibs/bytestr.h>
 #include <skalibs/env.h>
 
 size_t env_merge (char const **v, size_t vmax, char const *const *envp, size_t envlen, char const *modifs, size_t modiflen)
 {
-  return env_mergen(v, vmax, envp, envlen, modifs, modiflen, byte_count(modifs, modiflen, '\0')) ;
+  size_t vlen = envlen ;
+  size_t i = 0 ;
+  if (envlen >= vmax) return 0 ;
+  for (; i < envlen ; i++) v[i] = envp[i] ;
+  for (i = 0 ; i < modiflen ; i += strlen(modifs + i) + 1)
+  {
+    size_t split = str_chr(modifs + i, '=') ;
+    size_t j = 0 ;
+    for (; j < vlen ; j++)
+      if (!strncmp(modifs + i, v[j], split) && (v[j][split] == '=')) break ;
+    if (j < vlen) v[j] = v[--vlen] ;
+    if (modifs[i + split])
+    {
+      if (vlen >= vmax) return 0 ;
+      v[vlen++] = modifs + i ;
+    }
+  }
+  if (vlen >= vmax) return 0 ;
+  v[vlen++] = 0 ;
+  return vlen ;
 }
diff --git a/src/libenvexec/env_mergen.c b/src/libenvexec/env_mergen.c
deleted file mode 100644
index 64a77cb..0000000
--- a/src/libenvexec/env_mergen.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ISC license. */
-
-#include <string.h>
-#include <errno.h>
-
-#include <skalibs/bytestr.h>
-#include <skalibs/env.h>
-
-size_t env_mergen (char const **v, size_t vmax, char const *const *envp, size_t envlen, char const *modifs, size_t modiflen, size_t n)
-{
-  size_t vlen = envlen ;
-  size_t i = 0 ;
-  if (envlen >= vmax) return 0 ;
-  for (; i < envlen ; i++) v[i] = envp[i] ;
-  for (i = 0 ; i < modiflen ; i += strlen(modifs + i) + 1)
-  {
-    size_t split = str_chr(modifs + i, '=') ;
-    size_t j = 0 ;
-    for (; j < vlen ; j++)
-      if (!strncmp(modifs + i, v[j], split) && (v[j][split] == '=')) break ;
-    if (j < vlen) v[j] = v[--vlen] ;
-    if (modifs[i + split])
-    {
-      if (vlen >= vmax) return 0 ;
-      v[vlen++] = modifs + i ;
-    }
-  }
-  if (vlen >= vmax) return 0 ;
-  v[vlen++] = 0 ;
-  return vlen ;
-}
diff --git a/src/libstddjb/gcspawn.c b/src/libenvexec/gcspawn.c
index 7e9e602..7e9e602 100644
--- a/src/libstddjb/gcspawn.c
+++ b/src/libenvexec/gcspawn.c
diff --git a/src/libenvexec/gmspawn_afn.c b/src/libenvexec/gmspawn_afn.c
new file mode 100644
index 0000000..dc49017
--- /dev/null
+++ b/src/libenvexec/gmspawn_afn.c
@@ -0,0 +1,11 @@
+/* ISC license. */
+
+#include <skalibs/env.h>
+#include <skalibs/cspawn.h>
+
+pid_t gmspawn_afn (char const *file, char const *const *argv, char const *const *envp, size_t envlen, char const *modif, size_t modiflen, size_t modifn, uint16_t flags, cspawn_fileaction const *fa, size_t n)
+{
+  char const *newenvp[envlen + modifn + 1] ;
+  env_merge(newenvp, envlen + modifn + 1, envp, envlen, modif, modiflen) ;
+  return gcspawn(file, argv, newenvp, flags, fa, n) ;
+}
diff --git a/src/libenvexec/mspawn_af.c b/src/libenvexec/mspawn_af.c
new file mode 100644
index 0000000..97dc877
--- /dev/null
+++ b/src/libenvexec/mspawn_af.c
@@ -0,0 +1,17 @@
+/* ISC license. */
+
+#include <skalibs/stralloc.h>
+#include <skalibs/env.h>
+#include <skalibs/cspawn.h>
+
+static stralloc modifsa = STRALLOC_ZERO ;
+
+int env_mspawn (char const *key, char const *value)
+{
+  return env_addmodif(&modifsa, key, value) ;
+}
+
+pid_t mspawn_af (char const *file, char const *const *argv, char const *const *envp, size_t envlen, uint16_t flags, cspawn_fileaction const *fa, size_t n)
+{
+  return mspawn_afm(file, argv, envp, envlen, modifsa.s, modifsa.len, flags, fa, n) ;
+}
diff --git a/src/libenvexec/mspawn_afm.c b/src/libenvexec/mspawn_afm.c
new file mode 100644
index 0000000..4b3711e
--- /dev/null
+++ b/src/libenvexec/mspawn_afm.c
@@ -0,0 +1,9 @@
+/* ISC license. */
+
+#include <skalibs/bytestr.h>
+#include <skalibs/cspawn.h>
+
+pid_t mspawn_afm (char const *file, char const *const *argv, char const *const *envp, size_t envlen, char const *modif, size_t modiflen, uint16_t flags, cspawn_fileaction const *fa, size_t n)
+{
+  return mspawn_afn(file, argv, envp, envlen, modif, modiflen, byte_count(modif, modiflen, '\0'), flags, fa, n) ;
+}
diff --git a/src/libenvexec/mspawn_afn.c b/src/libenvexec/mspawn_afn.c
new file mode 100644
index 0000000..fe36fca
--- /dev/null
+++ b/src/libenvexec/mspawn_afn.c
@@ -0,0 +1,11 @@
+/* ISC license. */
+
+#include <skalibs/env.h>
+#include <skalibs/cspawn.h>
+
+pid_t mspawn_afn (char const *file, char const *const *argv, char const *const *envp, size_t envlen, char const *modif, size_t modiflen, size_t modifn, uint16_t flags, cspawn_fileaction const *fa, size_t n)
+{
+  char const *newenvp[envlen + modifn + 1] ;
+  env_merge(newenvp, envlen + modifn + 1, envp, envlen, modif, modiflen) ;
+  return cspawn(file, argv, newenvp, flags, fa, n) ;
+}
diff --git a/src/libenvexec/xmspawn_af.c b/src/libenvexec/xmspawn_af.c
new file mode 100644
index 0000000..3e79114
--- /dev/null
+++ b/src/libenvexec/xmspawn_af.c
@@ -0,0 +1,13 @@
+/* ISC license. */
+
+#include <errno.h>
+
+#include <skalibs/strerr.h>
+#include <skalibs/cspawn.h>
+
+pid_t xmspawn_af (char const *file, char const *const *argv, char const *const *envp, size_t envlen, uint16_t flags, cspawn_fileaction const *fa, size_t n)
+{
+  pid_t pid = mspawn_af(file, argv, envp, envlen, flags, fa, n) ;
+  if (!pid) strerr_diefu2sys(errno == ENOENT ? 127 : 126, "spawn ", file) ;
+  return pid ;
+}
diff --git a/src/libenvexec/xmspawn_afm.c b/src/libenvexec/xmspawn_afm.c
new file mode 100644
index 0000000..5335fb1
--- /dev/null
+++ b/src/libenvexec/xmspawn_afm.c
@@ -0,0 +1,13 @@
+/* ISC license. */
+
+#include <errno.h>
+
+#include <skalibs/strerr.h>
+#include <skalibs/cspawn.h>
+
+pid_t xmspawn_afm (char const *file, char const *const *argv, char const *const *envp, size_t envlen, char const *modif, size_t modiflen, uint16_t flags, cspawn_fileaction const *fa, size_t n)
+{
+  pid_t pid = mspawn_afm(file, argv, envp, envlen, modif, modiflen, flags, fa, n) ;
+  if (!pid) strerr_diefu2sys(errno == ENOENT ? 127 : 126, "spawn ", file) ;
+  return pid ;
+}
diff --git a/src/libenvexec/xmspawn_afn.c b/src/libenvexec/xmspawn_afn.c
new file mode 100644
index 0000000..5af7c2e
--- /dev/null
+++ b/src/libenvexec/xmspawn_afn.c
@@ -0,0 +1,13 @@
+/* ISC license. */
+
+#include <errno.h>
+
+#include <skalibs/strerr.h>
+#include <skalibs/cspawn.h>
+
+pid_t xmspawn_afn (char const *file, char const *const *argv, char const *const *envp, size_t envlen, char const *modif, size_t modiflen, size_t modifn, uint16_t flags, cspawn_fileaction const *fa, size_t n)
+{
+  pid_t pid = mspawn_afn(file, argv, envp, envlen, modif, modiflen, modifn, flags, fa, n) ;
+  if (!pid) strerr_diefu2sys(errno == ENOENT ? 127 : 126, "spawn ", file) ;
+  return pid ;
+}