summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2007-10-03 13:07:24 +0000
committerCharles.Forsyth <devnull@localhost>2007-10-03 13:07:24 +0000
commit1311e23dda88a63b0497469995cbfa52c2432671 (patch)
tree332b3d04cccd35d0cc9e5279174e5cd83dbf2dc4
parent2b1e4b84370b327f5eb17c9ba8bc44f4296e4a86 (diff)
20071003-1406
-rw-r--r--CHANGES1
-rw-r--r--appl/cmd/sh/sh.b51
-rw-r--r--appl/cmd/sh/sh.y48
-rw-r--r--appl/cmd/sh/tk.b38
-rw-r--r--include/version.h2
5 files changed, 101 insertions, 39 deletions
diff --git a/CHANGES b/CHANGES
index 621458f5..517d423a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,6 @@
20071002
ensure fmtdef.h included by some lib9 functions so that va_copy is defined on older systems that lack that needless notion
+ <{} and >{} added to sh(1)
20070929
move emu/MacOSX/mkfile to .../mkfile-x11 and replace it by the variant that builds for Carbon, now the default
20070927
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)
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)
diff --git a/appl/cmd/sh/tk.b b/appl/cmd/sh/tk.b
index bc6fe753..31040c45 100644
--- a/appl/cmd/sh/tk.b
+++ b/appl/cmd/sh/tk.b
@@ -118,7 +118,6 @@ builtin_tk(ctxt: ref Context, argv: list of ref Listnode): string
argv = tl argv;
if (len argv < 1 || !isnum((hd argv).word))
ctxt.fail("usage", "usage: tk onscreen winid [how]");
- wid := (hd argv).word;
how := "";
if(tl argv != nil)
how = word(hd tl argv);
@@ -232,22 +231,35 @@ sbuiltin_alt(ctxt: ref Context, argv: list of ref Listnode): list of ref Listnod
argv = tl argv;
if (argv == nil)
ctxt.fail("usage", "usage: alt chan...");
- ca := array[len argv] of chan of string;
- cname := array[len ca] of string;
+ nc := len argv;
+ kbd := array[nc] of chan of int;
+ ptr := array[nc] of chan of ref Draw->Pointer;
+ ca := array[nc * 3] of chan of string;
+ win := array[nc] of ref Tk->Toplevel;
+
+ cname := array[nc] of string;
i := 0;
for (; argv != nil; argv = tl argv) {
- ca[i] = egetchan(ctxt, hd argv);
- cname[i] = (hd argv).word;
+ w := (hd argv).word;
+ ca[i*3] = egetchan(ctxt, hd argv);
+ cname[i] = w;
+ if(isnum(w)){
+ win[i] = egetwin(ctxt, hd argv);
+ ca[i*3+1] = win[i].ctxt.ctl;
+ ca[i*3+2] = win[i].wreq;
+ ptr[i] = win[i].ctxt.ptr;
+ kbd[i] = win[i].ctxt.kbd;
+ }
i++;
}
- n := 0;
- v: string;
- if (i == 1)
- v = <-ca[0];
- else
- (n, v) = <-ca;
-
- return ref Listnode(nil, cname[n]) :: ref Listnode(nil, v) :: nil;
+ for(;;) alt{
+ (n, key) := <-kbd =>
+ tk->keyboard(win[n], key);
+ (n, p) := <-ptr =>
+ tk->pointer(win[n], *p);
+ (n, v) := <-ca =>
+ return ref Listnode(nil, cname[n/3]) :: ref Listnode(nil, v) :: nil;
+ }
}
sbuiltin_recv(ctxt: ref Context, argv: list of ref Listnode): list of ref Listnode
diff --git a/include/version.h b/include/version.h
index c560352d..b69de01c 100644
--- a/include/version.h
+++ b/include/version.h
@@ -1 +1 @@
-#define VERSION "Fourth Edition (20071002)"
+#define VERSION "Fourth Edition (20071003)"