2 * Plan 9 versions of system-specific functions
3 * By convention, exported routines herein have names beginning with an
12 "sigexit", "sighup", "sigint", "sigquit",
13 "sigalrm", "sigkill", "sigfpe", "sigterm",
16 char *syssigname[] = {
17 "exit", /* can't happen */
20 "quit", /* can't happen */
27 char Rcmain[]="/rc/lib/rcmain";
28 char Fdprefix[]="/fd/";
36 "exec", execexec, /* but with popword first */
55 dir = open("/env", OREAD);
57 pfmt(err, "rc: can't open /env: %r\n");
62 nent = dirread(dir, &ent);
65 for(i = 0; i<nent; i++){
67 if(len && strncmp(ent[i].name, "fn#", 3)!=0){
68 snprint(envname, sizeof envname, "/env/%s", ent[i].name);
69 if((f = open(envname, 0))>=0){
70 buf = emalloc((int)len+1);
71 read(f, buf, (long)len);
73 /* Charitably add a 0 at the end if need be */
78 while(s!=buf && s[-1]!='\0') --s;
79 val = newword(s, val);
84 setvar(ent[i].name, val);
85 vlook(ent[i].name)->changed = 0;
101 static Dir *ent, *allocent;
109 nent = dirread(envdir, &allocent);
118 if(len && strncmp(e->name, "fn#", 3)==0){
119 snprint(envname, sizeof envname, "/env/%s", e->name);
120 if((f = open(envname, 0))>=0){
135 static int first = 1;
144 envdir = open("/env", 0);
146 pfmt(err, "rc: can't open /env: %r\n");
149 start(rdfns, 1, runq->local);
153 Waitfor(int pid, int persist)
159 while((w = wait()) != nil){
165 for(p = runq->ret;p;p = p->ret)
168 strcpy(p->status, w->msg);
173 errstr(errbuf, sizeof errbuf);
174 if(strcmp(errbuf, "interrupted")==0) return -1;
181 char **argv = (char **)emalloc((count(a)+2)*sizeof(char *));
182 char **argp = argv+1; /* leave one at front for runcoms */
183 for(;a;a = a->next) *argp++=a->word;
197 snprint(envname, sizeof envname, "/env/%s", v->name);
198 if((f = Creat(envname))<0)
199 pfmt(err, "rc: can't open %s: %r\n", envname);
201 for(w = v->val;w;w = w->next)
202 write(f, w->word, strlen(w->word)+1L);
208 snprint(envname, sizeof envname, "/env/fn#%s", v->name);
209 if((f = Creat(envname))<0)
210 pfmt(err, "rc: can't open %s: %r\n", envname);
214 pfmt(fd, "fn %q %s\n", v->name, v->fn[v->pc-1].s);
226 updenvlocal(v->next);
235 for(h = gvar;h!=&gvar[NVAR];h++)
236 for(v=*h;v;v = v->next)
239 updenvlocal(runq->local);
243 ForkExecute(char *file, char **argv, int sin, int sout, int serr)
248 fprint(2, "forkexec %s", file);
249 for(i = 0; argv[i]; i++)fprint(2, " %s", argv[i]);
250 fprint(2, " %d %d %d\n", sin, sout, serr);
252 if(access(file, 1) != 0)
254 fprint(2, "forking\n");
255 switch(pid = fork()){
271 fprint(2, "execing\n");
273 fprint(2, "exec: %r\n");
280 Execute(word *args, word *path)
282 char **argv = mkargv(args);
286 for(;path;path = path->next){
287 nc = strlen(path->word);
289 strcpy(file, path->word);
294 if(nc+strlen(argv[1])<1024){
295 strcat(file, argv[1]);
298 else werrstr("command name too long");
301 rerrstr(file, sizeof file);
302 pfmt(err, "%s: %s\n", argv[1], file);
305 #define NDIR 256 /* shoud be a better way */
310 int isglob = 0, globlen = NDIR+1;
316 globlen+=*p=='*'?NDIR:1;
321 return isglob?globlen:0;
340 if(db!=nil && (db->mode&DMDIR)){
354 trimdirs(Dir *d, int nd)
358 for(r=w=0; r<nd; r++)
365 * onlydirs is advisory -- it means you only
366 * need to return the directories. it's okay to
367 * return files too (e.g., on unix where you can't
368 * tell during the readdir), but that just makes
369 * the globber work harder.
372 Readdir(int f, void *p, int onlydirs)
379 if(dir[f].i==dir[f].n){ /* read */
382 n = dirread(f, &dir[f].dbuf);
385 n = trimdirs(dir[f].dbuf, n);
394 if(dir[f].i == dir[f].n)
396 strcpy(p, dir[f].dbuf[dir[f].i].name);
414 notifyf(void*, char *s)
417 for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
418 if(strncmp(s, "sys: ", 5)!=0) interrupted = 1;
421 pfmt(err, "rc: note: %s\n", s);
425 if(strcmp(s, "interrupt")!=0 || trap[i]==0){
429 if(ntrap>=32){ /* rc is probably in a trap loop */
430 pfmt(err, "rc: Too many traps (trap %s), aborting\n", s);
449 Write(int fd, void *buf, long cnt)
451 return write(fd, buf, (long)cnt);
455 Read(int fd, void *buf, long cnt)
457 return read(fd, buf, cnt);
461 Seek(int fd, long cnt, long whence)
463 return seek(fd, cnt, whence);
467 Executable(char *file)
472 statbuf = dirstat(file);
475 ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0);
483 return create(file, 1, 0666L);
503 exits(truestatus()?"":getstatus());
527 if(strncmp(d1->name, "ptty", 4)==0){ /* fwd complaints to philw */
531 d2 = dirstat("/dev/cons");
536 ret = (d1->type==d2->type&&d1->dev==d2->dev&&d1->qid.path==d2->qid.path);
545 pfmt(err, "aborting\n");
551 Memcpy(void *a, void *b, long n)
563 Realloc(void *p, ulong n)
565 return realloc(p, n);