aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rc/haventfork.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-23 18:04:08 +0000
committerrsc <devnull@localhost>2003-11-23 18:04:08 +0000
commitf08fdedcee12c06e3ce9ac9bec363915978e8289 (patch)
treed67a27473be1e8f98d3694028104d9ddf915345b /src/cmd/rc/haventfork.c
parent5993a8f2756bc455101a8c9ce95347d5050e7883 (diff)
downloadplan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.gz
plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.bz2
plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.zip
Plan 9's rc.
not a clear win over byron's, but at least it has the right syntax.
Diffstat (limited to 'src/cmd/rc/haventfork.c')
-rw-r--r--src/cmd/rc/haventfork.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/src/cmd/rc/haventfork.c b/src/cmd/rc/haventfork.c
new file mode 100644
index 00000000..fc8f7608
--- /dev/null
+++ b/src/cmd/rc/haventfork.c
@@ -0,0 +1,211 @@
+#include "rc.h"
+#include "getflags.h"
+#include "exec.h"
+#include "io.h"
+#include "fns.h"
+
+int havefork = 0;
+
+static char **
+rcargv(char *s)
+{
+ int argc;
+ char **argv;
+ word *p;
+
+ p = vlook("*")->val;
+ argv = malloc((count(p)+6)*sizeof(char*));
+ argc = 0;
+ argv[argc++] = argv0;
+ if(flag['e'])
+ argv[argc++] = "-Se";
+ else
+ argv[argc++] = "-S";
+ argv[argc++] = "-c";
+ argv[argc++] = s;
+ for(p = vlook("*")->val; p; p = p->next)
+ argv[argc++] = p->word;
+ argv[argc] = 0;
+ return argv;
+}
+
+void
+Xasync(void)
+{
+ uint pid;
+ char buf[20], **argv;
+
+ Updenv();
+
+ argv = rcargv(runq->code[runq->pc].s);
+ pid = ForkExecute(argv0, argv, -1, 1, 2);
+ free(argv);
+
+ if(pid == 0) {
+ Xerror("proc failed");
+ return;
+ }
+
+ runq->pc++;
+ sprint(buf, "%d", pid);
+ setvar("apid", newword(buf, (word *)0));
+}
+
+void
+Xbackq(void)
+{
+ char wd[8193], **argv;
+ int c;
+ char *s, *ewd=&wd[8192], *stop;
+ struct io *f;
+ var *ifs = vlook("ifs");
+ word *v, *nextv;
+ int pfd[2];
+ int pid;
+
+ stop = ifs->val?ifs->val->word:"";
+ if(pipe(pfd)<0){
+ Xerror("can't make pipe");
+ return;
+ }
+
+ Updenv();
+
+ argv = rcargv(runq->code[runq->pc].s);
+ pid = ForkExecute(argv0, argv, -1, pfd[1], 2);
+ free(argv);
+
+ close(pfd[1]);
+
+ if(pid == 0) {
+ Xerror("proc failed");
+ close(pfd[0]);
+ return;
+ }
+
+ f = openfd(pfd[0]);
+ s = wd;
+ v = 0;
+ while((c=rchr(f))!=EOF){
+ if(strchr(stop, c) || s==ewd){
+ if(s!=wd){
+ *s='\0';
+ v=newword(wd, v);
+ s=wd;
+ }
+ }
+ else *s++=c;
+ }
+ if(s!=wd){
+ *s='\0';
+ v=newword(wd, v);
+ }
+ closeio(f);
+ Waitfor(pid, 1);
+ /* v points to reversed arglist -- reverse it onto argv */
+ while(v){
+ nextv=v->next;
+ v->next=runq->argv->words;
+ runq->argv->words=v;
+ v=nextv;
+ }
+ runq->pc++;
+}
+
+void
+Xpipe(void)
+{
+ thread *p=runq;
+ int pc=p->pc, pid;
+ int rfd=p->code[pc+1].i;
+ int pfd[2];
+ char **argv;
+
+ if(pipe(pfd)<0){
+ Xerror1("can't get pipe");
+ return;
+ }
+
+ Updenv();
+
+ argv = rcargv(runq->code[pc+2].s);
+ pid = ForkExecute(argv0, argv, 0, pfd[1], 2);
+ free(argv);
+ close(pfd[1]);
+
+ if(pid == 0) {
+ Xerror("proc failed");
+ close(pfd[0]);
+ return;
+ }
+
+ start(p->code, pc+4, runq->local);
+ pushredir(ROPEN, pfd[0], rfd);
+ p->pc=p->code[pc+3].i;
+ p->pid=pid;
+}
+
+void
+Xpipefd(void)
+{
+ Abort();
+}
+
+void
+Xsubshell(void)
+{
+ char **argv;
+ int pid;
+
+ Updenv();
+
+ argv = rcargv(runq->code[runq->pc].s);
+ pid = ForkExecute(argv0, argv, -1, 1, 2);
+ free(argv);
+
+ if(pid < 0) {
+ Xerror("proc failed");
+ return;
+ }
+
+ Waitfor(pid, 1);
+ runq->pc++;
+}
+
+/*
+ * start a process running the cmd on the stack and return its pid.
+ */
+int
+execforkexec(void)
+{
+ char **argv;
+ char file[1024];
+ int nc;
+ word *path;
+ int pid;
+
+ if(runq->argv->words==0)
+ return -1;
+ argv = mkargv(runq->argv->words);
+
+ for(path = searchpath(runq->argv->words->word);path;path = path->next){
+ nc = strlen(path->word);
+ if(nc<sizeof(file)){
+ strcpy(file, path->word);
+ if(file[0]){
+ strcat(file, "/");
+ nc++;
+ }
+ if(nc+strlen(argv[1])<sizeof(file)){
+ strcat(file, argv[1]);
+ pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2));
+ if(pid >= 0){
+ free(argv);
+ return pid;
+ }
+ }
+ }
+ }
+ free(argv);
+ return -1;
+}