From ce05175372a9ddca1a225db0765ace1127a39293 Mon Sep 17 00:00:00 2001 From: Nicholas Date: Fri, 12 Nov 2021 09:22:01 -0800 Subject: chore: simplified organizational structure --- src/cmd/rc/sys.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/cmd/rc/sys.c (limited to 'src/cmd/rc/sys.c') diff --git a/src/cmd/rc/sys.c b/src/cmd/rc/sys.c new file mode 100644 index 0000000..807359d --- /dev/null +++ b/src/cmd/rc/sys.c @@ -0,0 +1,137 @@ +#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; +} -- cgit v1.2.1