summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2015-01-27 01:11:13 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2015-01-27 01:11:13 +0000
commita1f847eae994d665d01b85b0fd1a69492455f3ec (patch)
tree6e95b9da46cc0a735ef1f75ae0ad20bcbe61c915
parent86aa8c6429885ecde3c4cbbb9528fc82f024f40a (diff)
downloadexecline-a1f847eae994d665d01b85b0fd1a69492455f3ec.tar.xz
- Added -D option to backtick
- Doc updated
-rw-r--r--doc/backtick.html12
-rw-r--r--doc/forbacktickx.html2
-rw-r--r--doc/forx.html2
-rw-r--r--doc/index.html7
-rw-r--r--src/execline/backtick.c52
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.
</p>
<pre>
- backtick [ -i ] [ -n ] <em>variable</em> { <em>prog1...</em> } <em>prog2...</em>
+ backtick [ -i | -D <em>default</em> ] [ -n ] <em>variable</em> { <em>prog1...</em> } <em>prog2...</em>
</pre>
<ul>
@@ -45,9 +45,13 @@ output as a value. </li>
<h2> Options </h2>
<ul>
- <li> <tt>-i</tt>&nbsp;: insist. If <em>prog1</em> exits non-zero,
+ <li> <tt>-i</tt>&nbsp;: insist. If <em>prog1</em> crashes or exits non-zero,
<tt>backtick</tt> exits with the same exit code (or 111 if <em>prog1</em>
-crashed for some reason). Without this option, <tt>backtick</tt> execs into
+crashed). </li>
+ <li> <tt>-D&nbsp;<em>default</em></tt>&nbsp;: default value. If
+<em>prog1</em> crashes or exits non-zero, <em>default</em> is used as
+<em>variable</em>'s value. If neither the <tt>-i</tt> nor the <tt>-D</tt>
+option have been given, <tt>backtick</tt> execs into
<em>prog2...</em> no matter what <em>prog1</em> does, with the null word as
<em>variable</em>'s value if <em>prog1</em> didn't write anything before
dying. </li>
@@ -58,7 +62,7 @@ output. </li>
<h2> Notes </h2>
<ul>
- <li> You can start <em>prog2...</em> with "import <em>variable</em> unexport <em>variable</em>"
+ <li> You can start <em>prog2...</em> with "import -u <em>variable</em>"
to perform variable substitution. </li>
</ul>
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 <em>x</em>. </li>
<h2> Notes </h2>
<ul>
- <li> You can start <em>loop...</em> with "import <em>variable</em> unexport <em>variable</em>"
+ <li> You can start <em>loop...</em> with "import -u <em>variable</em>"
to perform variable substitution.
</ul>
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. </li>
<h2> Notes </h2>
<ul>
- <li> You can start <em>loop</em> with "import <em>variable</em> unexport <em>variable</em>"
+ <li> You can start <em>loop</em> with "import -u <em>variable</em>"
if you want variable substitution. </li>
</ul>
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.
<ul>
<li> A POSIX-compliant system with a standard C development environment </li>
- <li> GNU make, version 4.0 or later </li>
+ <li> GNU make, version 4.0 or later. Please be aware that execline will
+not build with an earlier version. </li>
<li> <a href="http://skarnet.org/software/skalibs/">skalibs</a> version
-2.2.1.0 or later </li>
+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. </li>
</ul>
<h3> Licensing </h3>
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 <sys/types.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <skalibs/bytestr.h>
#include <skalibs/sgetopt.h>
@@ -9,25 +10,29 @@
#include <skalibs/djbunix.h>
#include <execline/execline.h>
-#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 ;
}