aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2025-10-28 21:11:11 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2025-10-28 21:11:11 +0000
commitda11c327290b02537d95dbe6251ade8b76cedde4 (patch)
tree8cfa94052976b129e7a106496cec24b34b527d4e /src
parentaf1a9923d1fc79e76197059251d6f54fc0082db5 (diff)
downloadexecline-da11c327290b02537d95dbe6251ade8b76cedde4.tar.gz
Add emptyenv -l, prepare for 2.9.8.0
Diffstat (limited to 'src')
-rw-r--r--src/execline/emptyenv.c148
1 files changed, 92 insertions, 56 deletions
diff --git a/src/execline/emptyenv.c b/src/execline/emptyenv.c
index 3c5b287..ac59697 100644
--- a/src/execline/emptyenv.c
+++ b/src/execline/emptyenv.c
@@ -2,9 +2,12 @@
#include <string.h>
-#include <skalibs/gccattributes.h>
+#include <skalibs/uint64.h>
+#include <skalibs/types.h>
+#include <skalibs/posixplz.h>
#include <skalibs/bytestr.h>
-#include <skalibs/sgetopt.h>
+#include <skalibs/prog.h>
+#include <skalibs/gol.h>
#include <skalibs/strerr.h>
#include <skalibs/stralloc.h>
#include <skalibs/env.h>
@@ -12,74 +15,85 @@
#include <execline/execline.h>
-#define USAGE "emptyenv [ -p | -c | -o | -P ] prog..."
+#define USAGE "emptyenv [ -p | -l | -c | -o | -P ] prog..."
-static void cleanupenv (char const *const *, char const *const *) gccattr_noreturn ;
-static void cleanupenv (char const *const *argv, char const *const *envp)
+enum emptyenv_golb_e
{
- stralloc sa = STRALLOC_ZERO ;
- if (!env_mexec("!", 0) || !env_mexec("?", 0)) goto err ;
- for (; *envp ; envp++)
- {
- char const *s = *envp ;
- sa.len = 0 ;
- if (!strncmp(s, "ELGETOPT_", 9)
- || !strncmp(s, "EXECLINE_", 9)
- || !strncmp(s, "FD", 2)
- || (s[0] == '#')
- || ((s[0] >= '0') && (s[0] <= '9')))
- if (!stralloc_catb(&sa, s, str_chr(s, '='))
- || !stralloc_0(&sa)
- || !env_mexec(sa.s, 0))
- goto err ;
- }
- stralloc_free(&sa) ;
- xmexec(argv) ;
-err:
- strerr_diefu1sys(111, "clean up environment") ;
-}
+ GOLB_PATH = 0x01,
+ GOLB_LIB = 0x02,
+ GOLB_CLEANUP = 0x04,
+ GOLB_OPT = 0x08,
+ GOLB_POS = 0x10
+} ;
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
{
- int flagpath = 0, flagcleanup = 0, flagopt = 0, flagpos = 0 ;
+ static gol_bool const rgolb[5] =
+ {
+ { .so = 'p', .lo = "keep-path", .clear = 0, .set = GOLB_PATH },
+ { .so = 'l', .lo = "keep-ld-library-path", .clear = 0, .set = GOLB_LIB },
+ { .so = 'c', .lo = "cleanup", .clear = 0, .set = GOLB_CLEANUP },
+ { .so = 'o', .lo = "pop-elgetopt", .clear = 0, .set = GOLB_OPT },
+ { .so = 'P', .lo = "pop-execline", .clear = 0, .set = GOLB_POS }
+ } ;
+ uint64_t wgolb = 0 ;
+ unsigned int golc ;
PROG = "emptyenv" ;
+ golc = gol_main(argc, argv, rgolb, 5, 0, 0, &wgolb, 0) ;
+ argc -= golc ; argv += golc ;
+ if (!argc) strerr_dieusage(100, USAGE) ;
+
+ if (wgolb & GOLB_CLEANUP)
{
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
+ static char const *const onebyte = "!?#0" ;
+ char *const *envp = environ ;
+ for (size_t i = 0 ; onebyte[i] ; i++)
+ {
+ char s[2] ;
+ s[0] = onebyte[i] ;
+ s[1] = 0 ;
+ if (!env_mexec(s, 0)) goto err ;
+ }
+ if (!env_mexec("EXECLINE_STRICT", 0)) goto err ;
+ for (; *envp ; envp++)
{
- int opt = subgetopt_r(argc, argv, "pcoP", &l) ;
- if (opt == -1) break ;
- switch (opt)
+ size_t l ;
+ char const *s = *envp ;
+ if (!strncmp(s, "ELGETOPT_", 9)) goto add ;
+ if (!strncmp(s, "FD", 2))
{
- case 'p' : flagpath = 1 ; break ;
- case 'c' : flagcleanup = 1 ; break ;
- case 'o' : flagopt = 1 ; break ;
- case 'P' : flagpos = 1 ; break ;
- default : strerr_dieusage(100, USAGE) ;
+ unsigned int n ;
+ l = uint_scan(s + 2, &n) ;
+ if (l && s[2 + l] == '=') goto add ;
+ }
+ if ((s[0] >= '1') && (s[0] <= '9'))
+ {
+ unsigned int n ;
+ l = uint_scan(s, &n) ;
+ if (l && s[l] == '=') goto add ;
+ }
+ continue ;
+ add:
+ l = str_chr(s, '=') ;
+ if (l)
+ {
+ char tmp[l+1] ;
+ memcpy(tmp, s, l) ;
+ tmp[l] = 0 ;
+ if (!env_mexec(tmp, 0)) goto err ;
}
}
- argc -= l.ind ; argv += l.ind ;
+ xmexec(argv) ;
+ err:
+ strerr_diefu1sys(111, "clean up environment") ;
}
- if (!argc) strerr_dieusage(100, USAGE) ;
- if (flagcleanup) cleanupenv(argv, envp) ;
- else if (!flagopt && !flagpos)
- {
- char const *newenv[2] = { 0, 0 } ;
- if (flagpath)
- for (; *envp ; envp++)
- if (!strncmp(*envp, "PATH=", 5))
- {
- newenv[0] = *envp ;
- break ;
- }
- xexec_e(argv, newenv) ;
- }
- else
+
+ else if (wgolb & (GOLB_OPT | GOLB_POS))
{
static char const *const list[12] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "#", "ELGETOPT_" } ;
stralloc sa = STRALLOC_ZERO ;
- size_t envlen = env_len(envp) ;
- int n = el_popenv(&sa, envp, envlen, flagpos ? list : list + 11, 11 * flagpos + flagopt) ;
+ size_t envlen = env_len((char const *const *)environ) ;
+ int n = el_popenv(&sa, (char const *const *)environ, envlen, wgolb & GOLB_POS ? list : list + 11, (wgolb & GOLB_POS ? 11 : 0) + !!(wgolb & GOLB_OPT)) ;
if (n < 0) strerr_diefu1sys(111, "pop current execline environment") ;
{
char const *v[envlen - n + 1] ;
@@ -88,4 +102,26 @@ int main (int argc, char const *const *argv, char const *const *envp)
xexec_e(argv, v) ;
}
}
+
+ else
+ {
+ char const *newenv[3] = { 0, 0, 0 } ;
+ char *const *envp = environ ;
+ unsigned int m = 0 ;
+ wgolb &= GOLB_PATH | GOLB_LIB ;
+ for (; wgolb && *envp ; envp++)
+ {
+ if (wgolb & GOLB_PATH && !strncmp(*envp, "PATH=", 5))
+ {
+ newenv[m++] = *envp ;
+ wgolb &= ~GOLB_PATH ;
+ }
+ if (wgolb & GOLB_LIB && !strncmp(*envp, "LD_LIBRARY_PATH=", 16))
+ {
+ newenv[m++] = *envp ;
+ wgolb &= ~GOLB_LIB ;
+ }
+ }
+ xexec_e(argv, newenv) ;
+ }
}