summaryrefslogtreecommitdiff
path: root/src/execline/forstdin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/execline/forstdin.c')
-rw-r--r--src/execline/forstdin.c114
1 files changed, 53 insertions, 61 deletions
diff --git a/src/execline/forstdin.c b/src/execline/forstdin.c
index 336aaa4..bacb1ae 100644
--- a/src/execline/forstdin.c
+++ b/src/execline/forstdin.c
@@ -9,16 +9,14 @@
#include <skalibs/strerr2.h>
#include <skalibs/stralloc.h>
#include <skalibs/genalloc.h>
-#include <skalibs/env.h>
#include <skalibs/sig.h>
#include <skalibs/djbunix.h>
#include <skalibs/skamisc.h>
#include <skalibs/netstring.h>
-#include <execline/config.h>
#include <execline/execline.h>
-#define USAGE "forstdin [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -N | -n ] [ -C | -c ] [ -0 | -d delim ] var command..."
+#define USAGE "forstdin [ -E | -e ] [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -N | -n ] [ -C | -c ] [ -0 | -d delim ] var command..."
#define dieusage() strerr_dieusage(100, USAGE)
static genalloc pids = GENALLOC_ZERO ; /* pid_t */
@@ -45,19 +43,20 @@ static void parallel_sigchld_handler (int sig)
(void)sig ;
}
-int main (int argc, char const **argv, char const *const *envp)
+int main (int argc, char const **argv)
{
+ stralloc value = STRALLOC_ZERO ;
char const *delim = "\n" ;
size_t delimlen = 1 ;
size_t nbc = 0 ;
unsigned short okcodes[256] ;
- int crunch = 0, chomp = 1, not = 1, eofcode = 1 ;
+ int crunch = 0, chomp = 1, not = 1, eofcode = 1, doimport = 0 ;
PROG = "forstdin" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "pNnCc0d:o:x:", &l) ;
+ int opt = subgetopt_r(argc, argv, "pNnCc0d:o:x:Ee", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -81,81 +80,74 @@ int main (int argc, char const **argv, char const *const *envp)
not = 1 ;
if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
break ;
+ case 'E' : doimport = 1 ; break ;
+ case 'e' : doimport = 0 ; break ;
default : dieusage() ;
}
}
argc -= l.ind ; argv += l.ind ;
}
if (argc < 2) dieusage() ;
+ if (!argv[0][0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ;
+
+ if (pids.s)
{
- stralloc modif = STRALLOC_ZERO ;
- size_t envlen = env_len(envp) ;
- size_t modifstart = strlen(argv[0]) + 1 ;
- char const *newenv[envlen + 2] ;
- if (!stralloc_ready(&modif, modifstart+1))
- strerr_diefu1sys(111, "stralloc_ready") ;
- memcpy(modif.s, argv[0], modifstart - 1) ;
- modif.s[modifstart-1] = '=' ;
- if (pids.s)
- {
- if (sig_catch(SIGCHLD, &parallel_sigchld_handler) < 0)
- strerr_diefu1sys(111, "install SIGCHLD handler") ;
- }
- for (;;)
+ if (sig_catch(SIGCHLD, &parallel_sigchld_handler) < 0)
+ strerr_diefu1sys(111, "install SIGCHLD handler") ;
+ }
+ for (;;)
+ {
+ pid_t pid ;
+ value.len = 0 ;
+ if (delimlen)
{
- pid_t pid ;
- modif.len = modifstart ;
- if (delimlen)
- {
- int r = skagetlnsep(buffer_0, &modif, delim, delimlen) ;
- if (!r) break ;
- else if (r < 0)
- {
- if (errno != EPIPE) strerr_diefu1sys(111, "skagetlnsep") ;
- if (chomp) break ;
- }
- if (crunch && modif.len == modifstart + 1) continue ;
- if (chomp) modif.len-- ;
- }
- else
+ int r = skagetlnsep(buffer_0, &value, delim, delimlen) ;
+ if (!r) break ;
+ else if (r < 0)
{
- size_t unread = 0 ;
- if (netstring_get(buffer_0, &modif, &unread) <= 0)
- {
- if (netstring_okeof(buffer_0, unread)) break ;
- else strerr_diefu1sys(111, "netstring_get") ;
- }
- }
- eofcode = 0 ;
- if (!stralloc_0(&modif)) strerr_diefu1sys(111, "stralloc_0") ;
- if (!env_mergen(newenv, envlen+2, envp, envlen, modif.s, modif.len, 1))
- strerr_diefu1sys(111, "merge environment") ;
- if (pids.s) sig_block(SIGCHLD) ;
- pid = el_spawn0(argv[1], argv + 1, newenv) ;
- if (!pid) strerr_diefu2sys(111, "spawn ", argv[1]) ;
- if (pids.s)
- {
- if (!genalloc_append(pid_t, &pids, &pid))
- strerr_diefu1sys(111, "genalloc_append") ;
- sig_unblock(SIGCHLD) ;
+ if (errno != EPIPE) strerr_diefu1sys(111, "skagetlnsep") ;
+ if (chomp) break ;
}
- else
+ if (crunch && value.len == 1) continue ;
+ if (chomp) value.len-- ;
+ }
+ else
+ {
+ size_t unread = 0 ;
+ if (netstring_get(buffer_0, &value, &unread) <= 0)
{
- int wstat ;
- if (wait_pid(pid, &wstat) < 0)
- strerr_diefu2sys(111, "wait for ", argv[1]) ;
- if (not == isok(okcodes, nbc, wait_estatus(wstat)))
- return wait_estatus(wstat) ;
+ if (netstring_okeof(buffer_0, unread)) break ;
+ else strerr_diefu1sys(111, "netstring_get") ;
}
}
- stralloc_free(&modif) ;
+ eofcode = 0 ;
+ if (!stralloc_0(&value)) strerr_diefu1sys(111, "stralloc_0") ;
+ if (pids.s) sig_block(SIGCHLD) ;
+ pid = el_modif_and_spawn(argv + 1, argv[0], value.s, doimport) ;
+ if (!pid) strerr_diefu2sys(111, "spawn ", argv[1]) ;
+ if (pids.s)
+ {
+ if (!genalloc_append(pid_t, &pids, &pid))
+ strerr_diefu1sys(111, "genalloc_append") ;
+ sig_unblock(SIGCHLD) ;
+ }
+ else
+ {
+ int wstat ;
+ if (wait_pid(pid, &wstat) < 0)
+ strerr_diefu2sys(111, "wait for ", argv[1]) ;
+ if (not == isok(okcodes, nbc, wait_estatus(wstat)))
+ return wait_estatus(wstat) ;
+ }
}
if (pids.s)
+ {
for (;;)
{
sig_block(SIGCHLD) ;
if (!pids.len) break ;
sig_pause() ;
}
+ }
return eofcode ;
}