diff options
Diffstat (limited to 'appl/cmd/sh/sh.b')
| -rw-r--r-- | appl/cmd/sh/sh.b | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/appl/cmd/sh/sh.b b/appl/cmd/sh/sh.b index 6040457f..05a8227a 100644 --- a/appl/cmd/sh/sh.b +++ b/appl/cmd/sh/sh.b @@ -81,7 +81,6 @@ YYMAXDEPTH: con 200; EPERM: con "permission denied"; EPIPE: con "write on closed pipe"; -SHELLRC: con "lib/profile"; LIBSHELLRC: con "/lib/sh/profile"; BUILTINPATH: con "/dis/sh"; @@ -191,8 +190,6 @@ loop: while (argv != nil && hd argv != nil && (hd argv)[0] == '-') { runscript(ctxt, LIBSHELLRC, nil, 0); if (argv == nil) { - if (opts.lflag) - runscript(ctxt, SHELLRC, nil, 0); if (isconsole(sys->fildes(0))) interactive |= ctxt.INTERACTIVE; ctxt.setoptions(interactive, 1); @@ -256,7 +253,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; @@ -310,7 +307,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; @@ -495,6 +492,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) @@ -506,11 +525,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 => @@ -849,7 +872,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; @@ -859,7 +882,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)); @@ -885,7 +908,7 @@ externalexec(mod: Command, { mod->init(drawcontext, argv); } - exception e{ + exception { EPIPE => raise "fail:" + EPIPE; } @@ -1512,6 +1535,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]; } @@ -1852,10 +1877,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) |
