aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/sys.c')
-rw-r--r--sys/cmd/rc/sys.c139
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");
+}