diff options
author | Nicholas Noll <nbnoll@eml.cc> | 2021-10-15 16:18:02 -0700 |
---|---|---|
committer | Nicholas Noll <nbnoll@eml.cc> | 2021-10-15 16:18:02 -0700 |
commit | bf03074e346b004659196b6c17eee04dbffd3ac2 (patch) | |
tree | 7200db30f1ef7e3661091552932eb304bd4ce9c6 /sys/cmd/rc/sys.c | |
parent | 566d54fe549286895fdef8aa9f385686405dd290 (diff) |
feat(rc): working prototype of input->compile->print loop
Diffstat (limited to 'sys/cmd/rc/sys.c')
-rw-r--r-- | sys/cmd/rc/sys.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/sys/cmd/rc/sys.c b/sys/cmd/rc/sys.c new file mode 100644 index 0000000..2c6a19d --- /dev/null +++ b/sys/cmd/rc/sys.c @@ -0,0 +1,139 @@ +#include "rc.h" + +struct Wait +{ + int len, cap, *pid; +}; + +static struct Wait wait; + +// ----------------------------------------------------------------------- +// 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 +clearwait(void) +{ + wait.len = 0; +} + +int +havewait(int pid) +{ + int i; + + for(i=0; i<wait.len; i++) + if(wait.pid[i] == pid) + return 1; + return 0; +} + +void +addwait(int pid) +{ + if(wait.len == wait.cap){ + wait.cap = wait.cap + 2; + wait.pid = erealloc(wait.pid, wait.cap*sizeof(*wait.pid)); + } + wait.pid[wait.len++] = pid; +} + +/* +int +waitfor(int pid) +{ + Thread *p; + struct WaitMsg *w; + char errbuf[ERRMAX]; + + if(pid >= 0 && !havewait(pid)) + return 0; +} +*/ + +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){ + strcat(file, "/"); + nc++; + } + if(nc+strlen(argv[1]) < 1024){ + strcat(file, argv[1]); + execve(file, argv+1, env); + }else + fatal("command name too long"); + } + } + efree(argv); + fatal("failed to exec\n"); +} |