Skip to content

Commit

Permalink
Complete revamp of the pathexec functions
Browse files Browse the repository at this point in the history
- pathexec_run is now called exec_ae
    a for provided file name (default: argv[0])
    e for provided envp (default: environ)
- pathexec is now called mexec. m for merge environment. Option letters are:
    a for provided file name (default: argv[0])
    e for provided envp (default: environ)
    f for provided envp *and* length of the envp
    m for provided modif string plus its length (the length is always needed
because the modifs are null-terminated)
    n for provided modif string, length *and* number of modifs
- functions have a foo0 version for _exit(0) when argv[0] is null
- functions have a xfoo version to die if the exec fails
- and a xfoo0
- Compatibility #defines and #includes are there until the next major bump
  • Loading branch information
skarnet committed Nov 24, 2020
1 parent 265092c commit 18e4356
Show file tree
Hide file tree
Showing 54 changed files with 435 additions and 209 deletions.
1 change: 1 addition & 0 deletions NEWS
Expand Up @@ -8,6 +8,7 @@ In 2.9.4.0
unconditionally deleting the socket.
- ipc_bind_reuse() rewritten to use ipc_bind_reuse_lock(),
so it does the right thing instead of clobbering sockets.
- Complete revamping of the pathexec functions, see exec.h


In 2.9.3.0
Expand Down
1 change: 1 addition & 0 deletions doc/upgrade.html
Expand Up @@ -24,6 +24,7 @@ <h2> in 2.9.4.0 </h2>
<li> New <tt>ipc_bind_reuse_lock()</tt> function, which takes a lock before
deleting a Unix domain socket. The <tt>ipc_bind_reuse()</tt> function now
uses it, so it won't unconditionally clobber sockets in the filesystem anymore. </li>
<li> Complete revamping of the pathexec functions, see <tt>exec.h</tt>. </li>
</ul>

<h2> in 2.9.3.0 </h2>
Expand Down
69 changes: 41 additions & 28 deletions package/deps.mak

Large diffs are not rendered by default.

22 changes: 2 additions & 20 deletions src/include/skalibs/djbunix.h
Expand Up @@ -6,10 +6,10 @@
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/wait.h>

#include <skalibs/gccattributes.h>
#include <skalibs/stralloc.h>
#include <skalibs/envalloc.h>
#include <skalibs/posixplz.h>
#include <skalibs/exec.h> /* compat */

#define DJBUNIX_FLAG_NB 0x01U
#define DJBUNIX_FLAG_COE 0x02U
Expand Down Expand Up @@ -64,24 +64,6 @@ extern int socketpair_internal (int, int, int, unsigned int, int *) ;

extern size_t path_canonicalize (char *, char const *, int) ;

extern int pathexec_env (char const *, char const *) ;
extern void pathexec_r (char const *const *, char const *const *, size_t, char const *, size_t) ;
extern void pathexec_r_name (char const *, char const *const *, char const *const *, size_t, char const *, size_t) ;
extern void pathexec_fromenv (char const *const *, char const *const *, size_t) ;
extern void pathexec_run (char const *, char const *const *, char const *const *) ;
extern void pathexec0_run (char const *const *, char const *const *) ;
extern void pathexec (char const *const *) ;
extern void pathexec0 (char const *const *) ;

extern void xpathexec_r (char const *const *, char const *const *, size_t, char const *, size_t) gccattr_noreturn ;
extern void xpathexec_r_name (char const *, char const *const *, char const *const *, size_t, char const *, size_t) gccattr_noreturn ;
extern void xpathexec_fromenv (char const *const *, char const *const *, size_t) gccattr_noreturn ;
extern void xexecvep (char const *, char const *const *, char const *const *, char const *) gccattr_noreturn ;
extern void xpathexec_run (char const *, char const *const *, char const *const *) gccattr_noreturn ;
extern void xpathexec0_run (char const *const *, char const *const *) gccattr_noreturn ;
extern void xpathexec (char const *const *) gccattr_noreturn ;
extern void xpathexec0 (char const *const *) gccattr_noreturn ;

