aboutsummaryrefslogtreecommitdiffstats
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
parentaf1a9923d1fc79e76197059251d6f54fc0082db5 (diff)
downloadexecline-da11c327290b02537d95dbe6251ade8b76cedde4.tar.gz
Add emptyenv -l, prepare for 2.9.8.0
-rw-r--r--NEWS3
-rw-r--r--doc/emptyenv.html3
-rw-r--r--doc/index.html4
-rw-r--r--doc/upgrade.html2
-rw-r--r--package/info2
-rw-r--r--src/execline/emptyenv.c148
6 files changed, 100 insertions, 62 deletions
diff --git a/NEWS b/NEWS
index 17ffe77..7d84962 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,11 @@
Changelog for execline.
-In 2.9.7.1
+In 2.9.8.0
----------
- Bugfixes.
- Support for shared libraries on MacOS.
+ - New -l option to emptyenv: keep LD_LIBRARY_PATH
In 2.9.7.0
diff --git a/doc/emptyenv.html b/doc/emptyenv.html
index da6f653..1aa6075 100644
--- a/doc/emptyenv.html
+++ b/doc/emptyenv.html
@@ -26,7 +26,7 @@ executes a program.
<h2> Interface </h2>
<pre>
- emptyenv [ -p ] <em>prog...</em>
+ emptyenv [ -p ] [ -l ] <em>prog...</em>
emptyenv -c <em>prog...</em>
emptyenv [ -o ] [ -P ] <em>prog...</em>
</pre>
@@ -41,6 +41,7 @@ environment variables are unset.
<ul>
<li> <tt>-p</tt>&nbsp;: keep the <tt>PATH</tt> environment variable. </li>
+ <li> <tt>-l</tt>&nbsp;: keep the <tt>LD_LIBRARY_PATH</tt> environment variable. </li>
<li> <tt>-c</tt>&nbsp;: clean up. Do not empty the environment. Instead,
remove every variable used internally by the execline programs, to avoid
any interference with or information leakage to external programs. </li>
diff --git a/doc/index.html b/doc/index.html
index 9e6d45e..d0af579 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -77,8 +77,8 @@ want nsswitch-like functionality:
<h3> Download </h3>
<ul>
- <li> The current released version of execline is <a href="execline-2.9.7.1.tar.gz">2.9.7.1</a>.
-You can access its checksum <a href="execline-2.9.7.1.tar.gz.sha256">here</a>. </li>
+ <li> The current released version of execline is <a href="execline-2.9.8.0.tar.gz">2.9.8.0</a>.
+You can access its checksum <a href="execline-2.9.8.0.tar.gz.sha256">here</a>. </li>
<li> Alternatively, you can checkout a copy of the
<a href="//git.skarnet.org/cgi-bin/cgit.cgi/execline/">execline
git repository</a>:
diff --git a/doc/upgrade.html b/doc/upgrade.html
index c014c08..fbb7cc4 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,7 +18,7 @@
<h1> What has changed in execline </h1>
-<h2> in 2.9.7.1 </h2>
+<h2> in 2.9.8.0 </h2>
<ul>
<li> <a href="//skarnet.org/software/skalibs/">skalibs</a>
diff --git a/package/info b/package/info
index 0ef616e..1a386b2 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=execline
-version=2.9.7.1
+version=2.9.8.0
category=admin
package_macro_name=EXECLINE
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) ;
+ }
}