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" 113e12c5d1SDavid du Colombier char *Signame[] = { 123e12c5d1SDavid du Colombier "sigexit", "sighup", "sigint", "sigquit", 13219b2ee8SDavid du Colombier "sigalrm", "sigkill", "sigfpe", "sigterm", 14219b2ee8SDavid du Colombier 0 153e12c5d1SDavid du Colombier }; 163e12c5d1SDavid du Colombier char *syssigname[] = { 173e12c5d1SDavid du Colombier "exit", /* can't happen */ 183e12c5d1SDavid du Colombier "hangup", 193e12c5d1SDavid du Colombier "interrupt", 203e12c5d1SDavid du Colombier "quit", /* can't happen */ 213e12c5d1SDavid du Colombier "alarm", 22219b2ee8SDavid du Colombier "kill", 233e12c5d1SDavid du Colombier "sys: fp: ", 24219b2ee8SDavid du Colombier "term", 253e12c5d1SDavid du Colombier 0 263e12c5d1SDavid du Colombier }; 273e12c5d1SDavid du Colombier char Rcmain[]="/rc/lib/rcmain"; 283e12c5d1SDavid du Colombier char Fdprefix[]="/fd/"; 293e12c5d1SDavid du Colombier void execfinit(void); 303e12c5d1SDavid du Colombier void execbind(void); 313e12c5d1SDavid du Colombier void execmount(void); 323e12c5d1SDavid du Colombier void execnewpgrp(void); 333e12c5d1SDavid du Colombier builtin Builtin[] = { 343e12c5d1SDavid du Colombier "cd", execcd, 353e12c5d1SDavid du Colombier "whatis", execwhatis, 363e12c5d1SDavid du Colombier "eval", execeval, 373e12c5d1SDavid du Colombier "exec", execexec, /* but with popword first */ 383e12c5d1SDavid du Colombier "exit", execexit, 393e12c5d1SDavid du Colombier "shift", execshift, 403e12c5d1SDavid du Colombier "wait", execwait, 413e12c5d1SDavid du Colombier ".", execdot, 423e12c5d1SDavid du Colombier "finit", execfinit, 433e12c5d1SDavid du Colombier "flag", execflag, 443e12c5d1SDavid du Colombier "rfork", execnewpgrp, 453e12c5d1SDavid du Colombier 0 463e12c5d1SDavid du Colombier }; 47dc5a79c1SDavid du Colombier 48dc5a79c1SDavid du Colombier void 49dc5a79c1SDavid du Colombier execnewpgrp(void) 50dc5a79c1SDavid du Colombier { 513e12c5d1SDavid du Colombier int arg; 523e12c5d1SDavid du Colombier char *s; 533e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 54dc5a79c1SDavid du Colombier case 1: 55dc5a79c1SDavid du Colombier arg = RFENVG|RFNAMEG|RFNOTEG; 56dc5a79c1SDavid du Colombier break; 573e12c5d1SDavid du Colombier case 2: 583e12c5d1SDavid du Colombier arg = 0; 593e12c5d1SDavid du Colombier for(s = runq->argv->words->next->word;*s;s++) switch(*s){ 603e12c5d1SDavid du Colombier default: 613e12c5d1SDavid du Colombier goto Usage; 62dc5a79c1SDavid du Colombier case 'n': 63dc5a79c1SDavid du Colombier arg|=RFNAMEG; break; 64dc5a79c1SDavid du Colombier case 'N': 65dc5a79c1SDavid du Colombier arg|=RFCNAMEG; 66dc5a79c1SDavid du Colombier break; 67dc5a79c1SDavid du Colombier case 'm': 68dc5a79c1SDavid du Colombier arg|=RFNOMNT; break; 69dc5a79c1SDavid du Colombier case 'e': 70dc5a79c1SDavid du Colombier arg|=RFENVG; break; 71dc5a79c1SDavid du Colombier case 'E': 72dc5a79c1SDavid du Colombier arg|=RFCENVG; break; 73dc5a79c1SDavid du Colombier case 's': 74dc5a79c1SDavid du Colombier arg|=RFNOTEG; break; 75dc5a79c1SDavid du Colombier case 'f': 76dc5a79c1SDavid du Colombier arg|=RFFDG; break; 77dc5a79c1SDavid du Colombier case 'F': 78dc5a79c1SDavid du Colombier arg|=RFCFDG; break; 793e12c5d1SDavid du Colombier } 803e12c5d1SDavid du Colombier break; 813e12c5d1SDavid du Colombier default: 823e12c5d1SDavid du Colombier Usage: 837dd7cddfSDavid du Colombier pfmt(err, "Usage: %s [fnesFNEm]\n", runq->argv->words->word); 843e12c5d1SDavid du Colombier setstatus("rfork usage"); 853e12c5d1SDavid du Colombier poplist(); 863e12c5d1SDavid du Colombier return; 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier if(rfork(arg)==-1){ 893e12c5d1SDavid du Colombier pfmt(err, "rc: %s failed\n", runq->argv->words->word); 903e12c5d1SDavid du Colombier setstatus("rfork failed"); 913e12c5d1SDavid du Colombier } 923e12c5d1SDavid du Colombier else 933e12c5d1SDavid du Colombier setstatus(""); 943e12c5d1SDavid du Colombier poplist(); 953e12c5d1SDavid du Colombier } 96dc5a79c1SDavid du Colombier 97dc5a79c1SDavid du Colombier void 98dc5a79c1SDavid du Colombier Vinit(void) 99dc5a79c1SDavid du Colombier { 1009a747e4fSDavid du Colombier int dir, f, len; 1013e12c5d1SDavid du Colombier word *val; 1023e12c5d1SDavid du Colombier char *buf, *s; 1039a747e4fSDavid du Colombier Dir *ent; 1049a747e4fSDavid du Colombier int i, nent; 1059a747e4fSDavid du Colombier char envname[256]; 1069a747e4fSDavid du Colombier dir = open("/env", OREAD); 1073e12c5d1SDavid du Colombier if(dir<0){ 1089a747e4fSDavid du Colombier pfmt(err, "rc: can't open /env: %r\n"); 1093e12c5d1SDavid du Colombier return; 1103e12c5d1SDavid du Colombier } 1119a747e4fSDavid du Colombier ent = nil; 1129a747e4fSDavid du Colombier for(;;){ 1139a747e4fSDavid du Colombier nent = dirread(dir, &ent); 1149a747e4fSDavid du Colombier if(nent <= 0) 1159a747e4fSDavid du Colombier break; 1169a747e4fSDavid du Colombier for(i = 0; i<nent; i++){ 1179a747e4fSDavid du Colombier len = ent[i].length; 1189a747e4fSDavid du Colombier if(len && strncmp(ent[i].name, "fn#", 3)!=0){ 1199a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/%s", ent[i].name); 1203e12c5d1SDavid du Colombier if((f = open(envname, 0))>=0){ 1213e12c5d1SDavid du Colombier buf = emalloc((int)len+1); 1223e12c5d1SDavid du Colombier read(f, buf, (long)len); 1233e12c5d1SDavid du Colombier val = 0; 1243e12c5d1SDavid du Colombier /* Charitably add a 0 at the end if need be */ 125dc5a79c1SDavid du Colombier if(buf[len-1]) 126dc5a79c1SDavid du Colombier buf[len++]='\0'; 1273e12c5d1SDavid du Colombier s = buf+len-1; 1283e12c5d1SDavid du Colombier for(;;){ 1293e12c5d1SDavid du Colombier while(s!=buf && s[-1]!='\0') --s; 1303e12c5d1SDavid du Colombier val = newword(s, val); 131dc5a79c1SDavid du Colombier if(s==buf) 132dc5a79c1SDavid du Colombier break; 1333e12c5d1SDavid du Colombier --s; 1343e12c5d1SDavid du Colombier } 1359a747e4fSDavid du Colombier setvar(ent[i].name, val); 1369a747e4fSDavid du Colombier vlook(ent[i].name)->changed = 0; 1373e12c5d1SDavid du Colombier close(f); 1383e12c5d1SDavid du Colombier efree(buf); 1393e12c5d1SDavid du Colombier } 1403e12c5d1SDavid du Colombier } 1413e12c5d1SDavid du Colombier } 1429a747e4fSDavid du Colombier free(ent); 1439a747e4fSDavid du Colombier } 1443e12c5d1SDavid du Colombier close(dir); 1453e12c5d1SDavid du Colombier } 1463e12c5d1SDavid du Colombier int envdir; 147dc5a79c1SDavid du Colombier 148dc5a79c1SDavid du Colombier void 149dc5a79c1SDavid du Colombier Xrdfn(void) 150dc5a79c1SDavid du Colombier { 1513e12c5d1SDavid du Colombier int f, len; 1529a747e4fSDavid du Colombier static Dir *ent, *allocent; 1539a747e4fSDavid du Colombier static int nent; 1549a747e4fSDavid du Colombier Dir *e; 1559a747e4fSDavid du Colombier char envname[256]; 1569a747e4fSDavid du Colombier 1579a747e4fSDavid du Colombier for(;;){ 1589a747e4fSDavid du Colombier if(nent == 0){ 1599a747e4fSDavid du Colombier free(allocent); 1609a747e4fSDavid du Colombier nent = dirread(envdir, &allocent); 1619a747e4fSDavid du Colombier ent = allocent; 1629a747e4fSDavid du Colombier } 1639a747e4fSDavid du Colombier if(nent <= 0) 1649a747e4fSDavid du Colombier break; 1659a747e4fSDavid du Colombier while(nent){ 1669a747e4fSDavid du Colombier e = ent++; 1679a747e4fSDavid du Colombier nent--; 1689a747e4fSDavid du Colombier len = e->length; 1699a747e4fSDavid du Colombier if(len && strncmp(e->name, "fn#", 3)==0){ 1709a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/%s", e->name); 1713e12c5d1SDavid du Colombier if((f = open(envname, 0))>=0){ 1723e12c5d1SDavid du Colombier execcmds(openfd(f)); 1733e12c5d1SDavid du Colombier return; 1743e12c5d1SDavid du Colombier } 1753e12c5d1SDavid du Colombier } 1763e12c5d1SDavid du Colombier } 1779a747e4fSDavid du Colombier } 1783e12c5d1SDavid du Colombier close(envdir); 1793e12c5d1SDavid du Colombier Xreturn(); 1803e12c5d1SDavid du Colombier } 1813e12c5d1SDavid du Colombier union code rdfns[4]; 182dc5a79c1SDavid du Colombier 183dc5a79c1SDavid du Colombier void 184dc5a79c1SDavid du Colombier execfinit(void) 185dc5a79c1SDavid du Colombier { 1863e12c5d1SDavid du Colombier static int first = 1; 1873e12c5d1SDavid du Colombier if(first){ 1883e12c5d1SDavid du Colombier rdfns[0].i = 1; 1893e12c5d1SDavid du Colombier rdfns[1].f = Xrdfn; 1903e12c5d1SDavid du Colombier rdfns[2].f = Xjump; 1913e12c5d1SDavid du Colombier rdfns[3].i = 1; 1923e12c5d1SDavid du Colombier first = 0; 1933e12c5d1SDavid du Colombier } 1943e12c5d1SDavid du Colombier Xpopm(); 1959a747e4fSDavid du Colombier envdir = open("/env", 0); 1963e12c5d1SDavid du Colombier if(envdir<0){ 1979a747e4fSDavid du Colombier pfmt(err, "rc: can't open /env: %r\n"); 1983e12c5d1SDavid du Colombier return; 1993e12c5d1SDavid du Colombier } 2003e12c5d1SDavid du Colombier start(rdfns, 1, runq->local); 2013e12c5d1SDavid du Colombier } 202dc5a79c1SDavid du Colombier 203dc5a79c1SDavid du Colombier int 204dc5a79c1SDavid du Colombier Waitfor(int pid, int) 205dc5a79c1SDavid du Colombier { 2063e12c5d1SDavid du Colombier thread *p; 2079a747e4fSDavid du Colombier Waitmsg *w; 2089a747e4fSDavid du Colombier char errbuf[ERRMAX]; 2099a747e4fSDavid du Colombier 210*d3907fe5SDavid du Colombier if(pid >= 0 && !havewaitpid(pid)) 211*d3907fe5SDavid du Colombier return 0; 212*d3907fe5SDavid du Colombier 2139a747e4fSDavid du Colombier while((w = wait()) != nil){ 214*d3907fe5SDavid du Colombier delwaitpid(w->pid); 2159a747e4fSDavid du Colombier if(w->pid==pid){ 2169a747e4fSDavid du Colombier setstatus(w->msg); 2179a747e4fSDavid du Colombier free(w); 218219b2ee8SDavid du Colombier return 0; 2193e12c5d1SDavid du Colombier } 2203e12c5d1SDavid du Colombier for(p = runq->ret;p;p = p->ret) 2219a747e4fSDavid du Colombier if(p->pid==w->pid){ 2223e12c5d1SDavid du Colombier p->pid=-1; 2239a747e4fSDavid du Colombier strcpy(p->status, w->msg); 2243e12c5d1SDavid du Colombier } 2259a747e4fSDavid du Colombier free(w); 2263e12c5d1SDavid du Colombier } 2279a747e4fSDavid du Colombier 2289a747e4fSDavid du Colombier errstr(errbuf, sizeof errbuf); 229219b2ee8SDavid du Colombier if(strcmp(errbuf, "interrupted")==0) return -1; 2303e12c5d1SDavid du Colombier return 0; 2313e12c5d1SDavid du Colombier } 232dc5a79c1SDavid du Colombier 233dc5a79c1SDavid du Colombier char* 234dc5a79c1SDavid du Colombier *mkargv(word *a) 2353e12c5d1SDavid du Colombier { 2363e12c5d1SDavid du Colombier char **argv = (char **)emalloc((count(a)+2)*sizeof(char *)); 2373e12c5d1SDavid du Colombier char **argp = argv+1; /* leave one at front for runcoms */ 2383e12c5d1SDavid du Colombier for(;a;a = a->next) *argp++=a->word; 2393e12c5d1SDavid du Colombier *argp = 0; 2403e12c5d1SDavid du Colombier return argv; 2413e12c5d1SDavid du Colombier } 242dc5a79c1SDavid du Colombier 243dc5a79c1SDavid du Colombier void 244dc5a79c1SDavid du Colombier addenv(var *v) 2453e12c5d1SDavid du Colombier { 2469a747e4fSDavid du Colombier char envname[256]; 2473e12c5d1SDavid du Colombier word *w; 2483e12c5d1SDavid du Colombier int f; 2493e12c5d1SDavid du Colombier io *fd; 2503e12c5d1SDavid du Colombier if(v->changed){ 2513e12c5d1SDavid du Colombier v->changed = 0; 2529a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/%s", v->name); 2533e12c5d1SDavid du Colombier if((f = Creat(envname))<0) 2549a747e4fSDavid du Colombier pfmt(err, "rc: can't open %s: %r\n", envname); 2553e12c5d1SDavid du Colombier else{ 2563e12c5d1SDavid du Colombier for(w = v->val;w;w = w->next) 2573e12c5d1SDavid du Colombier write(f, w->word, strlen(w->word)+1L); 2583e12c5d1SDavid du Colombier close(f); 2593e12c5d1SDavid du Colombier } 2603e12c5d1SDavid du Colombier } 2613e12c5d1SDavid du Colombier if(v->fnchanged){ 2623e12c5d1SDavid du Colombier v->fnchanged = 0; 2639a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/fn#%s", v->name); 2643e12c5d1SDavid du Colombier if((f = Creat(envname))<0) 2659a747e4fSDavid du Colombier pfmt(err, "rc: can't open %s: %r\n", envname); 2663e12c5d1SDavid du Colombier else{ 2673e12c5d1SDavid du Colombier if(v->fn){ 2683e12c5d1SDavid du Colombier fd = openfd(f); 2693e12c5d1SDavid du Colombier pfmt(fd, "fn %s %s\n", v->name, v->fn[v->pc-1].s); 2703e12c5d1SDavid du Colombier closeio(fd); 2713e12c5d1SDavid du Colombier } 2723e12c5d1SDavid du Colombier close(f); 2733e12c5d1SDavid du Colombier } 2743e12c5d1SDavid du Colombier } 2753e12c5d1SDavid du Colombier } 276dc5a79c1SDavid du Colombier 277dc5a79c1SDavid du Colombier void 278dc5a79c1SDavid du Colombier updenvlocal(var *v) 2793e12c5d1SDavid du Colombier { 2803e12c5d1SDavid du Colombier if(v){ 2813e12c5d1SDavid du Colombier updenvlocal(v->next); 2823e12c5d1SDavid du Colombier addenv(v); 2833e12c5d1SDavid du Colombier } 2843e12c5d1SDavid du Colombier } 285dc5a79c1SDavid du Colombier 286dc5a79c1SDavid du Colombier void 287dc5a79c1SDavid du Colombier Updenv(void) 288dc5a79c1SDavid du Colombier { 2893e12c5d1SDavid du Colombier var *v, **h; 2903e12c5d1SDavid du Colombier for(h = gvar;h!=&gvar[NVAR];h++) 2913e12c5d1SDavid du Colombier for(v=*h;v;v = v->next) 2923e12c5d1SDavid du Colombier addenv(v); 293dc5a79c1SDavid du Colombier if(runq) 294dc5a79c1SDavid du Colombier updenvlocal(runq->local); 2953e12c5d1SDavid du Colombier } 296dc5a79c1SDavid du Colombier 297dc5a79c1SDavid du Colombier int 298dc5a79c1SDavid du Colombier ForkExecute(char *file, char **argv, int sin, int sout, int serr) 299dc5a79c1SDavid du Colombier { 300dc5a79c1SDavid du Colombier int pid; 301dc5a79c1SDavid du Colombier 302dc5a79c1SDavid du Colombier if(access(file, 1) != 0) 303dc5a79c1SDavid du Colombier return -1; 304dc5a79c1SDavid du Colombier switch(pid = fork()){ 305dc5a79c1SDavid du Colombier case -1: 306dc5a79c1SDavid du Colombier return -1; 307dc5a79c1SDavid du Colombier case 0: 308dc5a79c1SDavid du Colombier if(sin >= 0) 309dc5a79c1SDavid du Colombier dup(sin, 0); 310dc5a79c1SDavid du Colombier else 311dc5a79c1SDavid du Colombier close(0); 312dc5a79c1SDavid du Colombier if(sout >= 0) 313dc5a79c1SDavid du Colombier dup(sout, 1); 314dc5a79c1SDavid du Colombier else 315dc5a79c1SDavid du Colombier close(1); 316dc5a79c1SDavid du Colombier if(serr >= 0) 317dc5a79c1SDavid du Colombier dup(serr, 2); 318dc5a79c1SDavid du Colombier else 319dc5a79c1SDavid du Colombier close(2); 320dc5a79c1SDavid du Colombier exec(file, argv); 321dc5a79c1SDavid du Colombier exits(file); 322dc5a79c1SDavid du Colombier } 323dc5a79c1SDavid du Colombier return pid; 324dc5a79c1SDavid du Colombier } 325dc5a79c1SDavid du Colombier 326dc5a79c1SDavid du Colombier void 327dc5a79c1SDavid du Colombier Execute(word *args, word *path) 3283e12c5d1SDavid du Colombier { 3293e12c5d1SDavid du Colombier char **argv = mkargv(args); 330219b2ee8SDavid du Colombier char file[1024]; 331219b2ee8SDavid du Colombier int nc; 3323e12c5d1SDavid du Colombier Updenv(); 3333e12c5d1SDavid du Colombier for(;path;path = path->next){ 334219b2ee8SDavid du Colombier nc = strlen(path->word); 335219b2ee8SDavid du Colombier if(nc<1024){ 3363e12c5d1SDavid du Colombier strcpy(file, path->word); 337219b2ee8SDavid du Colombier if(file[0]){ 338219b2ee8SDavid du Colombier strcat(file, "/"); 339219b2ee8SDavid du Colombier nc++; 340219b2ee8SDavid du Colombier } 341219b2ee8SDavid du Colombier if(nc+strlen(argv[1])<1024){ 3423e12c5d1SDavid du Colombier strcat(file, argv[1]); 3433e12c5d1SDavid du Colombier exec(file, argv+1); 3443e12c5d1SDavid du Colombier } 345219b2ee8SDavid du Colombier else werrstr("command name too long"); 346219b2ee8SDavid du Colombier } 347219b2ee8SDavid du Colombier } 3489a747e4fSDavid du Colombier rerrstr(file, sizeof file); 3493e12c5d1SDavid du Colombier pfmt(err, "%s: %s\n", argv[1], file); 3503e12c5d1SDavid du Colombier efree((char *)argv); 3513e12c5d1SDavid du Colombier } 3529a747e4fSDavid du Colombier #define NDIR 256 /* shoud be a better way */ 353dc5a79c1SDavid du Colombier 354dc5a79c1SDavid du Colombier int 355dc5a79c1SDavid du Colombier Globsize(char *p) 3563e12c5d1SDavid du Colombier { 35773e742d7SDavid du Colombier int isglob = 0, globlen = NDIR+1; 3583e12c5d1SDavid du Colombier for(;*p;p++){ 3593e12c5d1SDavid du Colombier if(*p==GLOB){ 3603e12c5d1SDavid du Colombier p++; 361dc5a79c1SDavid du Colombier if(*p!=GLOB) 362dc5a79c1SDavid du Colombier isglob++; 3639a747e4fSDavid du Colombier globlen+=*p=='*'?NDIR:1; 3643e12c5d1SDavid du Colombier } 3653e12c5d1SDavid du Colombier else 3663e12c5d1SDavid du Colombier globlen++; 3673e12c5d1SDavid du Colombier } 3683e12c5d1SDavid du Colombier return isglob?globlen:0; 3693e12c5d1SDavid du Colombier } 3703e12c5d1SDavid du Colombier #define NFD 50 3713e12c5d1SDavid du Colombier #define NDBUF 32 3723e12c5d1SDavid du Colombier struct{ 3739a747e4fSDavid du Colombier Dir *dbuf; 3749a747e4fSDavid du Colombier int i; 3753e12c5d1SDavid du Colombier int n; 3763e12c5d1SDavid du Colombier }dir[NFD]; 377dc5a79c1SDavid du Colombier 378dc5a79c1SDavid du Colombier int 379dc5a79c1SDavid du Colombier Opendir(char *name) 3803e12c5d1SDavid du Colombier { 3819a747e4fSDavid du Colombier Dir *db; 3823e12c5d1SDavid du Colombier int f; 3833e12c5d1SDavid du Colombier f = open(name, 0); 3843e12c5d1SDavid du Colombier if(f==-1) 3853e12c5d1SDavid du Colombier return f; 3869a747e4fSDavid du Colombier db = dirfstat(f); 3879a747e4fSDavid du Colombier if(db!=nil && (db->mode&DMDIR)){ 3889a747e4fSDavid du Colombier if(f<NFD){ 3899a747e4fSDavid du Colombier dir[f].i = 0; 3909a747e4fSDavid du Colombier dir[f].n = 0; 3913e12c5d1SDavid du Colombier } 3929a747e4fSDavid du Colombier free(db); 3933e12c5d1SDavid du Colombier return f; 3943e12c5d1SDavid du Colombier } 3959a747e4fSDavid du Colombier free(db); 3963e12c5d1SDavid du Colombier close(f); 3973e12c5d1SDavid du Colombier return -1; 3983e12c5d1SDavid du Colombier } 3996b6b9ac8SDavid du Colombier 4006b6b9ac8SDavid du Colombier static int 4016b6b9ac8SDavid du Colombier trimdirs(Dir *d, int nd) 4026b6b9ac8SDavid du Colombier { 4036b6b9ac8SDavid du Colombier int r, w; 4046b6b9ac8SDavid du Colombier 4056b6b9ac8SDavid du Colombier for(r=w=0; r<nd; r++) 4066b6b9ac8SDavid du Colombier if(d[r].mode&DMDIR) 4076b6b9ac8SDavid du Colombier d[w++] = d[r]; 4086b6b9ac8SDavid du Colombier return w; 4096b6b9ac8SDavid du Colombier } 4106b6b9ac8SDavid du Colombier 4116b6b9ac8SDavid du Colombier /* 4126b6b9ac8SDavid du Colombier * onlydirs is advisory -- it means you only 4136b6b9ac8SDavid du Colombier * need to return the directories. it's okay to 4146b6b9ac8SDavid du Colombier * return files too (e.g., on unix where you can't 4156b6b9ac8SDavid du Colombier * tell during the readdir), but that just makes 4166b6b9ac8SDavid du Colombier * the globber work harder. 4176b6b9ac8SDavid du Colombier */ 418dc5a79c1SDavid du Colombier int 419dc5a79c1SDavid du Colombier Readdir(int f, char *p, int onlydirs) 4203e12c5d1SDavid du Colombier { 4213e12c5d1SDavid du Colombier int n; 422dc5a79c1SDavid du Colombier 4239a747e4fSDavid du Colombier if(f<0 || f>=NFD) 4243e12c5d1SDavid du Colombier return 0; 4256b6b9ac8SDavid du Colombier Again: 4269a747e4fSDavid du Colombier if(dir[f].i==dir[f].n){ /* read */ 4279a747e4fSDavid du Colombier free(dir[f].dbuf); 4289a747e4fSDavid du Colombier dir[f].dbuf = 0; 4299a747e4fSDavid du Colombier n = dirread(f, &dir[f].dbuf); 4306b6b9ac8SDavid du Colombier if(n>0){ 4316b6b9ac8SDavid du Colombier if(onlydirs){ 4326b6b9ac8SDavid du Colombier n = trimdirs(dir[f].dbuf, n); 4336b6b9ac8SDavid du Colombier if(n == 0) 4346b6b9ac8SDavid du Colombier goto Again; 4356b6b9ac8SDavid du Colombier } 4369a747e4fSDavid du Colombier dir[f].n = n; 4376b6b9ac8SDavid du Colombier }else 4383e12c5d1SDavid du Colombier dir[f].n = 0; 4399a747e4fSDavid du Colombier dir[f].i = 0; 4403e12c5d1SDavid du Colombier } 4419a747e4fSDavid du Colombier if(dir[f].i == dir[f].n) 4423e12c5d1SDavid du Colombier return 0; 4439a747e4fSDavid du Colombier strcpy(p, dir[f].dbuf[dir[f].i].name); 4449a747e4fSDavid du Colombier dir[f].i++; 4453e12c5d1SDavid du Colombier return 1; 4463e12c5d1SDavid du Colombier } 447dc5a79c1SDavid du Colombier 448dc5a79c1SDavid du Colombier void 449dc5a79c1SDavid du Colombier Closedir(int f) 450dc5a79c1SDavid du Colombier { 4519a747e4fSDavid du Colombier if(f>=0 && f<NFD){ 4529a747e4fSDavid du Colombier free(dir[f].dbuf); 4539a747e4fSDavid du Colombier dir[f].i = 0; 4549a747e4fSDavid du Colombier dir[f].n = 0; 4559a747e4fSDavid du Colombier dir[f].dbuf = 0; 4563e12c5d1SDavid du Colombier } 4573e12c5d1SDavid du Colombier close(f); 4583e12c5d1SDavid du Colombier } 4593e12c5d1SDavid du Colombier int interrupted = 0; 4603e12c5d1SDavid du Colombier void 4617dd7cddfSDavid du Colombier notifyf(void*, char *s) 4623e12c5d1SDavid du Colombier { 4633e12c5d1SDavid du Colombier int i; 4643e12c5d1SDavid du Colombier for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){ 4653e12c5d1SDavid du Colombier if(strncmp(s, "sys: ", 5)!=0) interrupted = 1; 4663e12c5d1SDavid du Colombier goto Out; 4673e12c5d1SDavid du Colombier } 4683e12c5d1SDavid du Colombier pfmt(err, "rc: note: %s\n", s); 4693e12c5d1SDavid du Colombier noted(NDFLT); 4703e12c5d1SDavid du Colombier return; 4713e12c5d1SDavid du Colombier Out: 472219b2ee8SDavid du Colombier if(strcmp(s, "interrupt")!=0 || trap[i]==0){ 4733e12c5d1SDavid du Colombier trap[i]++; 4743e12c5d1SDavid du Colombier ntrap++; 475219b2ee8SDavid du Colombier } 4763e12c5d1SDavid du Colombier if(ntrap>=32){ /* rc is probably in a trap loop */ 4773e12c5d1SDavid du Colombier pfmt(err, "rc: Too many traps (trap %s), aborting\n", s); 4783e12c5d1SDavid du Colombier abort(); 4793e12c5d1SDavid du Colombier } 4803e12c5d1SDavid du Colombier noted(NCONT); 4813e12c5d1SDavid du Colombier } 482dc5a79c1SDavid du Colombier 483dc5a79c1SDavid du Colombier void 484dc5a79c1SDavid du Colombier Trapinit(void) 485dc5a79c1SDavid du Colombier { 4863e12c5d1SDavid du Colombier notify(notifyf); 4873e12c5d1SDavid du Colombier } 488dc5a79c1SDavid du Colombier 489dc5a79c1SDavid du Colombier void 490dc5a79c1SDavid du Colombier Unlink(char *name) 4913e12c5d1SDavid du Colombier { 4923e12c5d1SDavid du Colombier remove(name); 4933e12c5d1SDavid du Colombier } 494dc5a79c1SDavid du Colombier 495dc5a79c1SDavid du Colombier long 496dc5a79c1SDavid du Colombier Write(int fd, char *buf, long cnt) 4973e12c5d1SDavid du Colombier { 4983e12c5d1SDavid du Colombier return write(fd, buf, (long)cnt); 4993e12c5d1SDavid du Colombier } 500dc5a79c1SDavid du Colombier 501dc5a79c1SDavid du Colombier long 502dc5a79c1SDavid du Colombier Read(int fd, char *buf, long cnt) 5033e12c5d1SDavid du Colombier { 5043e12c5d1SDavid du Colombier return read(fd, buf, cnt); 5053e12c5d1SDavid du Colombier } 506dc5a79c1SDavid du Colombier 507dc5a79c1SDavid du Colombier long 508dc5a79c1SDavid du Colombier Seek(int fd, long cnt, long whence) 5093e12c5d1SDavid du Colombier { 5103e12c5d1SDavid du Colombier return seek(fd, cnt, whence); 5113e12c5d1SDavid du Colombier } 512dc5a79c1SDavid du Colombier 513dc5a79c1SDavid du Colombier int 514dc5a79c1SDavid du Colombier Executable(char *file) 5153e12c5d1SDavid du Colombier { 5169a747e4fSDavid du Colombier Dir *statbuf; 5179a747e4fSDavid du Colombier int ret; 5183e12c5d1SDavid du Colombier 5199a747e4fSDavid du Colombier statbuf = dirstat(file); 520dc5a79c1SDavid du Colombier if(statbuf == nil) 521dc5a79c1SDavid du Colombier return 0; 5229a747e4fSDavid du Colombier ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0); 5239a747e4fSDavid du Colombier free(statbuf); 5249a747e4fSDavid du Colombier return ret; 5253e12c5d1SDavid du Colombier } 526dc5a79c1SDavid du Colombier 527dc5a79c1SDavid du Colombier int 528dc5a79c1SDavid du Colombier Creat(char *file) 5293e12c5d1SDavid du Colombier { 5303e12c5d1SDavid du Colombier return create(file, 1, 0666L); 5313e12c5d1SDavid du Colombier } 532dc5a79c1SDavid du Colombier 533dc5a79c1SDavid du Colombier int 534dc5a79c1SDavid du Colombier Dup(int a, int b) 535dc5a79c1SDavid du Colombier { 5363e12c5d1SDavid du Colombier return dup(a, b); 5373e12c5d1SDavid du Colombier } 538dc5a79c1SDavid du Colombier 539dc5a79c1SDavid du Colombier int 540dc5a79c1SDavid du Colombier Dup1(int) 541dc5a79c1SDavid du Colombier { 5423e12c5d1SDavid du Colombier return -1; 5433e12c5d1SDavid du Colombier } 544dc5a79c1SDavid du Colombier 545dc5a79c1SDavid du Colombier void 546dc5a79c1SDavid du Colombier Exit(char *stat) 5473e12c5d1SDavid du Colombier { 5483e12c5d1SDavid du Colombier Updenv(); 5493e12c5d1SDavid du Colombier setstatus(stat); 5503e12c5d1SDavid du Colombier exits(truestatus()?"":getstatus()); 5513e12c5d1SDavid du Colombier } 552dc5a79c1SDavid du Colombier 553dc5a79c1SDavid du Colombier int 554dc5a79c1SDavid du Colombier Eintr(void) 555dc5a79c1SDavid du Colombier { 5563e12c5d1SDavid du Colombier return interrupted; 5573e12c5d1SDavid du Colombier } 558dc5a79c1SDavid du Colombier 559dc5a79c1SDavid du Colombier void 560dc5a79c1SDavid du Colombier Noerror(void) 561dc5a79c1SDavid du Colombier { 5623e12c5d1SDavid du Colombier interrupted = 0; 5633e12c5d1SDavid du Colombier } 564dc5a79c1SDavid du Colombier 565dc5a79c1SDavid du Colombier int 566dc5a79c1SDavid du Colombier Isatty(int fd) 567dc5a79c1SDavid du Colombier { 5684f281771SDavid du Colombier char buf[64]; 5693e12c5d1SDavid du Colombier 5704f281771SDavid du Colombier if(fd2path(fd, buf, sizeof buf) != 0) 571dc5a79c1SDavid du Colombier return 0; 5724f281771SDavid du Colombier 5733806af99SDavid du Colombier /* might be #c/cons during boot - fixed 22 april 2005, remove this later */ 5743806af99SDavid du Colombier if(strcmp(buf, "#c/cons") == 0) 5753806af99SDavid du Colombier return 1; 5763806af99SDavid du Colombier 5774f281771SDavid du Colombier /* might be /mnt/term/dev/cons */ 5784f281771SDavid du Colombier return strlen(buf) >= 9 && strcmp(buf+strlen(buf)-9, "/dev/cons") == 0; 5793e12c5d1SDavid du Colombier } 580dc5a79c1SDavid du Colombier 581dc5a79c1SDavid du Colombier void 582dc5a79c1SDavid du Colombier Abort(void) 583dc5a79c1SDavid du Colombier { 5843e12c5d1SDavid du Colombier pfmt(err, "aborting\n"); 5853e12c5d1SDavid du Colombier flush(err); 5863e12c5d1SDavid du Colombier Exit("aborting"); 5873e12c5d1SDavid du Colombier } 588dc5a79c1SDavid du Colombier 589dc5a79c1SDavid du Colombier void 590dc5a79c1SDavid du Colombier Memcpy(char *a, char *b, long n) 5913e12c5d1SDavid du Colombier { 5923e12c5d1SDavid du Colombier memmove(a, b, (long)n); 5933e12c5d1SDavid du Colombier } 594dc5a79c1SDavid du Colombier 595dc5a79c1SDavid du Colombier void* 596dc5a79c1SDavid du Colombier Malloc(ulong n) 597dc5a79c1SDavid du Colombier { 5983e12c5d1SDavid du Colombier return malloc(n); 5993e12c5d1SDavid du Colombier } 600*d3907fe5SDavid du Colombier 601*d3907fe5SDavid du Colombier int *waitpids; 602*d3907fe5SDavid du Colombier int nwaitpids; 603*d3907fe5SDavid du Colombier 604*d3907fe5SDavid du Colombier void 605*d3907fe5SDavid du Colombier addwaitpid(int pid) 606*d3907fe5SDavid du Colombier { 607*d3907fe5SDavid du Colombier waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]); 608*d3907fe5SDavid du Colombier if(waitpids == 0) 609*d3907fe5SDavid du Colombier panic("Can't realloc %d waitpids", nwaitpids+1); 610*d3907fe5SDavid du Colombier waitpids[nwaitpids++] = pid; 611*d3907fe5SDavid du Colombier } 612*d3907fe5SDavid du Colombier 613*d3907fe5SDavid du Colombier void 614*d3907fe5SDavid du Colombier delwaitpid(int pid) 615*d3907fe5SDavid du Colombier { 616*d3907fe5SDavid du Colombier int r, w; 617*d3907fe5SDavid du Colombier 618*d3907fe5SDavid du Colombier for(r=w=0; r<nwaitpids; r++) 619*d3907fe5SDavid du Colombier if(waitpids[r] != pid) 620*d3907fe5SDavid du Colombier waitpids[w++] = waitpids[r]; 621*d3907fe5SDavid du Colombier nwaitpids = w; 622*d3907fe5SDavid du Colombier } 623*d3907fe5SDavid du Colombier 624*d3907fe5SDavid du Colombier void 625*d3907fe5SDavid du Colombier clearwaitpids(void) 626*d3907fe5SDavid du Colombier { 627*d3907fe5SDavid du Colombier nwaitpids = 0; 628*d3907fe5SDavid du Colombier } 629*d3907fe5SDavid du Colombier 630*d3907fe5SDavid du Colombier int 631*d3907fe5SDavid du Colombier havewaitpid(int pid) 632*d3907fe5SDavid du Colombier { 633*d3907fe5SDavid du Colombier int i; 634*d3907fe5SDavid du Colombier 635*d3907fe5SDavid du Colombier for(i=0; i<nwaitpids; i++) 636*d3907fe5SDavid du Colombier if(waitpids[i] == pid) 637*d3907fe5SDavid du Colombier return 1; 638*d3907fe5SDavid du Colombier return 0; 639*d3907fe5SDavid du Colombier } 640