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 2109a747e4fSDavid du Colombier while((w = wait()) != nil){ 2119a747e4fSDavid du Colombier if(w->pid==pid){ 2129a747e4fSDavid du Colombier setstatus(w->msg); 2139a747e4fSDavid du Colombier free(w); 214219b2ee8SDavid du Colombier return 0; 2153e12c5d1SDavid du Colombier } 2163e12c5d1SDavid du Colombier for(p = runq->ret;p;p = p->ret) 2179a747e4fSDavid du Colombier if(p->pid==w->pid){ 2183e12c5d1SDavid du Colombier p->pid=-1; 2199a747e4fSDavid du Colombier strcpy(p->status, w->msg); 2203e12c5d1SDavid du Colombier } 2219a747e4fSDavid du Colombier free(w); 2223e12c5d1SDavid du Colombier } 2239a747e4fSDavid du Colombier 2249a747e4fSDavid du Colombier errstr(errbuf, sizeof errbuf); 225219b2ee8SDavid du Colombier if(strcmp(errbuf, "interrupted")==0) return -1; 2263e12c5d1SDavid du Colombier return 0; 2273e12c5d1SDavid du Colombier } 228dc5a79c1SDavid du Colombier 229dc5a79c1SDavid du Colombier char* 230dc5a79c1SDavid du Colombier *mkargv(word *a) 2313e12c5d1SDavid du Colombier { 2323e12c5d1SDavid du Colombier char **argv = (char **)emalloc((count(a)+2)*sizeof(char *)); 2333e12c5d1SDavid du Colombier char **argp = argv+1; /* leave one at front for runcoms */ 2343e12c5d1SDavid du Colombier for(;a;a = a->next) *argp++=a->word; 2353e12c5d1SDavid du Colombier *argp = 0; 2363e12c5d1SDavid du Colombier return argv; 2373e12c5d1SDavid du Colombier } 238dc5a79c1SDavid du Colombier 239dc5a79c1SDavid du Colombier void 240dc5a79c1SDavid du Colombier addenv(var *v) 2413e12c5d1SDavid du Colombier { 2429a747e4fSDavid du Colombier char envname[256]; 2433e12c5d1SDavid du Colombier word *w; 2443e12c5d1SDavid du Colombier int f; 2453e12c5d1SDavid du Colombier io *fd; 2463e12c5d1SDavid du Colombier if(v->changed){ 2473e12c5d1SDavid du Colombier v->changed = 0; 2489a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/%s", v->name); 2493e12c5d1SDavid du Colombier if((f = Creat(envname))<0) 2509a747e4fSDavid du Colombier pfmt(err, "rc: can't open %s: %r\n", envname); 2513e12c5d1SDavid du Colombier else{ 2523e12c5d1SDavid du Colombier for(w = v->val;w;w = w->next) 2533e12c5d1SDavid du Colombier write(f, w->word, strlen(w->word)+1L); 2543e12c5d1SDavid du Colombier close(f); 2553e12c5d1SDavid du Colombier } 2563e12c5d1SDavid du Colombier } 2573e12c5d1SDavid du Colombier if(v->fnchanged){ 2583e12c5d1SDavid du Colombier v->fnchanged = 0; 2599a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/fn#%s", v->name); 2603e12c5d1SDavid du Colombier if((f = Creat(envname))<0) 2619a747e4fSDavid du Colombier pfmt(err, "rc: can't open %s: %r\n", envname); 2623e12c5d1SDavid du Colombier else{ 2633e12c5d1SDavid du Colombier if(v->fn){ 2643e12c5d1SDavid du Colombier fd = openfd(f); 2653e12c5d1SDavid du Colombier pfmt(fd, "fn %s %s\n", v->name, v->fn[v->pc-1].s); 2663e12c5d1SDavid du Colombier closeio(fd); 2673e12c5d1SDavid du Colombier } 2683e12c5d1SDavid du Colombier close(f); 2693e12c5d1SDavid du Colombier } 2703e12c5d1SDavid du Colombier } 2713e12c5d1SDavid du Colombier } 272dc5a79c1SDavid du Colombier 273dc5a79c1SDavid du Colombier void 274dc5a79c1SDavid du Colombier updenvlocal(var *v) 2753e12c5d1SDavid du Colombier { 2763e12c5d1SDavid du Colombier if(v){ 2773e12c5d1SDavid du Colombier updenvlocal(v->next); 2783e12c5d1SDavid du Colombier addenv(v); 2793e12c5d1SDavid du Colombier } 2803e12c5d1SDavid du Colombier } 281dc5a79c1SDavid du Colombier 282dc5a79c1SDavid du Colombier void 283dc5a79c1SDavid du Colombier Updenv(void) 284dc5a79c1SDavid du Colombier { 2853e12c5d1SDavid du Colombier var *v, **h; 2863e12c5d1SDavid du Colombier for(h = gvar;h!=&gvar[NVAR];h++) 2873e12c5d1SDavid du Colombier for(v=*h;v;v = v->next) 2883e12c5d1SDavid du Colombier addenv(v); 289dc5a79c1SDavid du Colombier if(runq) 290dc5a79c1SDavid du Colombier updenvlocal(runq->local); 2913e12c5d1SDavid du Colombier } 292dc5a79c1SDavid du Colombier 293dc5a79c1SDavid du Colombier int 294dc5a79c1SDavid du Colombier ForkExecute(char *file, char **argv, int sin, int sout, int serr) 295dc5a79c1SDavid du Colombier { 296dc5a79c1SDavid du Colombier int pid; 297dc5a79c1SDavid du Colombier 298dc5a79c1SDavid du Colombier if(access(file, 1) != 0) 299dc5a79c1SDavid du Colombier return -1; 300dc5a79c1SDavid du Colombier switch(pid = fork()){ 301dc5a79c1SDavid du Colombier case -1: 302dc5a79c1SDavid du Colombier return -1; 303dc5a79c1SDavid du Colombier case 0: 304dc5a79c1SDavid du Colombier if(sin >= 0) 305dc5a79c1SDavid du Colombier dup(sin, 0); 306dc5a79c1SDavid du Colombier else 307dc5a79c1SDavid du Colombier close(0); 308dc5a79c1SDavid du Colombier if(sout >= 0) 309dc5a79c1SDavid du Colombier dup(sout, 1); 310dc5a79c1SDavid du Colombier else 311dc5a79c1SDavid du Colombier close(1); 312dc5a79c1SDavid du Colombier if(serr >= 0) 313dc5a79c1SDavid du Colombier dup(serr, 2); 314dc5a79c1SDavid du Colombier else 315dc5a79c1SDavid du Colombier close(2); 316dc5a79c1SDavid du Colombier exec(file, argv); 317dc5a79c1SDavid du Colombier exits(file); 318dc5a79c1SDavid du Colombier } 319dc5a79c1SDavid du Colombier return pid; 320dc5a79c1SDavid du Colombier } 321dc5a79c1SDavid du Colombier 322dc5a79c1SDavid du Colombier void 323dc5a79c1SDavid du Colombier Execute(word *args, word *path) 3243e12c5d1SDavid du Colombier { 3253e12c5d1SDavid du Colombier char **argv = mkargv(args); 326219b2ee8SDavid du Colombier char file[1024]; 327219b2ee8SDavid du Colombier int nc; 3283e12c5d1SDavid du Colombier Updenv(); 3293e12c5d1SDavid du Colombier for(;path;path = path->next){ 330219b2ee8SDavid du Colombier nc = strlen(path->word); 331219b2ee8SDavid du Colombier if(nc<1024){ 3323e12c5d1SDavid du Colombier strcpy(file, path->word); 333219b2ee8SDavid du Colombier if(file[0]){ 334219b2ee8SDavid du Colombier strcat(file, "/"); 335219b2ee8SDavid du Colombier nc++; 336219b2ee8SDavid du Colombier } 337219b2ee8SDavid du Colombier if(nc+strlen(argv[1])<1024){ 3383e12c5d1SDavid du Colombier strcat(file, argv[1]); 3393e12c5d1SDavid du Colombier exec(file, argv+1); 3403e12c5d1SDavid du Colombier } 341219b2ee8SDavid du Colombier else werrstr("command name too long"); 342219b2ee8SDavid du Colombier } 343219b2ee8SDavid du Colombier } 3449a747e4fSDavid du Colombier rerrstr(file, sizeof file); 3453e12c5d1SDavid du Colombier pfmt(err, "%s: %s\n", argv[1], file); 3463e12c5d1SDavid du Colombier efree((char *)argv); 3473e12c5d1SDavid du Colombier } 3489a747e4fSDavid du Colombier #define NDIR 256 /* shoud be a better way */ 349dc5a79c1SDavid du Colombier 350dc5a79c1SDavid du Colombier int 351dc5a79c1SDavid du Colombier Globsize(char *p) 3523e12c5d1SDavid du Colombier { 353*73e742d7SDavid du Colombier int isglob = 0, globlen = NDIR+1; 3543e12c5d1SDavid du Colombier for(;*p;p++){ 3553e12c5d1SDavid du Colombier if(*p==GLOB){ 3563e12c5d1SDavid du Colombier p++; 357dc5a79c1SDavid du Colombier if(*p!=GLOB) 358dc5a79c1SDavid du Colombier isglob++; 3599a747e4fSDavid du Colombier globlen+=*p=='*'?NDIR:1; 3603e12c5d1SDavid du Colombier } 3613e12c5d1SDavid du Colombier else 3623e12c5d1SDavid du Colombier globlen++; 3633e12c5d1SDavid du Colombier } 3643e12c5d1SDavid du Colombier return isglob?globlen:0; 3653e12c5d1SDavid du Colombier } 3663e12c5d1SDavid du Colombier #define NFD 50 3673e12c5d1SDavid du Colombier #define NDBUF 32 3683e12c5d1SDavid du Colombier struct{ 3699a747e4fSDavid du Colombier Dir *dbuf; 3709a747e4fSDavid du Colombier int i; 3713e12c5d1SDavid du Colombier int n; 3723e12c5d1SDavid du Colombier }dir[NFD]; 373dc5a79c1SDavid du Colombier 374dc5a79c1SDavid du Colombier int 375dc5a79c1SDavid du Colombier Opendir(char *name) 3763e12c5d1SDavid du Colombier { 3779a747e4fSDavid du Colombier Dir *db; 3783e12c5d1SDavid du Colombier int f; 3793e12c5d1SDavid du Colombier f = open(name, 0); 3803e12c5d1SDavid du Colombier if(f==-1) 3813e12c5d1SDavid du Colombier return f; 3829a747e4fSDavid du Colombier db = dirfstat(f); 3839a747e4fSDavid du Colombier if(db!=nil && (db->mode&DMDIR)){ 3849a747e4fSDavid du Colombier if(f<NFD){ 3859a747e4fSDavid du Colombier dir[f].i = 0; 3869a747e4fSDavid du Colombier dir[f].n = 0; 3873e12c5d1SDavid du Colombier } 3889a747e4fSDavid du Colombier free(db); 3893e12c5d1SDavid du Colombier return f; 3903e12c5d1SDavid du Colombier } 3919a747e4fSDavid du Colombier free(db); 3923e12c5d1SDavid du Colombier close(f); 3933e12c5d1SDavid du Colombier return -1; 3943e12c5d1SDavid du Colombier } 3956b6b9ac8SDavid du Colombier 3966b6b9ac8SDavid du Colombier static int 3976b6b9ac8SDavid du Colombier trimdirs(Dir *d, int nd) 3986b6b9ac8SDavid du Colombier { 3996b6b9ac8SDavid du Colombier int r, w; 4006b6b9ac8SDavid du Colombier 4016b6b9ac8SDavid du Colombier for(r=w=0; r<nd; r++) 4026b6b9ac8SDavid du Colombier if(d[r].mode&DMDIR) 4036b6b9ac8SDavid du Colombier d[w++] = d[r]; 4046b6b9ac8SDavid du Colombier return w; 4056b6b9ac8SDavid du Colombier } 4066b6b9ac8SDavid du Colombier 4076b6b9ac8SDavid du Colombier /* 4086b6b9ac8SDavid du Colombier * onlydirs is advisory -- it means you only 4096b6b9ac8SDavid du Colombier * need to return the directories. it's okay to 4106b6b9ac8SDavid du Colombier * return files too (e.g., on unix where you can't 4116b6b9ac8SDavid du Colombier * tell during the readdir), but that just makes 4126b6b9ac8SDavid du Colombier * the globber work harder. 4136b6b9ac8SDavid du Colombier */ 414dc5a79c1SDavid du Colombier int 415dc5a79c1SDavid du Colombier Readdir(int f, char *p, int onlydirs) 4163e12c5d1SDavid du Colombier { 4173e12c5d1SDavid du Colombier int n; 418dc5a79c1SDavid du Colombier 4199a747e4fSDavid du Colombier if(f<0 || f>=NFD) 4203e12c5d1SDavid du Colombier return 0; 4216b6b9ac8SDavid du Colombier Again: 4229a747e4fSDavid du Colombier if(dir[f].i==dir[f].n){ /* read */ 4239a747e4fSDavid du Colombier free(dir[f].dbuf); 4249a747e4fSDavid du Colombier dir[f].dbuf = 0; 4259a747e4fSDavid du Colombier n = dirread(f, &dir[f].dbuf); 4266b6b9ac8SDavid du Colombier if(n>0){ 4276b6b9ac8SDavid du Colombier if(onlydirs){ 4286b6b9ac8SDavid du Colombier n = trimdirs(dir[f].dbuf, n); 4296b6b9ac8SDavid du Colombier if(n == 0) 4306b6b9ac8SDavid du Colombier goto Again; 4316b6b9ac8SDavid du Colombier } 4329a747e4fSDavid du Colombier dir[f].n = n; 4336b6b9ac8SDavid du Colombier }else 4343e12c5d1SDavid du Colombier dir[f].n = 0; 4359a747e4fSDavid du Colombier dir[f].i = 0; 4363e12c5d1SDavid du Colombier } 4379a747e4fSDavid du Colombier if(dir[f].i == dir[f].n) 4383e12c5d1SDavid du Colombier return 0; 4399a747e4fSDavid du Colombier strcpy(p, dir[f].dbuf[dir[f].i].name); 4409a747e4fSDavid du Colombier dir[f].i++; 4413e12c5d1SDavid du Colombier return 1; 4423e12c5d1SDavid du Colombier } 443dc5a79c1SDavid du Colombier 444dc5a79c1SDavid du Colombier void 445dc5a79c1SDavid du Colombier Closedir(int f) 446dc5a79c1SDavid du Colombier { 4479a747e4fSDavid du Colombier if(f>=0 && f<NFD){ 4489a747e4fSDavid du Colombier free(dir[f].dbuf); 4499a747e4fSDavid du Colombier dir[f].i = 0; 4509a747e4fSDavid du Colombier dir[f].n = 0; 4519a747e4fSDavid du Colombier dir[f].dbuf = 0; 4523e12c5d1SDavid du Colombier } 4533e12c5d1SDavid du Colombier close(f); 4543e12c5d1SDavid du Colombier } 4553e12c5d1SDavid du Colombier int interrupted = 0; 4563e12c5d1SDavid du Colombier void 4577dd7cddfSDavid du Colombier notifyf(void*, char *s) 4583e12c5d1SDavid du Colombier { 4593e12c5d1SDavid du Colombier int i; 4603e12c5d1SDavid du Colombier for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){ 4613e12c5d1SDavid du Colombier if(strncmp(s, "sys: ", 5)!=0) interrupted = 1; 4623e12c5d1SDavid du Colombier goto Out; 4633e12c5d1SDavid du Colombier } 4643e12c5d1SDavid du Colombier pfmt(err, "rc: note: %s\n", s); 4653e12c5d1SDavid du Colombier noted(NDFLT); 4663e12c5d1SDavid du Colombier return; 4673e12c5d1SDavid du Colombier Out: 468219b2ee8SDavid du Colombier if(strcmp(s, "interrupt")!=0 || trap[i]==0){ 4693e12c5d1SDavid du Colombier trap[i]++; 4703e12c5d1SDavid du Colombier ntrap++; 471219b2ee8SDavid du Colombier } 4723e12c5d1SDavid du Colombier if(ntrap>=32){ /* rc is probably in a trap loop */ 4733e12c5d1SDavid du Colombier pfmt(err, "rc: Too many traps (trap %s), aborting\n", s); 4743e12c5d1SDavid du Colombier abort(); 4753e12c5d1SDavid du Colombier } 4763e12c5d1SDavid du Colombier noted(NCONT); 4773e12c5d1SDavid du Colombier } 478dc5a79c1SDavid du Colombier 479dc5a79c1SDavid du Colombier void 480dc5a79c1SDavid du Colombier Trapinit(void) 481dc5a79c1SDavid du Colombier { 4823e12c5d1SDavid du Colombier notify(notifyf); 4833e12c5d1SDavid du Colombier } 484dc5a79c1SDavid du Colombier 485dc5a79c1SDavid du Colombier void 486dc5a79c1SDavid du Colombier Unlink(char *name) 4873e12c5d1SDavid du Colombier { 4883e12c5d1SDavid du Colombier remove(name); 4893e12c5d1SDavid du Colombier } 490dc5a79c1SDavid du Colombier 491dc5a79c1SDavid du Colombier long 492dc5a79c1SDavid du Colombier Write(int fd, char *buf, long cnt) 4933e12c5d1SDavid du Colombier { 4943e12c5d1SDavid du Colombier return write(fd, buf, (long)cnt); 4953e12c5d1SDavid du Colombier } 496dc5a79c1SDavid du Colombier 497dc5a79c1SDavid du Colombier long 498dc5a79c1SDavid du Colombier Read(int fd, char *buf, long cnt) 4993e12c5d1SDavid du Colombier { 5003e12c5d1SDavid du Colombier return read(fd, buf, cnt); 5013e12c5d1SDavid du Colombier } 502dc5a79c1SDavid du Colombier 503dc5a79c1SDavid du Colombier long 504dc5a79c1SDavid du Colombier Seek(int fd, long cnt, long whence) 5053e12c5d1SDavid du Colombier { 5063e12c5d1SDavid du Colombier return seek(fd, cnt, whence); 5073e12c5d1SDavid du Colombier } 508dc5a79c1SDavid du Colombier 509dc5a79c1SDavid du Colombier int 510dc5a79c1SDavid du Colombier Executable(char *file) 5113e12c5d1SDavid du Colombier { 5129a747e4fSDavid du Colombier Dir *statbuf; 5139a747e4fSDavid du Colombier int ret; 5143e12c5d1SDavid du Colombier 5159a747e4fSDavid du Colombier statbuf = dirstat(file); 516dc5a79c1SDavid du Colombier if(statbuf == nil) 517dc5a79c1SDavid du Colombier return 0; 5189a747e4fSDavid du Colombier ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0); 5199a747e4fSDavid du Colombier free(statbuf); 5209a747e4fSDavid du Colombier return ret; 5213e12c5d1SDavid du Colombier } 522dc5a79c1SDavid du Colombier 523dc5a79c1SDavid du Colombier int 524dc5a79c1SDavid du Colombier Creat(char *file) 5253e12c5d1SDavid du Colombier { 5263e12c5d1SDavid du Colombier return create(file, 1, 0666L); 5273e12c5d1SDavid du Colombier } 528dc5a79c1SDavid du Colombier 529dc5a79c1SDavid du Colombier int 530dc5a79c1SDavid du Colombier Dup(int a, int b) 531dc5a79c1SDavid du Colombier { 5323e12c5d1SDavid du Colombier return dup(a, b); 5333e12c5d1SDavid du Colombier } 534dc5a79c1SDavid du Colombier 535dc5a79c1SDavid du Colombier int 536dc5a79c1SDavid du Colombier Dup1(int) 537dc5a79c1SDavid du Colombier { 5383e12c5d1SDavid du Colombier return -1; 5393e12c5d1SDavid du Colombier } 540dc5a79c1SDavid du Colombier 541dc5a79c1SDavid du Colombier void 542dc5a79c1SDavid du Colombier Exit(char *stat) 5433e12c5d1SDavid du Colombier { 5443e12c5d1SDavid du Colombier Updenv(); 5453e12c5d1SDavid du Colombier setstatus(stat); 5463e12c5d1SDavid du Colombier exits(truestatus()?"":getstatus()); 5473e12c5d1SDavid du Colombier } 548dc5a79c1SDavid du Colombier 549dc5a79c1SDavid du Colombier int 550dc5a79c1SDavid du Colombier Eintr(void) 551dc5a79c1SDavid du Colombier { 5523e12c5d1SDavid du Colombier return interrupted; 5533e12c5d1SDavid du Colombier } 554dc5a79c1SDavid du Colombier 555dc5a79c1SDavid du Colombier void 556dc5a79c1SDavid du Colombier Noerror(void) 557dc5a79c1SDavid du Colombier { 5583e12c5d1SDavid du Colombier interrupted = 0; 5593e12c5d1SDavid du Colombier } 560dc5a79c1SDavid du Colombier 561dc5a79c1SDavid du Colombier int 562dc5a79c1SDavid du Colombier Isatty(int fd) 563dc5a79c1SDavid du Colombier { 5644f281771SDavid du Colombier char buf[64]; 5653e12c5d1SDavid du Colombier 5664f281771SDavid du Colombier if(fd2path(fd, buf, sizeof buf) != 0) 567dc5a79c1SDavid du Colombier return 0; 5684f281771SDavid du Colombier 5693806af99SDavid du Colombier /* might be #c/cons during boot - fixed 22 april 2005, remove this later */ 5703806af99SDavid du Colombier if(strcmp(buf, "#c/cons") == 0) 5713806af99SDavid du Colombier return 1; 5723806af99SDavid du Colombier 5734f281771SDavid du Colombier /* might be /mnt/term/dev/cons */ 5744f281771SDavid du Colombier return strlen(buf) >= 9 && strcmp(buf+strlen(buf)-9, "/dev/cons") == 0; 5753e12c5d1SDavid du Colombier } 576dc5a79c1SDavid du Colombier 577dc5a79c1SDavid du Colombier void 578dc5a79c1SDavid du Colombier Abort(void) 579dc5a79c1SDavid du Colombier { 5803e12c5d1SDavid du Colombier pfmt(err, "aborting\n"); 5813e12c5d1SDavid du Colombier flush(err); 5823e12c5d1SDavid du Colombier Exit("aborting"); 5833e12c5d1SDavid du Colombier } 584dc5a79c1SDavid du Colombier 585dc5a79c1SDavid du Colombier void 586dc5a79c1SDavid du Colombier Memcpy(char *a, char *b, long n) 5873e12c5d1SDavid du Colombier { 5883e12c5d1SDavid du Colombier memmove(a, b, (long)n); 5893e12c5d1SDavid du Colombier } 590dc5a79c1SDavid du Colombier 591dc5a79c1SDavid du Colombier void* 592dc5a79c1SDavid du Colombier Malloc(ulong n) 593dc5a79c1SDavid du Colombier { 5943e12c5d1SDavid du Colombier return malloc(n); 5953e12c5d1SDavid du Colombier } 596