#include "rc.h" // ----------------------------------------------------------------------- // internal static char** mkargv(Word *args) { char **argv=emalloc((count(args)+2)*sizeof(char *)); char **argp=argv+1; /* leave one at front for runcoms */ for(;args;args=args->link) *argp++=args->str; *argp=nil; return argv; } static Word* envval(char *s) { Word *v; char *t, c; for(t=s; *t && *t!='\1'; t++) ; c = *t; *t = '\0'; v = makeword(s, (c=='\0') ? nil : envval(t+1)); *t=c; return v; } // ----------------------------------------------------------------------- // exported void initenv(void) { extern char **environ; char *s; char **env; for(env=environ; *env; env++) { for(s=*env; *s && *s != '(' && *s != '='; s++) ; switch(*s){ case '\0': break; case '(': /* ignore functions */ break; case '=': *s = '\0'; setvar(*env, envval(s+1)); *s = '='; break; } } } void execute(Word *cmd, Word *path) { int nc; char **argv = mkargv(cmd); char **env = mkenv(); char file[1024]; for(; path; path=path->link){ nc = strlen(path->str); if(nc < arrlen(file)){ strcpy(file, path->str); if(file[0]){ strcat(file, "/"); nc++; } if(nc+strlen(argv[1]) < arrlen(file)){ strcat(file, argv[1]); execve(file, argv+1, env); }else fatal("command name too long"); } } print(shell.err, "could not execute command: %s\n", argv[1]); efree(argv); } void redirect(Redir *r) { if(r){ redirect(r->link); switch(r->type){ case Ropen: if(r->from != r->to){ dup2(r->from, r->to); close(r->from); } break; case Rdupfd: dup2(r->from, r->to); // TODO: error checking break; case Rclose: close(r->from); break; default: fatal("unrecognized redirection type %d\n", r->type); } } } int mapfd(int fd) { Redir *r; for(r = runner->redir.end; r; r = r->link){ switch(r->type){ case Rclose: if(r->from == fd) fd = -1; break; case Rdupfd: case Ropen: if(r->to == fd) fd = r->from; break; } } return fd; }