From a1f847eae994d665d01b85b0fd1a69492455f3ec Mon Sep 17 00:00:00 2001
From: Laurent Bercot
Date: Tue, 27 Jan 2015 01:11:13 +0000
Subject: - Added -D option to backtick - Doc updated
---
doc/backtick.html | 12 ++++++++----
doc/forbacktickx.html | 2 +-
doc/forx.html | 2 +-
doc/index.html | 7 +++++--
src/execline/backtick.c | 52 ++++++++++++++++++++++++++++---------------------
5 files changed, 45 insertions(+), 30 deletions(-)
diff --git a/doc/backtick.html b/doc/backtick.html
index 7bdc037..bdcd785 100644
--- a/doc/backtick.html
+++ b/doc/backtick.html
@@ -29,7 +29,7 @@ another program.
- backtick [ -i ] [ -n ] variable { prog1... } prog2...
+ backtick [ -i | -D default ] [ -n ] variable { prog1... } prog2...
@@ -45,9 +45,13 @@ output as a value.
Options
- - -i : insist. If prog1 exits non-zero,
+
- -i : insist. If prog1 crashes or exits non-zero,
backtick exits with the same exit code (or 111 if prog1
-crashed for some reason). Without this option, backtick execs into
+crashed).
+ - -D default : default value. If
+prog1 crashes or exits non-zero, default is used as
+variable's value. If neither the -i nor the -D
+option have been given, backtick execs into
prog2... no matter what prog1 does, with the null word as
variable's value if prog1 didn't write anything before
dying.
@@ -58,7 +62,7 @@ output.
Notes
- - You can start prog2... with "import variable unexport variable"
+
- You can start prog2... with "import -u variable"
to perform variable substitution.
diff --git a/doc/forbacktickx.html b/doc/forbacktickx.html
index 9e09c81..d40799a 100644
--- a/doc/forbacktickx.html
+++ b/doc/forbacktickx.html
@@ -69,7 +69,7 @@ split x.
Notes
- - You can start loop... with "import variable unexport variable"
+
- You can start loop... with "import -u variable"
to perform variable substitution.
diff --git a/doc/forx.html b/doc/forx.html
index 86729b8..0349a85 100644
--- a/doc/forx.html
+++ b/doc/forx.html
@@ -58,7 +58,7 @@ same exit code.
Notes
- - You can start loop with "import variable unexport variable"
+
- You can start loop with "import -u variable"
if you want variable substitution.
diff --git a/doc/index.html b/doc/index.html
index 851a0c5..a847509 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -48,9 +48,12 @@ shell's syntax, and has no security issues.
- A POSIX-compliant system with a standard C development environment
- - GNU make, version 4.0 or later
+ - GNU make, version 4.0 or later. Please be aware that execline will
+not build with an earlier version.
- skalibs version
-2.2.1.0 or later
+2.2.1.0 or later. It's a build-time requirement. It's also a run-time
+requirement if you link against the shared version of the skalibs
+library.
Licensing
diff --git a/src/execline/backtick.c b/src/execline/backtick.c
index d0f74e4..3928f90 100644
--- a/src/execline/backtick.c
+++ b/src/execline/backtick.c
@@ -1,6 +1,7 @@
/* ISC license. */
#include
+#include
#include
#include
#include
@@ -9,25 +10,29 @@
#include
#include
-#define USAGE "backtick [ -i ] [ -n ] var { prog... } remainder..."
+#define USAGE "backtick [ -i | -D default ] [ -n ] var { prog... } remainder..."
#define dieusage() strerr_dieusage(100, USAGE)
int main (int argc, char const **argv, char const *const *envp)
{
subgetopt_t localopt = SUBGETOPT_ZERO ;
- int argc1 ;
+ pid_t pid ;
+ int argc1, fdwstat ;
stralloc modif = STRALLOC_ZERO ;
+ unsigned int modifstart ;
int insist = 0, chomp = 0 ;
+ char const *def = 0 ;
PROG = "backtick" ;
for (;;)
{
- register int opt = subgetopt_r(argc, argv, "ein", &localopt) ;
+ register int opt = subgetopt_r(argc, argv, "einD:", &localopt) ;
if (opt < 0) break ;
switch (opt)
{
case 'i' : insist = 1 ; break ;
case 'n' : chomp = 1 ; break ;
case 'e' : break ; /* compat */
+ case 'D' : def = localopt.arg ; break ;
default : dieusage() ;
}
}
@@ -37,33 +42,29 @@ int main (int argc, char const **argv, char const *const *envp)
if (!*argv[0]) strerr_dief1x(100, "empty variable not accepted") ;
if (!stralloc_cats(&modif, argv[0]) || !stralloc_catb(&modif, "=", 1))
strerr_diefu1sys(111, "stralloc_catb") ;
+ modifstart = modif.len ;
argc-- ; argv++ ;
argc1 = el_semicolon(argv) ;
if (!argc1) strerr_dief1x(100, "empty block") ;
if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ;
+ argv[argc1] = 0 ;
+ pid = child_spawn1_pipe(argv[0], argv, envp, &fdwstat, 1) ;
+ if (!pid) strerr_diefu2sys(111, "spawn ", argv[0]) ;
+ if (!slurp(&modif, fdwstat)) strerr_diefu1sys(111, "slurp") ;
+ close(fdwstat) ;
+ if (wait_pid(pid, &fdwstat) < 0) strerr_diefu1sys(111, "wait_pid") ;
+
+ if (WIFSIGNALED(fdwstat) || WEXITSTATUS(fdwstat))
{
- int p[2] ;
- pid_t pid ;
- if (pipe(p) < 0) strerr_diefu1sys(111, "pipe") ;
- pid = fork() ;
- switch (pid)
+ if (insist)
+ if (WIFSIGNALED(fdwstat)) strerr_dief1x(111, "child process crashed") ;
+ else strerr_dief1x(WEXITSTATUS(fdwstat), "child process exited non-zero") ;
+ else if (def)
{
- case -1: strerr_diefu1sys(111, "fork") ;
- case 0:
- argv[argc1] = 0 ;
- fd_close(p[0]) ;
- PROG = "backtick (child)" ;
- if (fd_move(1, p[1]) < 0) strerr_diefu1sys(111, "fd_move") ;
- pathexec_run(argv[0], argv, envp) ;
- strerr_dieexec(111, argv[0]) ;
+ modif.len = modifstart ;
+ if (!stralloc_cats(&modif, def)) strerr_diefu1sys(111, "stralloc_catb") ;
}
- fd_close(p[1]) ;
- if (!slurp(&modif, p[0])) strerr_diefu1sys(111, "slurp") ;
- fd_close(p[0]) ;
- if (wait_pid(pid, &p[0]) < 0) strerr_diefu1sys(111, "wait_pid") ;
- if (insist && wait_status(p[0]))
- strerr_dief1x(wait_status(p[0]), "child process exited non-zero") ;
}
if (argc == argc1 - 1) return 0 ;
if (!stralloc_0(&modif)) strerr_diefu1sys(111, "stralloc_catb") ;
@@ -73,6 +74,13 @@ int main (int argc, char const **argv, char const *const *envp)
{
if (insist)
strerr_dief1x(1, "child process output contained a null character") ;
+ else if (def)
+ {
+ modif.len = modifstart ;
+ if (!stralloc_catb(&modif, def, str_len(def)+1))
+ strerr_diefu1sys(111, "stralloc_catb") ;
+ strerr_warnw2x("child process output contained a null character", " - using default instead") ;
+ }
else
modif.len = reallen + 1 ;
}
--
cgit v1.2.3