13e12c5d1SDavid du Colombier /* 23e12c5d1SDavid du Colombier * Plan 9 versions of system-specific functions 33e12c5d1SDavid du Colombier * By convention, exported routines herein have names beginning with an 43e12c5d1SDavid du Colombier * upper case letter. 53e12c5d1SDavid du Colombier */ 63e12c5d1SDavid du Colombier #include "rc.h" 73e12c5d1SDavid du Colombier #include "exec.h" 83e12c5d1SDavid du Colombier #include "io.h" 93e12c5d1SDavid du Colombier #include "fns.h" 103e12c5d1SDavid du Colombier #include "getflags.h" 11276e7d6dSDavid du Colombier 12276e7d6dSDavid du Colombier enum { 13276e7d6dSDavid du Colombier Maxenvname = 256, /* undocumented limit */ 14276e7d6dSDavid du Colombier }; 15276e7d6dSDavid du Colombier 163e12c5d1SDavid du Colombier char *Signame[] = { 173e12c5d1SDavid du Colombier "sigexit", "sighup", "sigint", "sigquit", 18219b2ee8SDavid du Colombier "sigalrm", "sigkill", "sigfpe", "sigterm", 19219b2ee8SDavid du Colombier 0 203e12c5d1SDavid du Colombier }; 213e12c5d1SDavid du Colombier char *syssigname[] = { 223e12c5d1SDavid du Colombier "exit", /* can't happen */ 233e12c5d1SDavid du Colombier "hangup", 243e12c5d1SDavid du Colombier "interrupt", 253e12c5d1SDavid du Colombier "quit", /* can't happen */ 263e12c5d1SDavid du Colombier "alarm", 27219b2ee8SDavid du Colombier "kill", 283e12c5d1SDavid du Colombier "sys: fp: ", 29219b2ee8SDavid du Colombier "term", 303e12c5d1SDavid du Colombier 0 313e12c5d1SDavid du Colombier }; 323e12c5d1SDavid du Colombier char Rcmain[]="/rc/lib/rcmain"; 333e12c5d1SDavid du Colombier char Fdprefix[]="/fd/"; 343e12c5d1SDavid du Colombier void execfinit(void); 353e12c5d1SDavid du Colombier void execbind(void); 363e12c5d1SDavid du Colombier void execmount(void); 373e12c5d1SDavid du Colombier void execnewpgrp(void); 383e12c5d1SDavid du Colombier builtin Builtin[] = { 393e12c5d1SDavid du Colombier "cd", execcd, 403e12c5d1SDavid du Colombier "whatis", execwhatis, 413e12c5d1SDavid du Colombier "eval", execeval, 423e12c5d1SDavid du Colombier "exec", execexec, /* but with popword first */ 433e12c5d1SDavid du Colombier "exit", execexit, 443e12c5d1SDavid du Colombier "shift", execshift, 453e12c5d1SDavid du Colombier "wait", execwait, 463e12c5d1SDavid du Colombier ".", execdot, 473e12c5d1SDavid du Colombier "finit", execfinit, 483e12c5d1SDavid du Colombier "flag", execflag, 493e12c5d1SDavid du Colombier "rfork", execnewpgrp, 503e12c5d1SDavid du Colombier 0 513e12c5d1SDavid du Colombier }; 52dc5a79c1SDavid du Colombier 53dc5a79c1SDavid du Colombier void 54dc5a79c1SDavid du Colombier execnewpgrp(void) 55dc5a79c1SDavid du Colombier { 563e12c5d1SDavid du Colombier int arg; 573e12c5d1SDavid du Colombier char *s; 583e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 59dc5a79c1SDavid du Colombier case 1: 60dc5a79c1SDavid du Colombier arg = RFENVG|RFNAMEG|RFNOTEG; 61dc5a79c1SDavid du Colombier break; 623e12c5d1SDavid du Colombier case 2: 633e12c5d1SDavid du Colombier arg = 0; 643e12c5d1SDavid du Colombier for(s = runq->argv->words->next->word;*s;s++) switch(*s){ 653e12c5d1SDavid du Colombier default: 663e12c5d1SDavid du Colombier goto Usage; 67dc5a79c1SDavid du Colombier case 'n': 68dc5a79c1SDavid du Colombier arg|=RFNAMEG; break; 69dc5a79c1SDavid du Colombier case 'N': 70dc5a79c1SDavid du Colombier arg|=RFCNAMEG; 71dc5a79c1SDavid du Colombier break; 72dc5a79c1SDavid du Colombier case 'm': 73dc5a79c1SDavid du Colombier arg|=RFNOMNT; break; 74dc5a79c1SDavid du Colombier case 'e': 75dc5a79c1SDavid du Colombier arg|=RFENVG; break; 76dc5a79c1SDavid du Colombier case 'E': 77dc5a79c1SDavid du Colombier arg|=RFCENVG; break; 78dc5a79c1SDavid du Colombier case 's': 79dc5a79c1SDavid du Colombier arg|=RFNOTEG; break; 80dc5a79c1SDavid du Colombier case 'f': 81dc5a79c1SDavid du Colombier arg|=RFFDG; break; 82dc5a79c1SDavid du Colombier case 'F': 83dc5a79c1SDavid du Colombier arg|=RFCFDG; break; 843e12c5d1SDavid du Colombier } 853e12c5d1SDavid du Colombier break; 863e12c5d1SDavid du Colombier default: 873e12c5d1SDavid du Colombier Usage: 887dd7cddfSDavid du Colombier pfmt(err, "Usage: %s [fnesFNEm]\n", runq->argv->words->word); 893e12c5d1SDavid du Colombier setstatus("rfork usage"); 903e12c5d1SDavid du Colombier poplist(); 913e12c5d1SDavid du Colombier return; 923e12c5d1SDavid du Colombier } 933e12c5d1SDavid du Colombier if(rfork(arg)==-1){ 943e12c5d1SDavid du Colombier pfmt(err, "rc: %s failed\n", runq->argv->words->word); 953e12c5d1SDavid du Colombier setstatus("rfork failed"); 963e12c5d1SDavid du Colombier } 973e12c5d1SDavid du Colombier else 983e12c5d1SDavid du Colombier setstatus(""); 993e12c5d1SDavid du Colombier poplist(); 1003e12c5d1SDavid du Colombier } 101dc5a79c1SDavid du Colombier 102dc5a79c1SDavid du Colombier void 103dc5a79c1SDavid du Colombier Vinit(void) 104dc5a79c1SDavid du Colombier { 105276e7d6dSDavid du Colombier int dir, f, len, i, n, nent; 1063e12c5d1SDavid du Colombier char *buf, *s; 107276e7d6dSDavid du Colombier char envname[Maxenvname]; 108276e7d6dSDavid du Colombier word *val; 1099a747e4fSDavid du Colombier Dir *ent; 110276e7d6dSDavid du Colombier 1119a747e4fSDavid du Colombier dir = open("/env", OREAD); 1123e12c5d1SDavid du Colombier if(dir<0){ 1139a747e4fSDavid du Colombier pfmt(err, "rc: can't open /env: %r\n"); 1143e12c5d1SDavid du Colombier return; 1153e12c5d1SDavid du Colombier } 1169a747e4fSDavid du Colombier ent = nil; 1179a747e4fSDavid du Colombier for(;;){ 1189a747e4fSDavid du Colombier nent = dirread(dir, &ent); 1199a747e4fSDavid du Colombier if(nent <= 0) 1209a747e4fSDavid du Colombier break; 1219a747e4fSDavid du Colombier for(i = 0; i<nent; i++){ 1229a747e4fSDavid du Colombier len = ent[i].length; 1239a747e4fSDavid du Colombier if(len && strncmp(ent[i].name, "fn#", 3)!=0){ 12499eb86a7SDavid du Colombier snprint(envname, sizeof envname, "/env/%s", ent[i].name); 1253e12c5d1SDavid du Colombier if((f = open(envname, 0))>=0){ 126276e7d6dSDavid du Colombier buf = emalloc(len+1); 127276e7d6dSDavid du Colombier n = readn(f, buf, len); 128276e7d6dSDavid du Colombier if (n <= 0) 129276e7d6dSDavid du Colombier buf[0] = '\0'; 130276e7d6dSDavid du Colombier else 131276e7d6dSDavid du Colombier buf[n] = '\0'; 1323e12c5d1SDavid du Colombier val = 0; 1333e12c5d1SDavid du Colombier /* Charitably add a 0 at the end if need be */ 134dc5a79c1SDavid du Colombier if(buf[len-1]) 135dc5a79c1SDavid du Colombier buf[len++]='\0'; 1363e12c5d1SDavid du Colombier s = buf+len-1; 1373e12c5d1SDavid du Colombier for(;;){ 13899eb86a7SDavid du Colombier while(s!=buf && s[-1]!='\0') --s; 1393e12c5d1SDavid du Colombier val = newword(s, val); 140dc5a79c1SDavid du Colombier if(s==buf) 141dc5a79c1SDavid du Colombier break; 1423e12c5d1SDavid du Colombier --s; 1433e12c5d1SDavid du Colombier } 1449a747e4fSDavid du Colombier setvar(ent[i].name, val); 1459a747e4fSDavid du Colombier vlook(ent[i].name)->changed = 0; 1463e12c5d1SDavid du Colombier close(f); 1473e12c5d1SDavid du Colombier efree(buf); 1483e12c5d1SDavid du Colombier } 1493e12c5d1SDavid du Colombier } 1503e12c5d1SDavid du Colombier } 1519a747e4fSDavid du Colombier free(ent); 1529a747e4fSDavid du Colombier } 1533e12c5d1SDavid du Colombier close(dir); 1543e12c5d1SDavid du Colombier } 1553e12c5d1SDavid du Colombier int envdir; 156dc5a79c1SDavid du Colombier 157dc5a79c1SDavid du Colombier void 158dc5a79c1SDavid du Colombier Xrdfn(void) 159dc5a79c1SDavid du Colombier { 1603e12c5d1SDavid du Colombier int f, len; 161276e7d6dSDavid du Colombier Dir *e; 162276e7d6dSDavid du Colombier char envname[Maxenvname]; 1639a747e4fSDavid du Colombier static Dir *ent, *allocent; 1649a747e4fSDavid du Colombier static int nent; 1659a747e4fSDavid du Colombier 1669a747e4fSDavid du Colombier for(;;){ 1679a747e4fSDavid du Colombier if(nent == 0){ 1689a747e4fSDavid du Colombier free(allocent); 1699a747e4fSDavid du Colombier nent = dirread(envdir, &allocent); 1709a747e4fSDavid du Colombier ent = allocent; 1719a747e4fSDavid du Colombier } 1729a747e4fSDavid du Colombier if(nent <= 0) 1739a747e4fSDavid du Colombier break; 1749a747e4fSDavid du Colombier while(nent){ 1759a747e4fSDavid du Colombier e = ent++; 1769a747e4fSDavid du Colombier nent--; 1779a747e4fSDavid du Colombier len = e->length; 1789a747e4fSDavid du Colombier if(len && strncmp(e->name, "fn#", 3)==0){ 17999eb86a7SDavid du Colombier snprint(envname, sizeof envname, "/env/%s", e->name); 1803e12c5d1SDavid du Colombier if((f = open(envname, 0))>=0){ 1813e12c5d1SDavid du Colombier execcmds(openfd(f)); 1823e12c5d1SDavid du Colombier return; 1833e12c5d1SDavid du Colombier } 1843e12c5d1SDavid du Colombier } 1853e12c5d1SDavid du Colombier } 1869a747e4fSDavid du Colombier } 1873e12c5d1SDavid du Colombier close(envdir); 1883e12c5d1SDavid du Colombier Xreturn(); 1893e12c5d1SDavid du Colombier } 1903e12c5d1SDavid du Colombier union code rdfns[4]; 191dc5a79c1SDavid du Colombier 192dc5a79c1SDavid du Colombier void 193dc5a79c1SDavid du Colombier execfinit(void) 194dc5a79c1SDavid du Colombier { 1953e12c5d1SDavid du Colombier static int first = 1; 1963e12c5d1SDavid du Colombier if(first){ 1973e12c5d1SDavid du Colombier rdfns[0].i = 1; 1983e12c5d1SDavid du Colombier rdfns[1].f = Xrdfn; 1993e12c5d1SDavid du Colombier rdfns[2].f = Xjump; 2003e12c5d1SDavid du Colombier rdfns[3].i = 1; 2013e12c5d1SDavid du Colombier first = 0; 2023e12c5d1SDavid du Colombier } 2033e12c5d1SDavid du Colombier Xpopm(); 2049a747e4fSDavid du Colombier envdir = open("/env", 0); 2053e12c5d1SDavid du Colombier if(envdir<0){ 2069a747e4fSDavid du Colombier pfmt(err, "rc: can't open /env: %r\n"); 2073e12c5d1SDavid du Colombier return; 2083e12c5d1SDavid du Colombier } 2093e12c5d1SDavid du Colombier start(rdfns, 1, runq->local); 2103e12c5d1SDavid du Colombier } 211dc5a79c1SDavid du Colombier 212dc5a79c1SDavid du Colombier int 213dc5a79c1SDavid du Colombier Waitfor(int pid, int) 214dc5a79c1SDavid du Colombier { 2153e12c5d1SDavid du Colombier thread *p; 2169a747e4fSDavid du Colombier Waitmsg *w; 2179a747e4fSDavid du Colombier char errbuf[ERRMAX]; 2189a747e4fSDavid du Colombier 219d3907fe5SDavid du Colombier if(pid >= 0 && !havewaitpid(pid)) 220d3907fe5SDavid du Colombier return 0; 221d3907fe5SDavid du Colombier 2229a747e4fSDavid du Colombier while((w = wait()) != nil){ 223d3907fe5SDavid du Colombier delwaitpid(w->pid); 2249a747e4fSDavid du Colombier if(w->pid==pid){ 2259a747e4fSDavid du Colombier setstatus(w->msg); 2269a747e4fSDavid du Colombier free(w); 227219b2ee8SDavid du Colombier return 0; 2283e12c5d1SDavid du Colombier } 2293e12c5d1SDavid du Colombier for(p = runq->ret;p;p = p->ret) 2309a747e4fSDavid du Colombier if(p->pid==w->pid){ 2313e12c5d1SDavid du Colombier p->pid=-1; 2329a747e4fSDavid du Colombier strcpy(p->status, w->msg); 2333e12c5d1SDavid du Colombier } 2349a747e4fSDavid du Colombier free(w); 2353e12c5d1SDavid du Colombier } 2369a747e4fSDavid du Colombier 2379a747e4fSDavid du Colombier errstr(errbuf, sizeof errbuf); 23899eb86a7SDavid du Colombier if(strcmp(errbuf, "interrupted")==0) return -1; 2393e12c5d1SDavid du Colombier return 0; 2403e12c5d1SDavid du Colombier } 241dc5a79c1SDavid du Colombier 242276e7d6dSDavid du Colombier char ** 243276e7d6dSDavid du Colombier mkargv(word *a) 2443e12c5d1SDavid du Colombier { 2453e12c5d1SDavid du Colombier char **argv = (char **)emalloc((count(a)+2)*sizeof(char *)); 2463e12c5d1SDavid du Colombier char **argp = argv+1; /* leave one at front for runcoms */ 24799eb86a7SDavid du Colombier for(;a;a = a->next) *argp++=a->word; 2483e12c5d1SDavid du Colombier *argp = 0; 2493e12c5d1SDavid du Colombier return argv; 2503e12c5d1SDavid du Colombier } 251dc5a79c1SDavid du Colombier 252dc5a79c1SDavid du Colombier void 253dc5a79c1SDavid du Colombier addenv(var *v) 2543e12c5d1SDavid du Colombier { 255276e7d6dSDavid du Colombier char envname[Maxenvname]; 2563e12c5d1SDavid du Colombier word *w; 2573e12c5d1SDavid du Colombier int f; 2583e12c5d1SDavid du Colombier io *fd; 2593e12c5d1SDavid du Colombier if(v->changed){ 2603e12c5d1SDavid du Colombier v->changed = 0; 2619a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/%s", v->name); 2623e12c5d1SDavid du Colombier if((f = Creat(envname))<0) 2639a747e4fSDavid du Colombier pfmt(err, "rc: can't open %s: %r\n", envname); 2643e12c5d1SDavid du Colombier else{ 2653e12c5d1SDavid du Colombier for(w = v->val;w;w = w->next) 26699eb86a7SDavid du Colombier write(f, w->word, strlen(w->word)+1L); 2673e12c5d1SDavid du Colombier close(f); 2683e12c5d1SDavid du Colombier } 2693e12c5d1SDavid du Colombier } 2703e12c5d1SDavid du Colombier if(v->fnchanged){ 2713e12c5d1SDavid du Colombier v->fnchanged = 0; 2729a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/fn#%s", v->name); 2733e12c5d1SDavid du Colombier if((f = Creat(envname))<0) 2749a747e4fSDavid du Colombier pfmt(err, "rc: can't open %s: %r\n", envname); 2753e12c5d1SDavid du Colombier else{ 2763e12c5d1SDavid du Colombier if(v->fn){ 2773e12c5d1SDavid du Colombier fd = openfd(f); 278fed0fa9eSDavid du Colombier pfmt(fd, "fn %q %s\n", v->name, v->fn[v->pc-1].s); 2793e12c5d1SDavid du Colombier closeio(fd); 2803e12c5d1SDavid du Colombier } 2813e12c5d1SDavid du Colombier close(f); 2823e12c5d1SDavid du Colombier } 2833e12c5d1SDavid du Colombier } 2843e12c5d1SDavid du Colombier } 285dc5a79c1SDavid du Colombier 286dc5a79c1SDavid du Colombier void 287dc5a79c1SDavid du Colombier updenvlocal(var *v) 2883e12c5d1SDavid du Colombier { 2893e12c5d1SDavid du Colombier if(v){ 2903e12c5d1SDavid du Colombier updenvlocal(v->next); 2913e12c5d1SDavid du Colombier addenv(v); 2923e12c5d1SDavid du Colombier } 2933e12c5d1SDavid du Colombier } 294dc5a79c1SDavid du Colombier 295dc5a79c1SDavid du Colombier void 296dc5a79c1SDavid du Colombier Updenv(void) 297dc5a79c1SDavid du Colombier { 2983e12c5d1SDavid du Colombier var *v, **h; 2993e12c5d1SDavid du Colombier for(h = gvar;h!=&gvar[NVAR];h++) 3003e12c5d1SDavid du Colombier for(v=*h;v;v = v->next) 3013e12c5d1SDavid du Colombier addenv(v); 302dc5a79c1SDavid du Colombier if(runq) 303dc5a79c1SDavid du Colombier updenvlocal(runq->local); 3043e12c5d1SDavid du Colombier } 305dc5a79c1SDavid du Colombier 306*5acbe002SDavid du Colombier /* not used on plan 9 */ 307dc5a79c1SDavid du Colombier int 308dc5a79c1SDavid du Colombier ForkExecute(char *file, char **argv, int sin, int sout, int serr) 309dc5a79c1SDavid du Colombier { 310dc5a79c1SDavid du Colombier int pid; 311dc5a79c1SDavid du Colombier 312dc5a79c1SDavid du Colombier if(access(file, 1) != 0) 313dc5a79c1SDavid du Colombier return -1; 314dc5a79c1SDavid du Colombier switch(pid = fork()){ 315dc5a79c1SDavid du Colombier case -1: 316dc5a79c1SDavid du Colombier return -1; 317dc5a79c1SDavid du Colombier case 0: 318dc5a79c1SDavid du Colombier if(sin >= 0) 319dc5a79c1SDavid du Colombier dup(sin, 0); 320dc5a79c1SDavid du Colombier else 321dc5a79c1SDavid du Colombier close(0); 322dc5a79c1SDavid du Colombier if(sout >= 0) 323dc5a79c1SDavid du Colombier dup(sout, 1); 324dc5a79c1SDavid du Colombier else 325dc5a79c1SDavid du Colombier close(1); 326dc5a79c1SDavid du Colombier if(serr >= 0) 327dc5a79c1SDavid du Colombier dup(serr, 2); 328dc5a79c1SDavid du Colombier else 329dc5a79c1SDavid du Colombier close(2); 330dc5a79c1SDavid du Colombier exec(file, argv); 331dc5a79c1SDavid du Colombier exits(file); 332dc5a79c1SDavid du Colombier } 333dc5a79c1SDavid du Colombier return pid; 334dc5a79c1SDavid du Colombier } 335dc5a79c1SDavid du Colombier 336dc5a79c1SDavid du Colombier void 337dc5a79c1SDavid du Colombier Execute(word *args, word *path) 3383e12c5d1SDavid du Colombier { 3393e12c5d1SDavid du Colombier char **argv = mkargv(args); 340*5acbe002SDavid du Colombier char file[1024], errstr[1024]; 341219b2ee8SDavid du Colombier int nc; 342*5acbe002SDavid du Colombier 3433e12c5d1SDavid du Colombier Updenv(); 344*5acbe002SDavid du Colombier errstr[0] = '\0'; 3453e12c5d1SDavid du Colombier for(;path;path = path->next){ 346219b2ee8SDavid du Colombier nc = strlen(path->word); 347276e7d6dSDavid du Colombier if(nc < sizeof file - 1){ /* 1 for / */ 3483e12c5d1SDavid du Colombier strcpy(file, path->word); 349219b2ee8SDavid du Colombier if(file[0]){ 350219b2ee8SDavid du Colombier strcat(file, "/"); 351219b2ee8SDavid du Colombier nc++; 352219b2ee8SDavid du Colombier } 353276e7d6dSDavid du Colombier if(nc + strlen(argv[1]) < sizeof file){ 3543e12c5d1SDavid du Colombier strcat(file, argv[1]); 3553e12c5d1SDavid du Colombier exec(file, argv+1); 356*5acbe002SDavid du Colombier rerrstr(errstr, sizeof errstr); 357*5acbe002SDavid du Colombier /* 358*5acbe002SDavid du Colombier * if file is executable, exec should have 359*5acbe002SDavid du Colombier * worked. stop searching and print the 360*5acbe002SDavid du Colombier * reason for failure. 361*5acbe002SDavid du Colombier */ 362*5acbe002SDavid du Colombier if (access(file, AEXEC) == 0) 363*5acbe002SDavid du Colombier break; 3643e12c5d1SDavid du Colombier } 36599eb86a7SDavid du Colombier else werrstr("command name too long"); 366219b2ee8SDavid du Colombier } 367219b2ee8SDavid du Colombier } 368*5acbe002SDavid du Colombier pfmt(err, "%s: %s\n", argv[1], errstr); 3693e12c5d1SDavid du Colombier efree((char *)argv); 3703e12c5d1SDavid du Colombier } 37199eb86a7SDavid du Colombier #define NDIR 256 /* shoud be a better way */ 372dc5a79c1SDavid du Colombier 373dc5a79c1SDavid du Colombier int 374dc5a79c1SDavid du Colombier Globsize(char *p) 3753e12c5d1SDavid du Colombier { 37673e742d7SDavid du Colombier int isglob = 0, globlen = NDIR+1; 3773e12c5d1SDavid du Colombier for(;*p;p++){ 3783e12c5d1SDavid du Colombier if(*p==GLOB){ 3793e12c5d1SDavid du Colombier p++; 380dc5a79c1SDavid du Colombier if(*p!=GLOB) 381dc5a79c1SDavid du Colombier isglob++; 3829a747e4fSDavid du Colombier globlen+=*p=='*'?NDIR:1; 3833e12c5d1SDavid du Colombier } 3843e12c5d1SDavid du Colombier else 3853e12c5d1SDavid du Colombier globlen++; 3863e12c5d1SDavid du Colombier } 3873e12c5d1SDavid du Colombier return isglob?globlen:0; 3883e12c5d1SDavid du Colombier } 3893e12c5d1SDavid du Colombier #define NFD 50 390276e7d6dSDavid du Colombier 3913e12c5d1SDavid du Colombier struct{ 3929a747e4fSDavid du Colombier Dir *dbuf; 3939a747e4fSDavid du Colombier int i; 3943e12c5d1SDavid du Colombier int n; 3953e12c5d1SDavid du Colombier }dir[NFD]; 396dc5a79c1SDavid du Colombier 397dc5a79c1SDavid du Colombier int 398dc5a79c1SDavid du Colombier Opendir(char *name) 3993e12c5d1SDavid du Colombier { 4009a747e4fSDavid du Colombier Dir *db; 4013e12c5d1SDavid du Colombier int f; 4023e12c5d1SDavid du Colombier f = open(name, 0); 4033e12c5d1SDavid du Colombier if(f==-1) 4043e12c5d1SDavid du Colombier return f; 4059a747e4fSDavid du Colombier db = dirfstat(f); 4069a747e4fSDavid du Colombier if(db!=nil && (db->mode&DMDIR)){ 4079a747e4fSDavid du Colombier if(f<NFD){ 4089a747e4fSDavid du Colombier dir[f].i = 0; 4099a747e4fSDavid du Colombier dir[f].n = 0; 4103e12c5d1SDavid du Colombier } 4119a747e4fSDavid du Colombier free(db); 4123e12c5d1SDavid du Colombier return f; 4133e12c5d1SDavid du Colombier } 4149a747e4fSDavid du Colombier free(db); 4153e12c5d1SDavid du Colombier close(f); 4163e12c5d1SDavid du Colombier return -1; 4173e12c5d1SDavid du Colombier } 4186b6b9ac8SDavid du Colombier 4196b6b9ac8SDavid du Colombier static int 4206b6b9ac8SDavid du Colombier trimdirs(Dir *d, int nd) 4216b6b9ac8SDavid du Colombier { 4226b6b9ac8SDavid du Colombier int r, w; 4236b6b9ac8SDavid du Colombier 4246b6b9ac8SDavid du Colombier for(r=w=0; r<nd; r++) 4256b6b9ac8SDavid du Colombier if(d[r].mode&DMDIR) 4266b6b9ac8SDavid du Colombier d[w++] = d[r]; 4276b6b9ac8SDavid du Colombier return w; 4286b6b9ac8SDavid du Colombier } 4296b6b9ac8SDavid du Colombier 4306b6b9ac8SDavid du Colombier /* 4316b6b9ac8SDavid du Colombier * onlydirs is advisory -- it means you only 4326b6b9ac8SDavid du Colombier * need to return the directories. it's okay to 4336b6b9ac8SDavid du Colombier * return files too (e.g., on unix where you can't 4346b6b9ac8SDavid du Colombier * tell during the readdir), but that just makes 4356b6b9ac8SDavid du Colombier * the globber work harder. 4366b6b9ac8SDavid du Colombier */ 437dc5a79c1SDavid du Colombier int 438276e7d6dSDavid du Colombier Readdir(int f, void *p, int onlydirs) 4393e12c5d1SDavid du Colombier { 4403e12c5d1SDavid du Colombier int n; 441dc5a79c1SDavid du Colombier 4429a747e4fSDavid du Colombier if(f<0 || f>=NFD) 4433e12c5d1SDavid du Colombier return 0; 4446b6b9ac8SDavid du Colombier Again: 4459a747e4fSDavid du Colombier if(dir[f].i==dir[f].n){ /* read */ 4469a747e4fSDavid du Colombier free(dir[f].dbuf); 4479a747e4fSDavid du Colombier dir[f].dbuf = 0; 4489a747e4fSDavid du Colombier n = dirread(f, &dir[f].dbuf); 4496b6b9ac8SDavid du Colombier if(n>0){ 4506b6b9ac8SDavid du Colombier if(onlydirs){ 4516b6b9ac8SDavid du Colombier n = trimdirs(dir[f].dbuf, n); 4526b6b9ac8SDavid du Colombier if(n == 0) 4536b6b9ac8SDavid du Colombier goto Again; 4546b6b9ac8SDavid du Colombier } 4559a747e4fSDavid du Colombier dir[f].n = n; 4566b6b9ac8SDavid du Colombier }else 4573e12c5d1SDavid du Colombier dir[f].n = 0; 4589a747e4fSDavid du Colombier dir[f].i = 0; 4593e12c5d1SDavid du Colombier } 4609a747e4fSDavid du Colombier if(dir[f].i == dir[f].n) 4613e12c5d1SDavid du Colombier return 0; 4629a747e4fSDavid du Colombier strcpy(p, dir[f].dbuf[dir[f].i].name); 4639a747e4fSDavid du Colombier dir[f].i++; 4643e12c5d1SDavid du Colombier return 1; 4653e12c5d1SDavid du Colombier } 466dc5a79c1SDavid du Colombier 467dc5a79c1SDavid du Colombier void 468dc5a79c1SDavid du Colombier Closedir(int f) 469dc5a79c1SDavid du Colombier { 4709a747e4fSDavid du Colombier if(f>=0 && f<NFD){ 4719a747e4fSDavid du Colombier free(dir[f].dbuf); 4729a747e4fSDavid du Colombier dir[f].i = 0; 4739a747e4fSDavid du Colombier dir[f].n = 0; 4749a747e4fSDavid du Colombier dir[f].dbuf = 0; 4753e12c5d1SDavid du Colombier } 4763e12c5d1SDavid du Colombier close(f); 4773e12c5d1SDavid du Colombier } 4783e12c5d1SDavid du Colombier int interrupted = 0; 4793e12c5d1SDavid du Colombier void 4807dd7cddfSDavid du Colombier notifyf(void*, char *s) 4813e12c5d1SDavid du Colombier { 4823e12c5d1SDavid du Colombier int i; 48399eb86a7SDavid du Colombier for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){ 48499eb86a7SDavid du Colombier if(strncmp(s, "sys: ", 5)!=0) interrupted = 1; 4853e12c5d1SDavid du Colombier goto Out; 4863e12c5d1SDavid du Colombier } 4873e12c5d1SDavid du Colombier pfmt(err, "rc: note: %s\n", s); 4883e12c5d1SDavid du Colombier noted(NDFLT); 4893e12c5d1SDavid du Colombier return; 4903e12c5d1SDavid du Colombier Out: 491219b2ee8SDavid du Colombier if(strcmp(s, "interrupt")!=0 || trap[i]==0){ 4923e12c5d1SDavid du Colombier trap[i]++; 4933e12c5d1SDavid du Colombier ntrap++; 494219b2ee8SDavid du Colombier } 4953e12c5d1SDavid du Colombier if(ntrap>=32){ /* rc is probably in a trap loop */ 4963e12c5d1SDavid du Colombier pfmt(err, "rc: Too many traps (trap %s), aborting\n", s); 4973e12c5d1SDavid du Colombier abort(); 4983e12c5d1SDavid du Colombier } 4993e12c5d1SDavid du Colombier noted(NCONT); 5003e12c5d1SDavid du Colombier } 501dc5a79c1SDavid du Colombier 502dc5a79c1SDavid du Colombier void 503dc5a79c1SDavid du Colombier Trapinit(void) 504dc5a79c1SDavid du Colombier { 5053e12c5d1SDavid du Colombier notify(notifyf); 5063e12c5d1SDavid du Colombier } 507dc5a79c1SDavid du Colombier 508dc5a79c1SDavid du Colombier void 509dc5a79c1SDavid du Colombier Unlink(char *name) 5103e12c5d1SDavid du Colombier { 5113e12c5d1SDavid du Colombier remove(name); 5123e12c5d1SDavid du Colombier } 513dc5a79c1SDavid du Colombier 514dc5a79c1SDavid du Colombier long 515276e7d6dSDavid du Colombier Write(int fd, void *buf, long cnt) 5163e12c5d1SDavid du Colombier { 517276e7d6dSDavid du Colombier return write(fd, buf, cnt); 5183e12c5d1SDavid du Colombier } 519dc5a79c1SDavid du Colombier 520dc5a79c1SDavid du Colombier long 521276e7d6dSDavid du Colombier Read(int fd, void *buf, long cnt) 5223e12c5d1SDavid du Colombier { 5233e12c5d1SDavid du Colombier return read(fd, buf, cnt); 5243e12c5d1SDavid du Colombier } 525dc5a79c1SDavid du Colombier 526dc5a79c1SDavid du Colombier long 527dc5a79c1SDavid du Colombier Seek(int fd, long cnt, long whence) 5283e12c5d1SDavid du Colombier { 5293e12c5d1SDavid du Colombier return seek(fd, cnt, whence); 5303e12c5d1SDavid du Colombier } 531dc5a79c1SDavid du Colombier 532dc5a79c1SDavid du Colombier int 533dc5a79c1SDavid du Colombier Executable(char *file) 5343e12c5d1SDavid du Colombier { 5359a747e4fSDavid du Colombier Dir *statbuf; 5369a747e4fSDavid du Colombier int ret; 5373e12c5d1SDavid du Colombier 5389a747e4fSDavid du Colombier statbuf = dirstat(file); 539dc5a79c1SDavid du Colombier if(statbuf == nil) 540dc5a79c1SDavid du Colombier return 0; 54199eb86a7SDavid du Colombier ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0); 5429a747e4fSDavid du Colombier free(statbuf); 5439a747e4fSDavid du Colombier return ret; 5443e12c5d1SDavid du Colombier } 545dc5a79c1SDavid du Colombier 546dc5a79c1SDavid du Colombier int 547dc5a79c1SDavid du Colombier Creat(char *file) 5483e12c5d1SDavid du Colombier { 54999eb86a7SDavid du Colombier return create(file, 1, 0666L); 5503e12c5d1SDavid du Colombier } 551dc5a79c1SDavid du Colombier 552dc5a79c1SDavid du Colombier int 553dc5a79c1SDavid du Colombier Dup(int a, int b) 554dc5a79c1SDavid du Colombier { 5553e12c5d1SDavid du Colombier return dup(a, b); 5563e12c5d1SDavid du Colombier } 557dc5a79c1SDavid du Colombier 558dc5a79c1SDavid du Colombier int 559dc5a79c1SDavid du Colombier Dup1(int) 560dc5a79c1SDavid du Colombier { 5613e12c5d1SDavid du Colombier return -1; 5623e12c5d1SDavid du Colombier } 563dc5a79c1SDavid du Colombier 564dc5a79c1SDavid du Colombier void 565dc5a79c1SDavid du Colombier Exit(char *stat) 5663e12c5d1SDavid du Colombier { 5673e12c5d1SDavid du Colombier Updenv(); 5683e12c5d1SDavid du Colombier setstatus(stat); 5693e12c5d1SDavid du Colombier exits(truestatus()?"":getstatus()); 5703e12c5d1SDavid du Colombier } 571dc5a79c1SDavid du Colombier 572dc5a79c1SDavid du Colombier int 573dc5a79c1SDavid du Colombier Eintr(void) 574dc5a79c1SDavid du Colombier { 5753e12c5d1SDavid du Colombier return interrupted; 5763e12c5d1SDavid du Colombier } 577dc5a79c1SDavid du Colombier 578dc5a79c1SDavid du Colombier void 579dc5a79c1SDavid du Colombier Noerror(void) 580dc5a79c1SDavid du Colombier { 5813e12c5d1SDavid du Colombier interrupted = 0; 5823e12c5d1SDavid du Colombier } 583dc5a79c1SDavid du Colombier 584dc5a79c1SDavid du Colombier int 585dc5a79c1SDavid du Colombier Isatty(int fd) 586dc5a79c1SDavid du Colombier { 5874f281771SDavid du Colombier char buf[64]; 5883e12c5d1SDavid du Colombier 5894f281771SDavid du Colombier if(fd2path(fd, buf, sizeof buf) != 0) 590dc5a79c1SDavid du Colombier return 0; 5914f281771SDavid du Colombier 5923806af99SDavid du Colombier /* might be #c/cons during boot - fixed 22 april 2005, remove this later */ 5933806af99SDavid du Colombier if(strcmp(buf, "#c/cons") == 0) 5943806af99SDavid du Colombier return 1; 5953806af99SDavid du Colombier 5964f281771SDavid du Colombier /* might be /mnt/term/dev/cons */ 5974f281771SDavid du Colombier return strlen(buf) >= 9 && strcmp(buf+strlen(buf)-9, "/dev/cons") == 0; 5983e12c5d1SDavid du Colombier } 599dc5a79c1SDavid du Colombier 600dc5a79c1SDavid du Colombier void 601dc5a79c1SDavid du Colombier Abort(void) 602dc5a79c1SDavid du Colombier { 6033e12c5d1SDavid du Colombier pfmt(err, "aborting\n"); 6043e12c5d1SDavid du Colombier flush(err); 6053e12c5d1SDavid du Colombier Exit("aborting"); 6063e12c5d1SDavid du Colombier } 607dc5a79c1SDavid du Colombier 608dc5a79c1SDavid du Colombier void 609276e7d6dSDavid du Colombier Memcpy(void *a, void *b, long n) 6103e12c5d1SDavid du Colombier { 611276e7d6dSDavid du Colombier memmove(a, b, n); 6123e12c5d1SDavid du Colombier } 613dc5a79c1SDavid du Colombier 614dc5a79c1SDavid du Colombier void* 615dc5a79c1SDavid du Colombier Malloc(ulong n) 616dc5a79c1SDavid du Colombier { 6173e12c5d1SDavid du Colombier return malloc(n); 6183e12c5d1SDavid du Colombier } 619d3907fe5SDavid du Colombier 620d3907fe5SDavid du Colombier int *waitpids; 621d3907fe5SDavid du Colombier int nwaitpids; 622d3907fe5SDavid du Colombier 623d3907fe5SDavid du Colombier void 624d3907fe5SDavid du Colombier addwaitpid(int pid) 625d3907fe5SDavid du Colombier { 626d3907fe5SDavid du Colombier waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]); 627d3907fe5SDavid du Colombier if(waitpids == 0) 628d3907fe5SDavid du Colombier panic("Can't realloc %d waitpids", nwaitpids+1); 629d3907fe5SDavid du Colombier waitpids[nwaitpids++] = pid; 630d3907fe5SDavid du Colombier } 631d3907fe5SDavid du Colombier 632d3907fe5SDavid du Colombier void 633d3907fe5SDavid du Colombier delwaitpid(int pid) 634d3907fe5SDavid du Colombier { 635d3907fe5SDavid du Colombier int r, w; 636d3907fe5SDavid du Colombier 637d3907fe5SDavid du Colombier for(r=w=0; r<nwaitpids; r++) 638d3907fe5SDavid du Colombier if(waitpids[r] != pid) 639d3907fe5SDavid du Colombier waitpids[w++] = waitpids[r]; 640d3907fe5SDavid du Colombier nwaitpids = w; 641d3907fe5SDavid du Colombier } 642d3907fe5SDavid du Colombier 643d3907fe5SDavid du Colombier void 644d3907fe5SDavid du Colombier clearwaitpids(void) 645d3907fe5SDavid du Colombier { 646d3907fe5SDavid du Colombier nwaitpids = 0; 647d3907fe5SDavid du Colombier } 648d3907fe5SDavid du Colombier 649d3907fe5SDavid du Colombier int 650d3907fe5SDavid du Colombier havewaitpid(int pid) 651d3907fe5SDavid du Colombier { 652d3907fe5SDavid du Colombier int i; 653d3907fe5SDavid du Colombier 654d3907fe5SDavid du Colombier for(i=0; i<nwaitpids; i++) 655d3907fe5SDavid du Colombier if(waitpids[i] == pid) 656d3907fe5SDavid du Colombier return 1; 657d3907fe5SDavid du Colombier return 0; 658d3907fe5SDavid du Colombier } 659f07722aaSDavid du Colombier 660f07722aaSDavid du Colombier /* avoid loading any floating-point library code */ 661f07722aaSDavid du Colombier int 662f07722aaSDavid du Colombier _efgfmt(Fmt *) 663f07722aaSDavid du Colombier { 664f07722aaSDavid du Colombier return -1; 665f07722aaSDavid du Colombier } 666