summaryrefslogtreecommitdiff
path: root/appl/cmd/sh/sh.y
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/sh/sh.y')
-rw-r--r--appl/cmd/sh/sh.y48
1 files changed, 37 insertions, 11 deletions
diff --git a/appl/cmd/sh/sh.y b/appl/cmd/sh/sh.y
index 083357c1..44984a1b 100644
--- a/appl/cmd/sh/sh.y
+++ b/appl/cmd/sh/sh.y
@@ -319,7 +319,7 @@ runscript(ctxt: ref Context, path: string, args: list of ref Listnode, reporterr
runfile(ctxt, fd, path, args);
else if (reporterr)
ctxt.fail("bad script path", sys->sprint("sh: cannot open %s: %r", path));
- } exception e {
+ } exception {
"fail:*" =>
if(!reporterr)
return;
@@ -375,7 +375,7 @@ runfile(ctxt: ref Context, fd: ref Sys->FD, path: string, args: list of ref List
raise "fail:" + laststatus;
ctxt.pop();
}
- exception e {
+ exception {
"fail:*" =>
ctxt.pop();
raise;
@@ -569,6 +569,28 @@ listjoin(left, right: list of ref Listnode): list of ref Listnode
return right;
}
+pipecmd(ctxt: ref Context, cmd: list of ref Listnode, redir: ref Redir): ref Sys->FD
+{
+ if(redir.fd2 != -1 || (redir.rtype & OAPPEND))
+ ctxt.fail("bad redir", "sh: bad redirection");
+ r := *redir;
+ case redir.rtype {
+ Sys->OREAD =>
+ r.rtype = Sys->OWRITE;
+ Sys->OWRITE =>
+ r.rtype = Sys->OREAD;
+ }
+
+ p := array[2] of ref Sys->FD;
+ if(sys->pipe(p) == -1)
+ ctxt.fail("no pipe", sys->sprint("sh: cannot make pipe: %r"));
+ startchan := chan of (int, ref Expropagate);
+ spawn runasync(ctxt, 1, cmd, ref Redirlist((p[1], nil, r) :: nil), startchan);
+ p[1] = nil;
+ <-startchan;
+ return p[0];
+}
+
glomoperation(ctxt: ref Context, n: ref Node, redirs: ref Redirlist): list of ref Listnode
{
if (n == nil)
@@ -580,11 +602,15 @@ glomoperation(ctxt: ref Context, n: ref Node, redirs: ref Redirlist): list of re
nlist = ref Listnode(nil, n.word) :: nil;
n_REDIR =>
wlist := glob(glom(ctxt, n.left, ref Redirlist(nil), nil));
- if (len wlist != 1 || (hd wlist).word == nil)
+ if (len wlist != 1)
ctxt.fail("bad redir", "sh: single redirection operand required");
-
- # add to redir list
- redirs.r = Redirword(nil, (hd wlist).word, *n.redir) :: redirs.r;
+ if((hd wlist).cmd != nil){
+ fd := pipecmd(ctxt, wlist, n.redir);
+ redirs.r = Redirword(fd, nil, (n.redir.rtype, fd.fd, -1)) :: redirs.r;
+ nlist = ref Listnode(nil, "/fd/"+string fd.fd) :: nil;
+ }else{
+ redirs.r = Redirword(nil, (hd wlist).word, *n.redir) :: redirs.r;
+ }
n_DUP =>
redirs.r = Redirword(nil, "", *n.redir) :: redirs.r;
n_LIST =>
@@ -938,7 +964,7 @@ runblock(ctxt: ref Context, args: list of ref Listnode, last: int): string
status := walk(ctxt, cmd, last);
ctxt.pop();
return status;
- } exception e{
+ } exception {
"fail:*" =>
ctxt.pop();
raise;
@@ -950,7 +976,7 @@ runblock(ctxt: ref Context, args: list of ref Listnode, last: int): string
trybuiltin(ctxt: ref Context, args: list of ref Listnode, lseq: int)
: (int, string)
{
- (n, bmods) := findbuiltin(ctxt.env.builtins, (hd args).word);
+ (nil, bmods) := findbuiltin(ctxt.env.builtins, (hd args).word);
if (bmods == nil)
return (0, nil);
return (1, (hd bmods)->runbuiltin(ctxt, myself, args, lseq));
@@ -976,7 +1002,7 @@ externalexec(mod: Command,
{
mod->init(drawcontext, argv);
}
- exception e{
+ exception {
EPIPE =>
raise "fail:" + EPIPE;
}
@@ -1626,6 +1652,8 @@ patquote(word: string): string
i++;
if (i >= len word)
return outword;
+ if(word[i] == '[' && i < len word - 1 && word[i+1] == '~')
+ word[i+1] = '^';
}
outword[len outword] = word[i];
}
@@ -1987,10 +2015,8 @@ builtin_load(ctxt: ref Context, args: list of ref Listnode, nil: int): string
if (tl args == nil || (hd tl args).word == nil)
builtinusage(ctxt, "load path...");
args = tl args;
- path := (hd args).word;
if (args == nil)
builtinusage(ctxt, "load path...");
- status := "";
for (; args != nil; args = tl args) {
s := loadmodule(ctxt, (hd args).word);
if (s != nil)