extern pid_t wait_nointr (int *) ;
extern pid_t waitpid_nointr (pid_t, int *, int) ;
#define wait_pid(pid, wstat) waitpid_nointr(pid, (wstat), 0)
Expand Down
8 changes: 7 additions & 1 deletion src/include/skalibs/env.h
Expand Up @@ -4,18 +4,24 @@
#define SKALIBS_ENV_H

#include <sys/types.h>

#include <skalibs/gccattributes.h>
#include <skalibs/stralloc.h>

extern size_t env_len (char const *const *) gccattr_pure ;
extern char const *env_get (char const *) gccattr_deprecated ;
extern char const *env_get2 (char const *const *, char const *) gccattr_pure ;
extern char const *ucspi_get (char const *) gccattr_pure ;

extern int env_addmodif (stralloc *, char const *, char const *) ;
extern int env_make (char const **, size_t, char const *, size_t) ;
extern size_t env_merge (char const **, size_t, char const *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_merge (char const **, size_t, char const *const *, size_t, char const *, size_t) ;
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
extern int envdir_internal (char const *, stralloc *, unsigned int, char) ;
Expand Down
160 changes: 160 additions & 0 deletions src/include/skalibs/exec.h
@@ -0,0 +1,160 @@
/* ISC license. */

#ifndef SKALIBS_EXEC_H
#define SKALIBS_EXEC_H

#include <stddef.h>

#include <skalibs/environ.h>
#include <skalibs/env.h>
#include <skalibs/gccattributes.h>


/* Without environment modifications */

extern void xexecvep (char const *, char const *const *, char const *const *, char const *) gccattr_noreturn ;
extern void xexecvep_loose (char const *, char const *const *, char const *const *, char const *) gccattr_noreturn ;

extern void exec_ae (char const *, char const *const *, char const *const *) ;
#define exec_a(file, argv) exec_ae(file, (argv), (char const *const *)environ)
#define exec_e(argv, envp) exec_ae((argv)[0], (argv), envp)
#define exec(argv) exec_a((argv)[0], (argv))

extern void xexec_ae (char const *, char const *const *, char const *const *) gccattr_noreturn ;
#define xexec_a(file, argv) xexec_ae(file, (argv), (char const *const *)environ)
#define xexec_e(argv, envp) xexec_ae((argv)[0], (argv), envp)
#define xexec(argv) xexec_a((argv)[0], (argv))

extern void exec0_ae (char const *, char const *const *, char const *const *) ;
#define exec0_a(file, argv) exec0_ae(file, (argv), (char const *const *)environ)
#define exec0_e(argv, envp) exec0_ae((argv)[0], (argv), envp)
#define exec0(argv) exec0_a((argv)[0], (argv))

extern void xexec0_ae (char const *, char const *const *, char const *const *) gccattr_noreturn ;
#define xexec0_a(file, argv) xexec0_ae(file, (argv), (char const *const *)environ)
#define xexec0_e(argv, envp) xexec0_ae((argv)[0], (argv), envp)
#define xexec0(argv) xexec0_a((argv)[0], (argv))


/* With environment modifications : env_merge and exec */

extern int env_mexec (char const *, char const *) ;

extern void mexec_afn (char const *, char const *const *, char const *const *, size_t, char const *, size_t, size_t) ;
extern void mexec_afm (char const *, char const *const *, char const *const *, size_t, char const *, size_t) ;
extern void mexec_af (char const *, char const *const *, char const *const *, size_t) ;

#define mexec_aen(file, argv, envp, modif, modiflen, modifn) mexec_afn(file, argv, envp, env_len(envp), modif, modiflen, modifn)
#define mexec_aem(file, argv, envp, modif, modiflen) mexec_afm(file, argv, envp, env_len(envp), modif, modiflen)
#define mexec_ae(file, argv, envp) mexec_af(file, argv, envp, env_len(envp))

#define mexec_an(file, argv, modif, modiflen, modifn) mexec_aen(file, argv, (char const *const *)environ, modif, modiflen, modifn)
#define mexec_am(file, argv, modif, modiflen) mexec_aem(file, argv, (char const *const *)environ, modif, modiflen)
#define mexec_a(file, argv) mexec_ae(file, argv, (char const *const *)environ)

#define mexec_fn(argv, envp, envlen, modif, modiflen, modifn) mexec_afn((argv)[0], (argv), envp, envlen, modif, modiflen, modifn)
#define mexec_fm(argv, envp, envlen, modif, modiflen) mexec_afm((argv)[0], (argv), envp, envlen, modif, modiflen)
#define mexec_f(argv, envp, envlen) mexec_af((argv)[0], (argv), envp, envlen)

#define mexec_en(argv, envp, modif, modiflen, modifn) mexec_aen((argv)[0], (argv), envp, modif, modiflen, modifn)
#define mexec_em(argv, envp, modif, modiflen) mexec_aem((argv)[0], (argv), envp, modif, modiflen)
#define mexec_e(argv, envp) mexec_a((argv)[0], (argv), envp)

#define mexec_n(argv, modif, modiflen, modifn) mexec_an((argv)[0], (argv), modif, modiflen, modifn)
#define mexec_m(argv, modif, modiflen) mexec_am((argv)[0], (argv), modif, modiflen)
#define mexec(argv) mexec_a((argv)[0], (argv))

extern void mexec0_afn (char const *, char const *const *, char const *const *, size_t, char const *, size_t, size_t) ;
extern void mexec0_afm (char const *, char const *const *, char const *const *, size_t, char const *, size_t) ;
extern void mexec0_af (char const *, char const *const *, char const *const *, size_t) ;

#define mexec0_aen(file, argv, envp, modif, modiflen, modifn) mexec0_afn(file, argv, envp, env_len(envp), modif, modiflen, modifn)
#define mexec0_aem(file, argv, envp, modif, modiflen) mexec0_afm(file, argv, envp, env_len(envp), modif, modiflen)
#define mexec0_ae(file, argv, envp) mexec0_af(file, argv, envp, env_len(envp))

#define mexec0_an(file, argv, modif, modiflen, modifn) mexec0_aen(file, argv, (char const *const *)environ, modif, modiflen, modifn)
#define mexec0_am(file, argv, modif, modiflen) mexec0_aem(file, argv, (char const *const *)environ, modif, modiflen)
#define mexec0_a(file, argv) mexec0_ae(file, argv, (char const *const *)environ)

#define mexec0_fn(argv, envp, envlen, modif, modiflen, modifn) mexec0_afn((argv)[0], (argv), envp, envlen, modif, modiflen, modifn)
#define mexec0_fm(argv, envp, envlen, modif, modiflen) mexec0_afm((argv)[0], (argv), envp, envlen, modif, modiflen)
#define mexec0_f(argv, envp, envlen) mexec0_af((argv)[0], (argv), envp, envlen)

#define mexec0_en(argv, envp, modif, modiflen, modifn) mexec0_aen((argv)[0], (argv), envp, modif, modiflen, modifn)
#define mexec0_em(argv, envp, modif, modiflen) mexec0_aem((argv)[0], (argv), envp, modif, modiflen)
#define mexec0_e(argv, envp) mexec0_a((argv)[0], (argv), envp)

#define mexec0_n(argv, modif, modiflen, modifn) mexec0_an((argv)[0], (argv), modif, modiflen, modifn)
#define mexec0_m(argv, modif, modiflen) mexec0_am((argv)[0], (argv), modif, modiflen)
#define mexec0(argv) mexec0_a((argv)[0], (argv))

extern void xmexec_afn (char const *, char const *const *, char const *const *, size_t, char const *, size_t, size_t) gccattr_noreturn ;
extern void xmexec_afm (char const *, char const *const *, char const *const *, size_t, char const *, size_t) gccattr_noreturn ;
extern void xmexec_af (char const *, char const *const *, char const *const *, size_t) gccattr_noreturn ;

#define xmexec_aen(file, argv, envp, modif, modiflen, modifn) xmexec_afn(file, argv, envp, env_len(envp), modif, modiflen, modifn)
#define xmexec_aem(file, argv, envp, modif, modiflen) xmexec_afm(file, argv, envp, env_len(envp), modif, modiflen)
#define xmexec_ae(file, argv, envp) xmexec_af(file, argv, envp, env_len(envp))

#define xmexec_an(file, argv, modif, modiflen, modifn) xmexec_aen(file, argv, (char const *const *)environ, modif, modiflen, modifn)
#define xmexec_am(file, argv, modif, modiflen) xmexec_aem(file, argv, (char const *const *)environ, modif, modiflen)
#define xmexec_a(file, argv) xmexec_ae(file, argv, (char const *const *)environ)

#define xmexec_fn(argv, envp, envlen, modif, modiflen, modifn) xmexec_afn((argv)[0], (argv), envp, envlen, modif, modiflen, modifn)
#define xmexec_fm(argv, envp, envlen, modif, modiflen) xmexec_afm((argv)[0], (argv), envp, envlen, modif, modiflen)
#define xmexec_f(argv, envp, envlen) xmexec_af((argv)[0], (argv), envp, envlen)

#define xmexec_en(argv, envp, modif, modiflen, modifn) xmexec_aen((argv)[0], (argv), envp, modif, modiflen, modifn)
#define xmexec_em(argv, envp, modif, modiflen) xmexec_aem((argv)[0], (argv), envp, modif, modiflen)
#define xmexec_e(argv, envp) xmexec_a((argv)[0], (argv), envp)

#define xmexec_n(argv, modif, modiflen, modifn) xmexec_an((argv)[0], (argv), modif, modiflen, modifn)
#define xmexec_m(argv, modif, modiflen) xmexec_am((argv)[0], (argv), modif, modiflen)
#define xmexec(argv) xmexec_a((argv)[0], (argv))

extern void xmexec0_afn (char const *, char const *const *, char const *const *, size_t, char const *, size_t, size_t) ;
extern void xmexec0_afm (char const *, char const *const *, char const *const *, size_t, char const *, size_t) ;
extern void xmexec0_af (char const *, char const *const *, char const *const *, size_t) ;

#define xmexec0_aen(file, argv, envp, modif, modiflen, modifn) xmexec0_afn(file, argv, envp, env_len(envp), modif, modiflen, modifn)
#define xmexec0_aem(file, argv, envp, modif, modiflen) xmexec0_afm(file, argv, envp, env_len(envp), modif, modiflen)
#define xmexec0_ae(file, argv, envp) xmexec0_af(file, argv, envp, env_len(envp))

#define xmexec0_an(file, argv, modif, modiflen, modifn) xmexec0_aen(file, argv, (char const *const *)environ, modif, modiflen, modifn)
#define xmexec0_am(file, argv, modif, modiflen) xmexec0_aem(file, argv, (char const *const *)environ, modif, modiflen)
#define xmexec0_a(file, argv) xmexec0_ae(file, argv, (char const *const *)environ)

#define xmexec0_fn(argv, envp, envlen, modif, modiflen, modifn) xmexec0_afn((argv)[0], (argv), envp, envlen, modif, modiflen, modifn)
#define xmexec0_fm(argv, envp, envlen, modif, modiflen) xmexec0_afm((argv)[0], (argv), envp, envlen, modif, modiflen)
#define xmexec0_f(argv, envp, envlen) xmexec0_af((argv)[0], (argv), envp, envlen)

#define xmexec0_en(argv, envp, modif, modiflen, modifn) xmexec0_aen((argv)[0], (argv), envp, modif, modiflen, modifn)
#define xmexec0_em(argv, envp, modif, modiflen) xmexec0_aem((argv)[0], (argv), envp, modif, modiflen)
#define xmexec0_e(argv, envp) xmexec0_a((argv)[0], (argv), envp)

#define xmexec0_n(argv, modif, modiflen, modifn) xmexec0_an((argv)[0], (argv), modif, modiflen, modifn)
#define xmexec0_m(argv, modif, modiflen) xmexec0_am((argv)[0], (argv), modif, modiflen)
#define xmexec0(argv) xmexec0_a((argv)[0], (argv))


/* Compatibility */

#define pathexec_run(file, argv, envp) exec_ae(file, argv, envp)
#define pathexec0_run(file, argv, envp) exec0_ae(file, argv, envp)
#define xpathexec_run(file, argv, envp) xexec_ae(file, argv, envp)
#define xpathexec0_run(file, argv, envp) xexec0_ae(file, argv, envp)

#define pathexec_env(key, value) env_mexec(key, value)
#define pathexec_fromenv(argv, envp, envlen) mexec_f(argv, envp, envlen)
#define pathexec(argv) mexec(argv)
#define pathexec0(argv) mexec0(argv)
#define xpathexec_fromenv(argv, envp, envlen) xmexec_f(argv, envp, envlen)
#define xpathexec(argv) xmexec(argv)
#define xpathexec0(argv) xmexec0(argv)

#define pathexec_r_name(file, argv, envp, envlen, modif, modiflen) mexec_afm(file, argv, envp, envlen, modif, modiflen)
#define pathexec_r(argv, envp, envlen, modif, modiflen) mexec_fm(argv, envp, envlen, modif, modiflen)
#define xpathexec_r_name(file, argv, envp, envlen, modif, modiflen) xmexec_afm(file, argv, envp, envlen, modif, modiflen)
#define xpathexec_r(argv, envp, envlen, modif, modiflen) xmexec_fm(argv, envp, envlen, modif, modiflen)

#endif
1 change: 1 addition & 0 deletions src/include/skalibs/stddjb.h
Expand Up @@ -28,6 +28,7 @@
#include <skalibs/djbunix.h>
#include <skalibs/envalloc.h>
#include <skalibs/env.h>
#include <skalibs/exec.h>
#include <skalibs/fmtscan.h>
#include <skalibs/functypes.h>
#include <skalibs/gccattributes.h>
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions src/libenvexec/env_merg.c
@@ -0,0 +1,8 @@
/* ISC license. */

#include <skalibs/env.h>

size_t env_merg (char const **v, size_t vmax, char const *const *envp, char const *modifs, size_t modiflen)
{
return env_merge(v, vmax, envp, env_len(envp), modifs, modiflen) ;
}
9 changes: 9 additions & 0 deletions src/libenvexec/env_merge.c
@@ -0,0 +1,9 @@
/* ISC license. */

#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')) ;
}
4 changes: 2 additions & 2 deletions src/libstddjb/env_merge.c → src/libenvexec/env_mergen.c
Expand Up @@ -2,12 +2,12 @@

