summaryrefslogtreecommitdiff
path: root/sys/src/cmd/rc/haventfork.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/rc/haventfork.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/rc/haventfork.c')
-rwxr-xr-xsys/src/cmd/rc/haventfork.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/sys/src/cmd/rc/haventfork.c b/sys/src/cmd/rc/haventfork.c
new file mode 100755
index 000000000..a5464ba5b
--- /dev/null
+++ b/sys/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 - 1){ /* 1 for / */
+ 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;
+}