Annotation of lucent/sys/src/cmd/rc/plan9.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Plan 9 versions of system-specific functions
                      3:  *     By convention, exported routines herein have names beginning with an
                      4:  *     upper case letter.
                      5:  */
                      6: #include "rc.h"
                      7: #include "exec.h"
                      8: #include "io.h"
                      9: #include "fns.h"
                     10: #include "getflags.h"
                     11: char *Signame[]={
                     12:        "sigexit",      "sighup",       "sigint",       "sigquit",
                     13:        "sigalrm",      "sigkill",      "sigfpe",       "sigterm",
                     14:        0
                     15: };
                     16: char *syssigname[]={
                     17:        "exit",         /* can't happen */
                     18:        "hangup",
                     19:        "interrupt",
                     20:        "quit",         /* can't happen */
                     21:        "alarm",
                     22:        "kill",
                     23:        "sys: fp: ",
                     24:        "term",
                     25:        0
                     26: };
                     27: char Rcmain[]="/rc/lib/rcmain";
                     28: char Fdprefix[]="/fd/";
                     29: void execfinit(void);
                     30: void execbind(void);
                     31: void execmount(void);
                     32: void execnewpgrp(void);
                     33: builtin Builtin[]={
                     34:        "cd",           execcd,
                     35:        "whatis",       execwhatis,
                     36:        "eval",         execeval,
                     37:        "exec",         execexec,       /* but with popword first */
                     38:        "exit",         execexit,
                     39:        "shift",        execshift,
                     40:        "wait",         execwait,
                     41:        ".",            execdot,
                     42:        "finit",        execfinit,
                     43:        "flag",         execflag,
                     44:        "rfork",        execnewpgrp,
                     45:        0
                     46: };
                     47: void execnewpgrp(void){
                     48:        int arg;
                     49:        char *s;
                     50:        switch(count(runq->argv->words)){
                     51:        case 1: arg=RFENVG|RFNAMEG|RFNOTEG; break;
                     52:        case 2:
                     53:                arg=0;
                     54:                for(s=runq->argv->words->next->word;*s;s++) switch(*s){
                     55:                default:
                     56:                        goto Usage;
                     57:                case 'n': arg|=RFNAMEG;  break;
                     58:                case 'N': arg|=RFCNAMEG; break;
                     59:                case 'e': arg|=RFENVG;   break;
                     60:                case 'E': arg|=RFCENVG;  break;
                     61:                case 's': arg|=RFNOTEG;  break;
                     62:                case 'f': arg|=RFFDG;    break;
                     63:                case 'F': arg|=RFCFDG;   break;
                     64:                }
                     65:                break;
                     66:        default:
                     67:        Usage:
                     68:                pfmt(err, "Usage: %s [fnesFNE]\n", runq->argv->words->word);
                     69:                setstatus("rfork usage");
                     70:                poplist();
                     71:                return;
                     72:        }
                     73:        if(rfork(arg)==-1){
                     74:                pfmt(err, "rc: %s failed\n", runq->argv->words->word);
                     75:                setstatus("rfork failed");
                     76:        }
                     77:        else
                     78:                setstatus("");
                     79:        poplist();
                     80: }
                     81: void Vinit(void){
                     82:        int dir=open("#e", 0), f, len;
                     83:        word *val;
                     84:        char *buf, *s;
                     85:        Dir ent;
                     86:        char envname[NAMELEN+6];
                     87:        if(dir<0){
                     88:                pfmt(err, "rc: can't open #e\n");
                     89:                return;
                     90:        }
                     91:        while(dirread(dir, &ent, sizeof ent)==sizeof ent){
                     92:                len=ent.length;
                     93:                if(len && strncmp(ent.name, "fn#", 3)!=0){
                     94:                        strcpy(envname, "#e/");
                     95:                        strcat(envname, ent.name);
                     96:                        if((f=open(envname, 0))>=0){
                     97:                                buf=emalloc((int)len+1);
                     98:                                read(f, buf, (long)len);
                     99:                                val=0;
                    100:                                /* Charitably add a 0 at the end if need be */
                    101:                                if(buf[len-1]) buf[len++]='\0';
                    102:                                s=buf+len-1;
                    103:                                for(;;){
                    104:                                        while(s!=buf && s[-1]!='\0') --s;
                    105:                                        val=newword(s, val);
                    106:                                        if(s==buf) break;
                    107:                                        --s;
                    108:                                }
                    109:                                setvar(ent.name, val);
                    110:                                vlook(ent.name)->changed=0;
                    111:                                close(f);
                    112:                                efree(buf);
                    113:                        }
                    114:                }
                    115:        }
                    116:        close(dir);
                    117: }
                    118: #ifdef old_execfinit
                    119: void Xrdfn(void){}
                    120: void execfinit(void){
                    121:        Xpopm();
                    122: }
                    123: #else
                    124: int envdir;
                    125: void Xrdfn(void){
                    126:        int f, len;
                    127:        Dir ent;
                    128:        char envname[NAMELEN+6];
                    129:        while(dirread(envdir, &ent, sizeof ent)==sizeof ent){
                    130:                len=ent.length;
                    131:                if(len && strncmp(ent.name, "fn#", 3)==0){
                    132:                        strcpy(envname, "#e/");
                    133:                        strcat(envname, ent.name);
                    134:                        if((f=open(envname, 0))>=0){
                    135:                                execcmds(openfd(f));
                    136:                                return;
                    137:                        }
                    138:                }
                    139:        }
                    140:        close(envdir);
                    141:        Xreturn();
                    142: }
                    143: union code rdfns[4];
                    144: void execfinit(void){
                    145:        static int first=1;
                    146:        if(first){
                    147:                rdfns[0].i=1;
                    148:                rdfns[1].f=Xrdfn;
                    149:                rdfns[2].f=Xjump;
                    150:                rdfns[3].i=1;
                    151:                first=0;
                    152:        }
                    153:        Xpopm();
                    154:        envdir=open("#e", 0);
                    155:        if(envdir<0){
                    156:                pfmt(err, "rc: can't open #e\n");
                    157:                return;
                    158:        }
                    159:        start(rdfns, 1, runq->local);
                    160: }
                    161: #endif
                    162: int Waitfor(int pid, int persist){
                    163:        thread *p;
                    164:        Waitmsg w;
                    165:        int cpid;
                    166:        char errbuf[ERRLEN];
                    167:        while((cpid=wait(&w))>=0){
                    168:                if(pid==cpid){
                    169:                        setstatus(w.msg);
                    170:                        return 0;
                    171:                }
                    172:                for(p=runq->ret;p;p=p->ret)
                    173:                        if(p->pid==cpid){
                    174:                                p->pid=-1;
                    175:                                strcpy(p->status, w.msg);
                    176:                        }
                    177:        }
                    178:        errstr(errbuf);
                    179:        if(strcmp(errbuf, "interrupted")==0) return -1;
                    180:        return 0;
                    181: }
                    182: char **mkargv(word *a)
                    183: {
                    184:        char **argv=(char **)emalloc((count(a)+2)*sizeof(char *));
                    185:        char **argp=argv+1;     /* leave one at front for runcoms */
                    186:        for(;a;a=a->next) *argp++=a->word;
                    187:        *argp=0;
                    188:        return argv;
                    189: }
                    190: void addenv(var *v)
                    191: {
                    192:        char envname[NAMELEN+9];
                    193:        word *w;
                    194:        int f;
                    195:        io *fd;
                    196:        if(v->changed){
                    197:                v->changed=0;
                    198:                strcpy(envname, "#e/");
                    199:                strcat(envname, v->name);
                    200:                if((f=Creat(envname))<0)
                    201:                        pfmt(err, "rc: can't open %s\n", envname);
                    202:                else{
                    203:                        for(w=v->val;w;w=w->next)
                    204:                                write(f, w->word, strlen(w->word)+1L);
                    205:                        close(f);
                    206:                }
                    207:        }
                    208:        if(v->fnchanged){
                    209:                v->fnchanged=0;
                    210:                strcpy(envname, "#e/fn#");
                    211:                strcat(envname, v->name);
                    212:                if((f=Creat(envname))<0)
                    213:                        pfmt(err, "rc: can't open %s\n", envname);
                    214:                else{
                    215:                        if(v->fn){
                    216:                                fd=openfd(f);
                    217:                                pfmt(fd, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
                    218:                                closeio(fd);
                    219:                        }
                    220:                        close(f);
                    221:                }
                    222:        }
                    223: }
                    224: void updenvlocal(var *v)
                    225: {
                    226:        if(v){
                    227:                updenvlocal(v->next);
                    228:                addenv(v);
                    229:        }
                    230: }
                    231: void Updenv(void){
                    232:        var *v, **h;
                    233:        for(h=gvar;h!=&gvar[NVAR];h++)
                    234:                for(v=*h;v;v=v->next)
                    235:                        addenv(v);
                    236:        if(runq) updenvlocal(runq->local);
                    237: }
                    238: void Execute(word *args, word *path)
                    239: {
                    240:        char **argv=mkargv(args);
                    241:        char file[1024];
                    242:        int nc;
                    243:        Updenv();
                    244:        for(;path;path=path->next){
                    245:                nc=strlen(path->word);
                    246:                if(nc<1024){
                    247:                        strcpy(file, path->word);
                    248:                        if(file[0]){
                    249:                                strcat(file, "/");
                    250:                                nc++;
                    251:                        }
                    252:                        if(nc+strlen(argv[1])<1024){
                    253:                                strcat(file, argv[1]);
                    254:                                exec(file, argv+1);
                    255:                        }
                    256:                        else werrstr("command name too long");
                    257:                }
                    258:        }
                    259:        errstr(file);
                    260:        pfmt(err, "%s: %s\n", argv[1], file);
                    261:        efree((char *)argv);
                    262: }
                    263: int Globsize(char *p)
                    264: {
                    265:        ulong isglob=0, globlen=NAMELEN+1;
                    266:        for(;*p;p++){
                    267:                if(*p==GLOB){
                    268:                        p++;
                    269:                        if(*p!=GLOB) isglob++;
                    270:                        globlen+=*p=='*'?NAMELEN:1;
                    271:                }
                    272:                else
                    273:                        globlen++;
                    274:        }
                    275:        return isglob?globlen:0;
                    276: }
                    277: #define NFD    50
                    278: #define        NDBUF   32
                    279: struct{
                    280:        char    *buf;
                    281:        int     n;
                    282: }dir[NFD];
                    283: int Opendir(char *name)
                    284: {
                    285:        Dir db;
                    286:        int f;
                    287:        f=open(name, 0);
                    288:        if(f==-1)
                    289:                return f;
                    290:        if(dirfstat(f, &db)!=-1 && (db.mode&0x80000000)){
                    291:                if(f<NFD && dir[f].buf){
                    292:                        free(dir[f].buf);
                    293:                        dir[f].buf=0;
                    294:                }
                    295:                return f;
                    296:        }
                    297:        close(f);
                    298:        return -1;
                    299: }
                    300: int Readdir(int f, char *p)
                    301: {
                    302:        char dirent[DIRLEN];
                    303:        int n;
                    304:        if(f<0 || f>=NFD){
                    305:    slow:
                    306:                while(read(f, dirent, sizeof dirent)==sizeof dirent){
                    307:                        strcpy(p, dirent);
                    308:                        return 1;
                    309:                }
                    310:                return 0;
                    311:        }
                    312:        if(dir[f].buf==0){      /* allocate */
                    313:                dir[f].buf=malloc(NDBUF*DIRLEN);
                    314:                if(dir[f].buf==0)
                    315:                        goto slow;
                    316:                dir[f].n=0;
                    317:        }
                    318:        if(dir[f].n==0){        /* read */
                    319:                memset(dir[f].buf, 0, NDBUF*DIRLEN);
                    320:                n = read(f, dir[f].buf, NDBUF*DIRLEN);
                    321:                if(n>0 && n<NDBUF*DIRLEN){
                    322:                        memmove(dir[f].buf+NDBUF*DIRLEN-n, dir[f].buf, n);
                    323:                        dir[f].n=NDBUF-n/DIRLEN;
                    324:                }else
                    325:                        dir[f].n=0;
                    326:        }
                    327:        if(dir[f].buf[dir[f].n*DIRLEN]==0)
                    328:                return 0;
                    329:        strcpy(p, &dir[f].buf[dir[f].n*DIRLEN]);
                    330:        dir[f].n++;
                    331:        if(dir[f].n==NDBUF)
                    332:                dir[f].n=0;
                    333:        return 1;
                    334: }
                    335: void Closedir(int f){
                    336:        if(f>=0 && f<NFD && dir[f].buf){
                    337:                free(dir[f].buf);
                    338:                dir[f].buf=0;
                    339:        }
                    340:        close(f);
                    341: }
                    342: int interrupted = 0;
                    343: void
                    344: notifyf(void *a, char *s)
                    345: {
                    346:        int i;
                    347:        for(i=0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
                    348:                if(strncmp(s, "sys: ", 5)!=0) interrupted=1;
                    349:                goto Out;
                    350:        }
                    351:        pfmt(err, "rc: note: %s\n", s);
                    352:        noted(NDFLT);
                    353:        return;
                    354: Out:
                    355:        if(strcmp(s, "interrupt")!=0 || trap[i]==0){
                    356:                trap[i]++;
                    357:                ntrap++;
                    358:        }
                    359:        if(ntrap>=32){  /* rc is probably in a trap loop */
                    360:                pfmt(err, "rc: Too many traps (trap %s), aborting\n", s);
                    361:                abort();
                    362:        }
                    363:        noted(NCONT);
                    364: }
                    365: void Trapinit(void){
                    366:        notify(notifyf);
                    367: }
                    368: void Unlink(char *name)
                    369: {
                    370:        remove(name);
                    371: }
                    372: long Write(int fd, char *buf, long cnt)
                    373: {
                    374:        return write(fd, buf, (long)cnt);
                    375: }
                    376: long Read(int fd, char *buf, long cnt)
                    377: {
                    378:        int n;
                    379: 
                    380:        return read(fd, buf, cnt);
                    381: }
                    382: long Seek(int fd, long cnt, int whence)
                    383: {
                    384:        return seek(fd, cnt, whence);
                    385: }
                    386: int Executable(char *file)
                    387: {
                    388:        Dir statbuf;
                    389: 
                    390:        return dirstat(file, &statbuf)!=-1 && (statbuf.mode&0111)!=0 && (statbuf.mode&CHDIR)==0;
                    391: }
                    392: int Creat(char *file)
                    393: {
                    394:        return create(file, 1, 0666L);
                    395: }
                    396: int Dup(int a, int b){
                    397:        return dup(a, b);
                    398: }
                    399: int Dup1(int a){
                    400:        return -1;
                    401: }
                    402: void Exit(char *stat)
                    403: {
                    404:        Updenv();
                    405:        setstatus(stat);
                    406:        exits(truestatus()?"":getstatus());
                    407: }
                    408: int Eintr(void){
                    409:        return interrupted;
                    410: }
                    411: void Noerror(void){
                    412:        interrupted=0;
                    413: }
                    414: int Isatty(int fd){
                    415:        Dir d1, d2;
                    416: 
                    417:        if(dirfstat(0, &d1)==-1) return 0;
                    418:        if(strncmp(d1.name, "ptty", 4)==0) return 1;    /* fwd complaints to philw */
                    419:        if(dirstat("/dev/cons", &d2)==-1) return 0;
                    420:        return d1.type==d2.type&&d1.dev==d2.dev&&d1.qid.path==d2.qid.path;
                    421: }
                    422: void Abort(void){
                    423:        pfmt(err, "aborting\n");
                    424:        flush(err);
                    425:        Exit("aborting");
                    426: }
                    427: void Memcpy(char *a, char *b, long n)
                    428: {
                    429:        memmove(a, b, (long)n);
                    430: }
                    431: void *Malloc(ulong n){
                    432:        return malloc(n);
                    433: }
                    434: char *Geterrstr(void){
                    435:        static char error[ERRLEN];
                    436:        error[0]='\0';
                    437:        errstr(error);
                    438:        return error;
                    439: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.