#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)
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 n = byte_count(modifs, modiflen, '\0') ;
size_t vlen = envlen ;
size_t i = 0 ;
if (envlen + n + 1 > vmax) return (errno = ENAMETOOLONG, 0) ;
Expand Down
8 changes: 8 additions & 0 deletions src/libenvexec/env_mergn.c
@@ -0,0 +1,8 @@
/* ISC license. */

#include <skalibs/env.h>

size_t env_mergn (char const **v, size_t vmax, char const *const *envp, char const *modifs, size_t modiflen, size_t modifn)
{
return env_mergen(v, vmax, envp, env_len(envp), modifs, modiflen, modifn) ;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Expand Up @@ -9,7 +9,7 @@ int envalloc_merge (genalloc *v, char const *const *envp, size_t envlen, char co
{
size_t n = envlen + 1 + byte_count(modifs, modiflen, '\0') ;
if (!genalloc_readyplus(char const *, v, n)) return 0 ;
n = env_merge(genalloc_s(char const *, v) + genalloc_len(char const *, v), n, envp, envlen, modifs, modiflen) ;
n = env_mergen(genalloc_s(char const *, v) + genalloc_len(char const *, v), n, envp, envlen, modifs, modiflen, n) ;
genalloc_setlen(char const *, v, genalloc_len(char const *, v) + n) ;
return 1 ;
}
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions src/libenvexec/exec0_ae.c
@@ -0,0 +1,11 @@
/* ISC license. */

#include <unistd.h>

#include <skalibs/exec.h>

void exec0_ae (char const *file, char const *const *argv, char const *const *envp)
{
if (!argv[0]) _exit(0) ;
exec_ae(file, argv, envp) ;
}
5 changes: 3 additions & 2 deletions src/libstddjb/pathexec_run.c → src/libenvexec/exec_ae.c
@@ -1,11 +1,12 @@
/* ISC license. */

#include <stdlib.h>

#include <skalibs/config.h>
#include <skalibs/posixplz.h>
#include <skalibs/djbunix.h>
#include <skalibs/exec.h>

void pathexec_run (char const *file, char const *const *argv, char const *const *envp)
void exec_ae (char const *file, char const *const *argv, char const *const *envp)
{
char const *path = getenv("PATH") ;
if (!path) path = SKALIBS_DEFAULTPATH ;
Expand Down
11 changes: 11 additions & 0 deletions src/libenvexec/mexec0_af.c
@@ -0,0 +1,11 @@
/* ISC license. */

#include <unistd.h>

#include <skalibs/exec.h>

void mexec0_af (char const *file, char const *const *argv, char const *const *envp, size_t envlen)
{
if (!argv[0]) _exit(0) ;
mexec_af(file, argv, envp, envlen) ;
}
11 changes: 11 additions & 0 deletions src/libenvexec/mexec0_afm.c
@@ -0,0 +1,11 @@
/* ISC license. */

#include <unistd.h>

#include <skalibs/exec.h>

void mexec0_afm (char const *file, char const *const *argv, char const *const *envp, size_t envlen, char const *modif, size_t modiflen)
{
if (!argv[0]) _exit(0) ;
mexec_afm(file, argv, envp, envlen, modif, modiflen) ;
}
11 changes: 11 additions & 0 deletions src/libenvexec/mexec0_afn.c
@@ -0,0 +1,11 @@
/* ISC license. */

#include <unistd.h>

#include <skalibs/exec.h>

void mexec0_afn (char const *file, char const *const *argv, char const *const *envp, size_t envlen, char const *modif, size_t modiflen, size_t modifn)
{
if (!argv[0]) _exit(0) ;
mexec_afn(file, argv, envp, envlen, modif, modiflen, modifn) ;
}
17 changes: 17 additions & 0 deletions src/libenvexec/mexec_af.c
@@ -0,0 +1,17 @@
/* ISC license. */

#include <skalibs/stralloc.h>
#include <skalibs/env.h>
#include <skalibs/exec.h>

static stralloc modifsa = STRALLOC_ZERO ;

int env_mexec (char const *key, char const *value)
{
return env_addmodif(&modifsa, key, value) ;
}

void mexec_af (char const *file, char const *const *argv, char const *const *envp, size_t envlen)
{
mexec_afm(file, argv, envp, envlen, modifsa.s, modifsa.len) ;
}
9 changes: 9 additions & 0 deletions src/libenvexec/mexec_afm.c
@@ -0,0 +1,9 @@
/* ISC license. */

#include <skalibs/bytestr.h>
#include <skalibs/exec.h>

void mexec_afm (char const *file, char const *const *argv, char const *const *envp, size_t envlen, char const *modif, size_t modiflen)
{
mexec_afn(file, argv, envp, envlen, modif, modiflen, byte_count(modif, modiflen, '\0')) ;
}

0 comments on commit 18e4356

Please sign in to comment.