Logo Search packages:      
Sourcecode: 9base version File versions  Download package

haventfork.c

#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;
}

Generated by  Doxygen 1.6.0   Back to index