URI:
       thaventfork.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       thaventfork.c (3122B)
       ---
            1 #include "rc.h"
            2 #include "getflags.h"
            3 #include "exec.h"
            4 #include "io.h"
            5 #include "fns.h"
            6 
            7 int havefork = 0;
            8 
            9 static char **
           10 rcargv(char *s)
           11 {
           12         int argc;
           13         char **argv;
           14         word *p;
           15 
           16         p = vlook("*")->val;
           17         argv = malloc((count(p)+6)*sizeof(char*));
           18         argc = 0;
           19         argv[argc++] = argv0;
           20         if(flag['e'])
           21                 argv[argc++] = "-Se";
           22         else
           23                 argv[argc++] = "-S";
           24         argv[argc++] = "-c";
           25         argv[argc++] = s;
           26         for(p = vlook("*")->val; p; p = p->next)
           27                 argv[argc++] = p->word;
           28         argv[argc] = 0;
           29         return argv;
           30 }
           31 
           32 void
           33 Xasync(void)
           34 {
           35         uint pid;
           36         char buf[20], **argv;
           37 
           38         Updenv();
           39 
           40         argv = rcargv(runq->code[runq->pc].s);
           41         pid = ForkExecute(argv0, argv, -1, 1, 2);
           42         free(argv);
           43 
           44         if(pid == 0) {
           45                 Xerror("proc failed");
           46                 return;
           47         }
           48 
           49         runq->pc++;
           50         sprint(buf, "%d", pid);
           51         setvar("apid", newword(buf, (word *)0));
           52 }
           53 
           54 void
           55 Xbackq(void)
           56 {
           57         char wd[8193], **argv;
           58         int c;
           59         char *s, *ewd=&wd[8192], *stop;
           60         struct io *f;
           61         var *ifs = vlook("ifs");
           62         word *v, *nextv;
           63         int pfd[2];
           64         int pid;
           65 
           66         stop = ifs->val?ifs->val->word:"";
           67         if(pipe(pfd)<0){
           68                 Xerror("can't make pipe");
           69                 return;
           70         }
           71 
           72         Updenv();
           73 
           74         argv = rcargv(runq->code[runq->pc].s);
           75         pid = ForkExecute(argv0, argv, -1, pfd[1], 2);
           76         free(argv);
           77 
           78         close(pfd[1]);
           79 
           80         if(pid == 0) {
           81                 Xerror("proc failed");
           82                 close(pfd[0]);
           83                 return;
           84         }
           85 
           86         f = openfd(pfd[0]);
           87         s = wd;
           88         v = 0;
           89         while((c=rchr(f))!=EOF){
           90                 if(strchr(stop, c) || s==ewd){
           91                         if(s!=wd){
           92                                 *s='\0';
           93                                 v=newword(wd, v);
           94                                 s=wd;
           95                         }
           96                 }
           97                 else *s++=c;
           98         }
           99         if(s!=wd){
          100                 *s='\0';
          101                 v=newword(wd, v);
          102         }
          103         closeio(f);
          104         Waitfor(pid, 1);
          105         /* v points to reversed arglist -- reverse it onto argv */
          106         while(v){
          107                 nextv=v->next;
          108                 v->next=runq->argv->words;
          109                 runq->argv->words=v;
          110                 v=nextv;
          111         }
          112         runq->pc++;
          113 }
          114 
          115 void
          116 Xpipe(void)
          117 {
          118         thread *p=runq;
          119         int pc=p->pc, pid;
          120         int rfd=p->code[pc+1].i;
          121         int pfd[2];
          122         char **argv;
          123 
          124         if(pipe(pfd)<0){
          125                 Xerror1("can't get pipe");
          126                 return;
          127         }
          128 
          129         Updenv();
          130 
          131         argv = rcargv(runq->code[pc+2].s);
          132         pid = ForkExecute(argv0, argv, 0, pfd[1], 2);
          133         free(argv);
          134         close(pfd[1]);
          135 
          136         if(pid == 0) {
          137                 Xerror("proc failed");
          138                 close(pfd[0]);
          139                 return;
          140         }
          141 
          142         start(p->code, pc+4, runq->local);
          143         pushredir(ROPEN, pfd[0], rfd);
          144         p->pc=p->code[pc+3].i;
          145         p->pid=pid;
          146 }
          147 
          148 void
          149 Xpipefd(void)
          150 {
          151         Abort();
          152 }
          153 
          154 void
          155 Xsubshell(void)
          156 {
          157         char **argv;
          158         int pid;
          159 
          160         Updenv();
          161 
          162         argv = rcargv(runq->code[runq->pc].s);
          163         pid = ForkExecute(argv0, argv, -1, 1, 2);
          164         free(argv);
          165 
          166         if(pid < 0) {
          167                 Xerror("proc failed");
          168                 return;
          169         }
          170 
          171         Waitfor(pid, 1);
          172         runq->pc++;
          173 }
          174 
          175 /*
          176  *  start a process running the cmd on the stack and return its pid.
          177  */
          178 int
          179 execforkexec(void)
          180 {
          181         char **argv;
          182         char file[1024];
          183         int nc;
          184         word *path;
          185         int pid;
          186 
          187         if(runq->argv->words==0)
          188                 return -1;
          189         argv = mkargv(runq->argv->words);
          190 
          191         for(path = searchpath(runq->argv->words->word);path;path = path->next){
          192                 nc = strlen(path->word);
          193                 if(nc<sizeof(file)){
          194                         strcpy(file, path->word);
          195                         if(file[0]){
          196                                 strcat(file, "/");
          197                                 nc++;
          198                         }
          199                         if(nc+strlen(argv[1])<sizeof(file)){
          200                                 strcat(file, argv[1]);
          201                                 pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2));
          202                                 if(pid >= 0){
          203                                         free(argv);
          204                                         return pid;
          205                                 }
          206                         }
          207                 }
          208         }
          209         free(argv);
          210         return -1;
          211 }