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 306dc5a79c1SDavid du Colombier int 307dc5a79c1SDavid du Colombier ForkExecute(char *file, char **argv, int sin, int sout, int serr) 308dc5a79c1SDavid du Colombier { 309dc5a79c1SDavid du Colombier int pid; 310dc5a79c1SDavid du Colombier 311dc5a79c1SDavid du Colombier if(access(file, 1) != 0) 312dc5a79c1SDavid du Colombier return -1; 313dc5a79c1SDavid du Colombier switch(pid = fork()){ 314dc5a79c1SDavid du Colombier case -1: 315dc5a79c1SDavid du Colombier return -1; 316dc5a79c1SDavid du Colombier case 0: 317dc5a79c1SDavid du Colombier if(sin >= 0) 318dc5a79c1SDavid du Colombier dup(sin, 0); 319dc5a79c1SDavid du Colombier else 320dc5a79c1SDavid du Colombier close(0); 321dc5a79c1SDavid du Colombier if(sout >= 0) 322dc5a79c1SDavid du Colombier dup(sout, 1); 323dc5a79c1SDavid du Colombier else 324dc5a79c1SDavid du Colombier close(1); 325dc5a79c1SDavid du Colombier if(serr >= 0) 326dc5a79c1SDavid du Colombier dup(serr, 2); 327dc5a79c1SDavid du Colombier else 328dc5a79c1SDavid du Colombier close(2); 329dc5a79c1SDavid du Colombier exec(file, argv); 330dc5a79c1SDavid du Colombier exits(file); 331dc5a79c1SDavid du Colombier } 332dc5a79c1SDavid du Colombier return pid; 333dc5a79c1SDavid du Colombier } 334dc5a79c1SDavid du Colombier 335dc5a79c1SDavid du Colombier void 336dc5a79c1SDavid du Colombier Execute(word *args, word *path) 3373e12c5d1SDavid du Colombier { 3383e12c5d1SDavid du Colombier char **argv = mkargv(args); 339219b2ee8SDavid du Colombier char file[1024]; 340219b2ee8SDavid du Colombier int nc; 3413e12c5d1SDavid du Colombier Updenv(); 3423e12c5d1SDavid du Colombier for(;path;path = path->next){ 343219b2ee8SDavid du Colombier nc = strlen(path->word); 344276e7d6dSDavid du Colombier if(nc < sizeof file - 1){ /* 1 for / */ 3453e12c5d1SDavid du Colombier strcpy(file, path->word); 346219b2ee8SDavid du Colombier if(file[0]){ 347219b2ee8SDavid du Colombier strcat(file, "/"); 348219b2ee8SDavid du Colombier nc++; 349219b2ee8SDavid du Colombier } 350276e7d6dSDavid du Colombier if(nc + strlen(argv[1]) < sizeof file){ 3513e12c5d1SDavid du Colombier strcat(file, argv[1]); 3523e12c5d1SDavid du Colombier exec(file, argv+1); 3533e12c5d1SDavid du Colombier } 35499eb86a7SDavid du Colombier else werrstr("command name too long"); 355219b2ee8SDavid du Colombier } 356219b2ee8SDavid du Colombier } 3579a747e4fSDavid du Colombier rerrstr(file, sizeof file); 3583e12c5d1SDavid du Colombier pfmt(err, "%s: %s\n", argv[1], file); 3593e12c5d1SDavid du Colombier efree((char *)argv); 3603e12c5d1SDavid du Colombier } 36199eb86a7SDavid du Colombier #define NDIR 256 /* shoud be a better way */ 362dc5a79c1SDavid du Colombier 363dc5a79c1SDavid du Colombier int 364dc5a79c1SDavid du Colombier Globsize(char *p) 3653e12c5d1SDavid du Colombier { 36673e742d7SDavid du Colombier int isglob = 0, globlen = NDIR+1; 3673e12c5d1SDavid du Colombier for(;*p;p++){ 3683e12c5d1SDavid du Colombier if(*p==GLOB){ 3693e12c5d1SDavid du Colombier p++; 370dc5a79c1SDavid du Colombier if(*p!=GLOB) 371dc5a79c1SDavid du Colombier isglob++; 3729a747e4fSDavid du Colombier globlen+=*p=='*'?NDIR:1; 3733e12c5d1SDavid du Colombier } 3743e12c5d1SDavid du Colombier else 3753e12c5d1SDavid du Colombier globlen++; 3763e12c5d1SDavid du Colombier } 3773e12c5d1SDavid du Colombier return isglob?globlen:0; 3783e12c5d1SDavid du Colombier } 3793e12c5d1SDavid du Colombier #define NFD 50 380276e7d6dSDavid du Colombier 3813e12c5d1SDavid du Colombier struct{ 3829a747e4fSDavid du Colombier Dir *dbuf; 3839a747e4fSDavid du Colombier int i; 3843e12c5d1SDavid du Colombier int n; 3853e12c5d1SDavid du Colombier }dir[NFD]; 386dc5a79c1SDavid du Colombier 387dc5a79c1SDavid du Colombier int 388dc5a79c1SDavid du Colombier Opendir(char *name) 3893e12c5d1SDavid du Colombier { 3909a747e4fSDavid du Colombier Dir *db; 3913e12c5d1SDavid du Colombier int f; 3923e12c5d1SDavid du Colombier f = open(name, 0); 3933e12c5d1SDavid du Colombier if(f==-1) 3943e12c5d1SDavid du Colombier return f; 3959a747e4fSDavid du Colombier db = dirfstat(f); 3969a747e4fSDavid du Colombier if(db!=nil && (db->mode&DMDIR)){ 3979a747e4fSDavid du Colombier if(f<NFD){ 3989a747e4fSDavid du Colombier dir[f].i = 0; 3999a747e4fSDavid du Colombier dir[f].n = 0; 4003e12c5d1SDavid du Colombier } 4019a747e4fSDavid du Colombier free(db); 4023e12c5d1SDavid du Colombier return f; 4033e12c5d1SDavid du Colombier } 4049a747e4fSDavid du Colombier free(db); 4053e12c5d1SDavid du Colombier close(f); 4063e12c5d1SDavid du Colombier return -1; 4073e12c5d1SDavid du Colombier } 4086b6b9ac8SDavid du Colombier 4096b6b9ac8SDavid du Colombier static int 4106b6b9ac8SDavid du Colombier trimdirs(Dir *d, int nd) 4116b6b9ac8SDavid du Colombier { 4126b6b9ac8SDavid du Colombier int r, w; 4136b6b9ac8SDavid du Colombier 4146b6b9ac8SDavid du Colombier for(r=w=0; r<nd; r++) 4156b6b9ac8SDavid du Colombier if(d[r].mode&DMDIR) 4166b6b9ac8SDavid du Colombier d[w++] = d[r]; 4176b6b9ac8SDavid du Colombier return w; 4186b6b9ac8SDavid du Colombier } 4196b6b9ac8SDavid du Colombier 4206b6b9ac8SDavid du Colombier /* 4216b6b9ac8SDavid du Colombier * onlydirs is advisory -- it means you only 4226b6b9ac8SDavid du Colombier * need to return the directories. it's okay to 4236b6b9ac8SDavid du Colombier * return files too (e.g., on unix where you can't 4246b6b9ac8SDavid du Colombier * tell during the readdir), but that just makes 4256b6b9ac8SDavid du Colombier * the globber work harder. 4266b6b9ac8SDavid du Colombier */ 427dc5a79c1SDavid du Colombier int 428276e7d6dSDavid du Colombier Readdir(int f, void *p, int onlydirs) 4293e12c5d1SDavid du Colombier { 4303e12c5d1SDavid du Colombier int n; 431dc5a79c1SDavid du Colombier 4329a747e4fSDavid du Colombier if(f<0 || f>=NFD) 4333e12c5d1SDavid du Colombier return 0; 4346b6b9ac8SDavid du Colombier Again: 4359a747e4fSDavid du Colombier if(dir[f].i==dir[f].n){ /* read */ 4369a747e4fSDavid du Colombier free(dir[f].dbuf); 4379a747e4fSDavid du Colombier dir[f].dbuf = 0; 4389a747e4fSDavid du Colombier n = dirread(f, &dir[f].dbuf); 4396b6b9ac8SDavid du Colombier if(n>0){ 4406b6b9ac8SDavid du Colombier if(onlydirs){ 4416b6b9ac8SDavid du Colombier n = trimdirs(dir[f].dbuf, n); 4426b6b9ac8SDavid du Colombier if(n == 0) 4436b6b9ac8SDavid du Colombier goto Again; 4446b6b9ac8SDavid du Colombier } 4459a747e4fSDavid du Colombier dir[f].n = n; 4466b6b9ac8SDavid du Colombier }else 4473e12c5d1SDavid du Colombier dir[f].n = 0; 4489a747e4fSDavid du Colombier dir[f].i = 0; 4493e12c5d1SDavid du Colombier } 4509a747e4fSDavid du Colombier if(dir[f].i == dir[f].n) 4513e12c5d1SDavid du Colombier return 0; 4529a747e4fSDavid du Colombier strcpy(p, dir[f].dbuf[dir[f].i].name); 4539a747e4fSDavid du Colombier dir[f].i++; 4543e12c5d1SDavid du Colombier return 1; 4553e12c5d1SDavid du Colombier } 456dc5a79c1SDavid du Colombier 457dc5a79c1SDavid du Colombier void 458dc5a79c1SDavid du Colombier Closedir(int f) 459dc5a79c1SDavid du Colombier { 4609a747e4fSDavid du Colombier if(f>=0 && f<NFD){ 4619a747e4fSDavid du Colombier free(dir[f].dbuf); 4629a747e4fSDavid du Colombier dir[f].i = 0; 4639a747e4fSDavid du Colombier dir[f].n = 0; 4649a747e4fSDavid du Colombier dir[f].dbuf = 0; 4653e12c5d1SDavid du Colombier } 4663e12c5d1SDavid du Colombier close(f); 4673e12c5d1SDavid du Colombier } 4683e12c5d1SDavid du Colombier int interrupted = 0; 4693e12c5d1SDavid du Colombier void 4707dd7cddfSDavid du Colombier notifyf(void*, char *s) 4713e12c5d1SDavid du Colombier { 4723e12c5d1SDavid du Colombier int i; 47399eb86a7SDavid du Colombier for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){ 47499eb86a7SDavid du Colombier if(strncmp(s, "sys: ", 5)!=0) interrupted = 1; 4753e12c5d1SDavid du Colombier goto Out; 4763e12c5d1SDavid du Colombier } 4773e12c5d1SDavid du Colombier pfmt(err, "rc: note: %s\n", s); 4783e12c5d1SDavid du Colombier noted(NDFLT); 4793e12c5d1SDavid du Colombier return; 4803e12c5d1SDavid du Colombier Out: 481219b2ee8SDavid du Colombier if(strcmp(s, "interrupt")!=0 || trap[i]==0){ 4823e12c5d1SDavid du Colombier trap[i]++; 4833e12c5d1SDavid du Colombier ntrap++; 484219b2ee8SDavid du Colombier } 4853e12c5d1SDavid du Colombier if(ntrap>=32){ /* rc is probably in a trap loop */ 4863e12c5d1SDavid du Colombier pfmt(err, "rc: Too many traps (trap %s), aborting\n", s); 4873e12c5d1SDavid du Colombier abort(); 4883e12c5d1SDavid du Colombier } 4893e12c5d1SDavid du Colombier noted(NCONT); 4903e12c5d1SDavid du Colombier } 491dc5a79c1SDavid du Colombier 492dc5a79c1SDavid du Colombier void 493dc5a79c1SDavid du Colombier Trapinit(void) 494dc5a79c1SDavid du Colombier { 4953e12c5d1SDavid du Colombier notify(notifyf); 4963e12c5d1SDavid du Colombier } 497dc5a79c1SDavid du Colombier 498dc5a79c1SDavid du Colombier void 499dc5a79c1SDavid du Colombier Unlink(char *name) 5003e12c5d1SDavid du Colombier { 5013e12c5d1SDavid du Colombier remove(name); 5023e12c5d1SDavid du Colombier } 503dc5a79c1SDavid du Colombier 504dc5a79c1SDavid du Colombier long 505276e7d6dSDavid du Colombier Write(int fd, void *buf, long cnt) 5063e12c5d1SDavid du Colombier { 507276e7d6dSDavid du Colombier return write(fd, buf, cnt); 5083e12c5d1SDavid du Colombier } 509dc5a79c1SDavid du Colombier 510dc5a79c1SDavid du Colombier long 511276e7d6dSDavid du Colombier Read(int fd, void *buf, long cnt) 5123e12c5d1SDavid du Colombier { 5133e12c5d1SDavid du Colombier return read(fd, buf, cnt); 5143e12c5d1SDavid du Colombier } 515dc5a79c1SDavid du Colombier 516dc5a79c1SDavid du Colombier long 517dc5a79c1SDavid du Colombier Seek(int fd, long cnt, long whence) 5183e12c5d1SDavid du Colombier { 5193e12c5d1SDavid du Colombier return seek(fd, cnt, whence); 5203e12c5d1SDavid du Colombier } 521dc5a79c1SDavid du Colombier 522dc5a79c1SDavid du Colombier int 523dc5a79c1SDavid du Colombier Executable(char *file) 5243e12c5d1SDavid du Colombier { 5259a747e4fSDavid du Colombier Dir *statbuf; 5269a747e4fSDavid du Colombier int ret; 5273e12c5d1SDavid du Colombier 5289a747e4fSDavid du Colombier statbuf = dirstat(file); 529dc5a79c1SDavid du Colombier if(statbuf == nil) 530dc5a79c1SDavid du Colombier return 0; 53199eb86a7SDavid du Colombier ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0); 5329a747e4fSDavid du Colombier free(statbuf); 5339a747e4fSDavid du Colombier return ret; 5343e12c5d1SDavid du Colombier } 535dc5a79c1SDavid du Colombier 536dc5a79c1SDavid du Colombier int 537dc5a79c1SDavid du Colombier Creat(char *file) 5383e12c5d1SDavid du Colombier { 53999eb86a7SDavid du Colombier return create(file, 1, 0666L); 5403e12c5d1SDavid du Colombier } 541dc5a79c1SDavid du Colombier 542dc5a79c1SDavid du Colombier int 543dc5a79c1SDavid du Colombier Dup(int a, int b) 544dc5a79c1SDavid du Colombier { 5453e12c5d1SDavid du Colombier return dup(a, b); 5463e12c5d1SDavid du Colombier } 547dc5a79c1SDavid du Colombier 548dc5a79c1SDavid du Colombier int 549dc5a79c1SDavid du Colombier Dup1(int) 550dc5a79c1SDavid du Colombier { 5513e12c5d1SDavid du Colombier return -1; 5523e12c5d1SDavid du Colombier } 553dc5a79c1SDavid du Colombier 554dc5a79c1SDavid du Colombier void 555dc5a79c1SDavid du Colombier Exit(char *stat) 5563e12c5d1SDavid du Colombier { 5573e12c5d1SDavid du Colombier Updenv(); 5583e12c5d1SDavid du Colombier setstatus(stat); 5593e12c5d1SDavid du Colombier exits(truestatus()?"":getstatus()); 5603e12c5d1SDavid du Colombier } 561dc5a79c1SDavid du Colombier 562dc5a79c1SDavid du Colombier int 563dc5a79c1SDavid du Colombier Eintr(void) 564dc5a79c1SDavid du Colombier { 5653e12c5d1SDavid du Colombier return interrupted; 5663e12c5d1SDavid du Colombier } 567dc5a79c1SDavid du Colombier 568dc5a79c1SDavid du Colombier void 569dc5a79c1SDavid du Colombier Noerror(void) 570dc5a79c1SDavid du Colombier { 5713e12c5d1SDavid du Colombier interrupted = 0; 5723e12c5d1SDavid du Colombier } 573dc5a79c1SDavid du Colombier 574dc5a79c1SDavid du Colombier int 575dc5a79c1SDavid du Colombier Isatty(int fd) 576dc5a79c1SDavid du Colombier { 5774f281771SDavid du Colombier char buf[64]; 5783e12c5d1SDavid du Colombier 5794f281771SDavid du Colombier if(fd2path(fd, buf, sizeof buf) != 0) 580dc5a79c1SDavid du Colombier return 0; 5814f281771SDavid du Colombier 5823806af99SDavid du Colombier /* might be #c/cons during boot - fixed 22 april 2005, remove this later */ 5833806af99SDavid du Colombier if(strcmp(buf, "#c/cons") == 0) 5843806af99SDavid du Colombier return 1; 5853806af99SDavid du Colombier 5864f281771SDavid du Colombier /* might be /mnt/term/dev/cons */ 5874f281771SDavid du Colombier return strlen(buf) >= 9 && strcmp(buf+strlen(buf)-9, "/dev/cons") == 0; 5883e12c5d1SDavid du Colombier } 589dc5a79c1SDavid du Colombier 590dc5a79c1SDavid du Colombier void 591dc5a79c1SDavid du Colombier Abort(void) 592dc5a79c1SDavid du Colombier { 5933e12c5d1SDavid du Colombier pfmt(err, "aborting\n"); 5943e12c5d1SDavid du Colombier flush(err); 5953e12c5d1SDavid du Colombier Exit("aborting"); 5963e12c5d1SDavid du Colombier } 597dc5a79c1SDavid du Colombier 598dc5a79c1SDavid du Colombier void 599276e7d6dSDavid du Colombier Memcpy(void *a, void *b, long n) 6003e12c5d1SDavid du Colombier { 601276e7d6dSDavid du Colombier memmove(a, b, n); 6023e12c5d1SDavid du Colombier } 603dc5a79c1SDavid du Colombier 604dc5a79c1SDavid du Colombier void* 605dc5a79c1SDavid du Colombier Malloc(ulong n) 606dc5a79c1SDavid du Colombier { 6073e12c5d1SDavid du Colombier return malloc(n); 6083e12c5d1SDavid du Colombier } 609d3907fe5SDavid du Colombier 610d3907fe5SDavid du Colombier int *waitpids; 611d3907fe5SDavid du Colombier int nwaitpids; 612d3907fe5SDavid du Colombier 613d3907fe5SDavid du Colombier void 614d3907fe5SDavid du Colombier addwaitpid(int pid) 615d3907fe5SDavid du Colombier { 616d3907fe5SDavid du Colombier waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]); 617d3907fe5SDavid du Colombier if(waitpids == 0) 618d3907fe5SDavid du Colombier panic("Can't realloc %d waitpids", nwaitpids+1); 619d3907fe5SDavid du Colombier waitpids[nwaitpids++] = pid; 620d3907fe5SDavid du Colombier } 621d3907fe5SDavid du Colombier 622d3907fe5SDavid du Colombier void 623d3907fe5SDavid du Colombier delwaitpid(int pid) 624d3907fe5SDavid du Colombier { 625d3907fe5SDavid du Colombier int r, w; 626d3907fe5SDavid du Colombier 627d3907fe5SDavid du Colombier for(r=w=0; r<nwaitpids; r++) 628d3907fe5SDavid du Colombier if(waitpids[r] != pid) 629d3907fe5SDavid du Colombier waitpids[w++] = waitpids[r]; 630d3907fe5SDavid du Colombier nwaitpids = w; 631d3907fe5SDavid du Colombier } 632d3907fe5SDavid du Colombier 633d3907fe5SDavid du Colombier void 634d3907fe5SDavid du Colombier clearwaitpids(void) 635d3907fe5SDavid du Colombier { 636d3907fe5SDavid du Colombier nwaitpids = 0; 637d3907fe5SDavid du Colombier } 638d3907fe5SDavid du Colombier 639d3907fe5SDavid du Colombier int 640d3907fe5SDavid du Colombier havewaitpid(int pid) 641d3907fe5SDavid du Colombier { 642d3907fe5SDavid du Colombier int i; 643d3907fe5SDavid du Colombier 644d3907fe5SDavid du Colombier for(i=0; i<nwaitpids; i++) 645d3907fe5SDavid du Colombier if(waitpids[i] == pid) 646d3907fe5SDavid du Colombier return 1; 647d3907fe5SDavid du Colombier return 0; 648d3907fe5SDavid du Colombier } 649*f07722aaSDavid du Colombier 650*f07722aaSDavid du Colombier /* avoid loading any floating-point library code */ 651*f07722aaSDavid du Colombier int 652*f07722aaSDavid du Colombier _efgfmt(Fmt *) 653*f07722aaSDavid du Colombier { 654*f07722aaSDavid du Colombier return -1; 655*f07722aaSDavid du Colombier } 656