diff options
author | Nicholas Noll <nbnoll@eml.cc> | 2021-10-20 13:10:54 -0700 |
---|---|---|
committer | Nicholas Noll <nbnoll@eml.cc> | 2021-10-20 13:10:54 -0700 |
commit | 888679027c2e9b43d1485d970df8170ac4fda29f (patch) | |
tree | f46c257e6be1f47f4aa69d31a64643c76457a64b /sys/cmd/rc/lex.c | |
parent | 6d50d5b97d49a74a8faf587ec2bbf234626adf0c (diff) |
Refactored interactivity to track with thread.
Hit a bit of a stopping point. Specifically, the way XAsync runs
currently is by forking the execution context and having the child run
the async code while the parent runs the remainder. The problem with
this architecture is it doesn't interact well with job control. When we
fork, we create a new process group. Thus the Xasync fork becomes the
new leader.
In short, our traversal of the parse tree as to be less "preorder" and
more "in order", i.e. from the leaves up. The "left" command of the
pipeline should be the "leader" of the process group.
Diffstat (limited to 'sys/cmd/rc/lex.c')
-rw-r--r-- | sys/cmd/rc/lex.c | 97 |
1 files changed, 93 insertions, 4 deletions
diff --git a/sys/cmd/rc/lex.c b/sys/cmd/rc/lex.c index 4325882..373edd5 100644 --- a/sys/cmd/rc/lex.c +++ b/sys/cmd/rc/lex.c @@ -187,10 +187,6 @@ yylex(void) put3('E','O','F'); return EOF; - case '&': - put1('&'); - return '&'; - case '@': put1('@'); return Tsubshell; @@ -199,6 +195,99 @@ yylex(void) put1('!'); return Tbang; + case '&': + put1('&'); + return '&'; + + case '|': + if(nextis('|')){ + put2('|','|'); + return Toror; + } + node = maketree(); + *w++ = '|'; + + node->type = Tpipe; + node->redir.fd[0] = 1; + node->redir.fd[1] = 1; + goto redir; + + case '>': + node = maketree(); + *w++ = '>'; + node->type = Tredir; + + if(nextis('>')){ + node->redir.type = Rappend; + *w++ = '>'; + }else + node->redir.type = Rwrite; + node->redir.fd[0] = 1; + goto redir; + + case '<': + node = maketree(); + *w++ = '<'; + node->type = Tredir; + + if(nextis('<')){ + node->redir.type = Rhere; + *w++ = '<'; + }else if(nextis('>')){ + node->redir.type = Rrdwr; + *w++ = '>'; + }else{ + node->redir.type = Rread; + } + node->redir.fd[0] = 0; + /* fallthrough */ + redir: + if(nextis('[')){ + *w++='['; + c = advance(); + *w++ = c; + if(c < '0' || '9' < c){ + badredir: + *w = 0; + yyerror(node->type == Tpipe ? "pipe syntax" : "redirection syntax"); + return EOF; + } + node->redir.fd[0] = 0; + do{ + node->redir.fd[0] = 10*node->redir.fd[0]+(c-'0'); + *w++ = c; + c = advance(); + }while('0'<=c && c<='9'); + + if(c == '='){ + *w++ = '='; + if(node->type==Tredir) + node->type = Tdup; + c = advance(); + } + if(c < '0' || '9' < c){ + if(node->type == Tpipe) + goto badredir; + node->redir.type = Rclose; + }else{ + node->redir.type = Rdup; + node->redir.fd[1] = node->redir.fd[0]; + node->redir.fd[0] = 0; + do{ + node->redir.fd[0] = 10*node->redir.fd[0]+(c-'0'); + *w++ = c; + c = advance(); + }while('0'<=c && c<='9'); + } + if(c != ']' || (node->type == Tdup && (node->redir.type = Rhere || node->redir.type == Rappend))) + goto badredir; + *w++ = ']'; + } + *w++ = 0; + yylval.tree = node; + + return node->type; + case '$': if(nextis('#')){ put2('$','#'); |