Annotation of lucent/sys/src/cmd/rc/plan9.c, revision 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.