Annotation of lucent/sys/src/cmd/rc/simple.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Maybe `simple' is a misnomer.
        !             3:  */
        !             4: #include "rc.h"
        !             5: #include "getflags.h"
        !             6: #include "exec.h"
        !             7: #include "io.h"
        !             8: #include "fns.h"
        !             9: /*
        !            10:  * Search through the following code to see if we're just going to exit.
        !            11:  */
        !            12: exitnext(void){
        !            13:        union code *c=&runq->code[runq->pc];
        !            14:        while(c->f==Xpopredir) c++;
        !            15:        return c->f==Xexit;
        !            16: }
        !            17: void Xsimple(void){
        !            18:        word *a;
        !            19:        thread *p=runq;
        !            20:        var *v;
        !            21:        struct builtin *bp;
        !            22:        int pid;
        !            23:        globlist();
        !            24:        a=runq->argv->words;
        !            25:        if(a==0){
        !            26:                Xerror("empty argument list");
        !            27:                return;
        !            28:        }
        !            29:        if(flag['x'])
        !            30:                pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */
        !            31:        v=gvlook(a->word);
        !            32:        if(v->fn)
        !            33:                execfunc(v);
        !            34:        else{
        !            35:                if(strcmp(a->word, "builtin")==0){
        !            36:                        if(count(a)==1){
        !            37:                                pfmt(err, "builtin: empty argument list\n");
        !            38:                                setstatus("empty arg list");
        !            39:                                poplist();
        !            40:                                return;
        !            41:                        }
        !            42:                        a=a->next;
        !            43:                        popword();
        !            44:                }
        !            45:                for(bp=Builtin;bp->name;bp++)
        !            46:                        if(strcmp(a->word, bp->name)==0){
        !            47:                                (*bp->fnc)();
        !            48:                                return;
        !            49:                        }
        !            50:                if(exitnext()){
        !            51:                        /* fork and wait is redundant */
        !            52:                        pushword("exec");
        !            53:                        execexec();
        !            54:                        Xexit();
        !            55:                }
        !            56:                else{
        !            57:                        flush(err);
        !            58:                        Updenv();
        !            59:                        switch(pid=fork()){
        !            60:                        case -1:
        !            61:                                Xperror("try again");
        !            62:                                return;
        !            63:                        case 0:
        !            64:                                pushword("exec");
        !            65:                                execexec();
        !            66:                                Exit("can't exec");
        !            67:                        default:
        !            68:                                poplist();
        !            69:                                /* interrupts don't get us out */
        !            70:                                while(Waitfor(pid, 1) < 0)
        !            71:                                        ;
        !            72:                        }
        !            73:                }
        !            74:        }
        !            75: }
        !            76: struct word nullpath={ "", 0};
        !            77: void doredir(redir *rp)
        !            78: {
        !            79:        if(rp){
        !            80:                doredir(rp->next);
        !            81:                switch(rp->type){
        !            82:                case ROPEN:
        !            83:                        if(rp->from!=rp->to){
        !            84:                                Dup(rp->from, rp->to);
        !            85:                                close(rp->from);
        !            86:                        }
        !            87:                        break;
        !            88:                case RDUP: Dup(rp->from, rp->to); break;
        !            89:                case RCLOSE: close(rp->from); break;
        !            90:                }
        !            91:        }
        !            92: }
        !            93: word *searchpath(char *w){
        !            94:        word *path;
        !            95:        if(strncmp(w, "/", 1)==0
        !            96:        || strncmp(w, "#", 1)==0
        !            97:        || strncmp(w, "./", 2)==0
        !            98:        || strncmp(w, "../", 3)==0
        !            99:        || (path=vlook("path")->val)==0)
        !           100:                path=&nullpath;
        !           101:        return path;
        !           102: }
        !           103: void execexec(void){
        !           104:        word *path;
        !           105:        popword();      /* "exec" */
        !           106:        if(runq->argv->words==0){
        !           107:                Xerror("empty argument list");
        !           108:                return;
        !           109:        }
        !           110:        doredir(runq->redir);
        !           111:        Execute(runq->argv->words, searchpath(runq->argv->words->word));
        !           112:        poplist();
        !           113: }
        !           114: void execfunc(var *func)
        !           115: {
        !           116:        word *starval;
        !           117:        popword();
        !           118:        starval=runq->argv->words;
        !           119:        runq->argv->words=0;
        !           120:        poplist();
        !           121:        start(func->fn, func->pc, (struct var *)0);
        !           122:        runq->local=newvar(strdup("*"), runq->local);
        !           123:        runq->local->val=starval;
        !           124:        runq->local->changed=1;
        !           125: }
        !           126: void execcd(void){
        !           127:        word *a=runq->argv->words;
        !           128:        word *cdpath;
        !           129:        char dir[512];
        !           130:        setstatus("can't cd");
        !           131:        cdpath=vlook("cdpath")->val;
        !           132:        switch(count(a)){
        !           133:        default:
        !           134:                pfmt(err, "Usage: cd [directory]\n");
        !           135:                break;
        !           136:        case 2:
        !           137:                if(a->next->word[0]=='/' || cdpath==0) cdpath=&nullpath;
        !           138:                for(;cdpath;cdpath=cdpath->next){
        !           139:                        strcpy(dir, cdpath->word);
        !           140:                        if(dir[0]) strcat(dir, "/");
        !           141:                        strcat(dir, a->next->word);
        !           142:                        if(chdir(dir)>=0){
        !           143:                                if(strlen(cdpath->word)
        !           144:                                && strcmp(cdpath->word, ".")!=0)
        !           145:                                        pfmt(err, "%s\n", dir);
        !           146:                                setstatus("");
        !           147:                                break;
        !           148:                        }
        !           149:                }
        !           150:                if(cdpath==0) pfmt(err, "Can't cd %s\n", a->next->word);
        !           151:                break;
        !           152:        case 1:
        !           153:                a=vlook("home")->val;
        !           154:                if(count(a)>=1){
        !           155:                        if(chdir(a->word)>=0)
        !           156:                                setstatus("");
        !           157:                        else
        !           158:                                pfmt(err, "Can't cd %s\n", a->word);
        !           159:                }
        !           160:                else
        !           161:                        pfmt(err, "Can't cd -- $home empty\n");
        !           162:                break;
        !           163:        }
        !           164:        poplist();
        !           165: }
        !           166: void execexit(void){
        !           167:        switch(count(runq->argv->words)){
        !           168:        default: pfmt(err, "Usage: exit [status]\nExiting anyway\n");
        !           169:        case 2: setstatus(runq->argv->words->next->word);
        !           170:        case 1: Xexit();
        !           171:        }
        !           172: }
        !           173: void execshift(void){
        !           174:        int n;
        !           175:        word *a;
        !           176:        var *star;
        !           177:        switch(count(runq->argv->words)){
        !           178:        default:
        !           179:                pfmt(err, "Usage: shift [n]\n");
        !           180:                setstatus("shift usage");
        !           181:                poplist();
        !           182:                return;
        !           183:        case 2: n=atoi(runq->argv->words->next->word); break;
        !           184:        case 1: n=1; break;
        !           185:        }
        !           186:        star=vlook("*");
        !           187:        for(;n && star->val;--n){
        !           188:                a=star->val->next;
        !           189:                efree(star->val->word);
        !           190:                efree((char *)star->val);
        !           191:                star->val=a;
        !           192:                star->changed=1;
        !           193:        }
        !           194:        setstatus("");
        !           195:        poplist();
        !           196: }
        !           197: int octal(char *s)
        !           198: {
        !           199:        int n=0;
        !           200:        while(*s==' ' || *s=='\t' || *s=='\n') s++;
        !           201:        while('0'<=*s && *s<='7') n=n*8+*s++-'0';
        !           202:        return n;
        !           203: }
        !           204: int mapfd(int fd)
        !           205: {
        !           206:        redir *rp;
        !           207:        for(rp=runq->redir;rp;rp=rp->next){
        !           208:                switch(rp->type){
        !           209:                case RCLOSE:
        !           210:                        if(rp->from==fd) fd=-1;
        !           211:                        break;
        !           212:                case RDUP:
        !           213:                case ROPEN:
        !           214:                        if(rp->to==fd) fd=rp->from;
        !           215:                        break;
        !           216:                }
        !           217:        }
        !           218:        return fd;
        !           219: }
        !           220: union code rdcmds[4];
        !           221: void execcmds(io *f)
        !           222: {
        !           223:        static int first=1;
        !           224:        if(first){
        !           225:                rdcmds[0].i=1;
        !           226:                rdcmds[1].f=Xrdcmds;
        !           227:                rdcmds[2].f=Xreturn;
        !           228:                first=0;
        !           229:        }
        !           230:        start(rdcmds, 1, runq->local);
        !           231:        runq->cmdfd=f;
        !           232:        runq->iflast=0;
        !           233: }
        !           234: void execeval(void){
        !           235:        char *cmdline, *s, *t;
        !           236:        int len=0;
        !           237:        word *ap;
        !           238:        if(count(runq->argv->words)<=1){
        !           239:                Xerror("Usage: eval cmd ...");
        !           240:                return;
        !           241:        }
        !           242:        eflagok=1;
        !           243:        for(ap=runq->argv->words->next;ap;ap=ap->next)
        !           244:                len+=1+strlen(ap->word);
        !           245:        cmdline=emalloc(len);
        !           246:        s=cmdline;
        !           247:        for(ap=runq->argv->words->next;ap;ap=ap->next){
        !           248:                for(t=ap->word;*t;) *s++=*t++;
        !           249:                *s++=' ';
        !           250:        }
        !           251:        s[-1]='\n';
        !           252:        poplist();
        !           253:        execcmds(opencore(cmdline, len));
        !           254:        efree(cmdline);
        !           255: }
        !           256: union code dotcmds[14];
        !           257: void execdot(void){
        !           258:        int iflag=0;
        !           259:        int fd;
        !           260:        list *av;
        !           261:        thread *p=runq;
        !           262:        char *zero;
        !           263:        static int first=1;
        !           264:        char file[512];
        !           265:        word *path;
        !           266:        if(first){
        !           267:                dotcmds[0].i=1;
        !           268:                dotcmds[1].f=Xmark;
        !           269:                dotcmds[2].f=Xword;
        !           270:                dotcmds[3].s="0";
        !           271:                dotcmds[4].f=Xlocal;
        !           272:                dotcmds[5].f=Xmark;
        !           273:                dotcmds[6].f=Xword;
        !           274:                dotcmds[7].s="*";
        !           275:                dotcmds[8].f=Xlocal;
        !           276:                dotcmds[9].f=Xrdcmds;
        !           277:                dotcmds[10].f=Xunlocal;
        !           278:                dotcmds[11].f=Xunlocal;
        !           279:                dotcmds[12].f=Xreturn;
        !           280:                first=0;
        !           281:        }
        !           282:        else
        !           283:                eflagok=1;
        !           284:        popword();
        !           285:        if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){
        !           286:                iflag=1;
        !           287:                popword();
        !           288:        }
        !           289:        /* get input file */
        !           290:        if(p->argv->words==0){
        !           291:                Xerror("Usage: . [-i] file [arg ...]");
        !           292:                return;
        !           293:        }
        !           294:        zero=strdup(p->argv->words->word);
        !           295:        popword();
        !           296:        strcpy(file, "**No file name**");
        !           297:        for(path=searchpath(zero);path;path=path->next){
        !           298:                strcpy(file, path->word);
        !           299:                if(file[0]) strcat(file, "/");
        !           300:                strcat(file, zero);
        !           301:                if((fd=open(file, 0))>=0) break;
        !           302:                if(strcmp(file, "/dev/stdin")==0){      /* for sun & ucb */
        !           303:                        fd=Dup1(0);
        !           304:                        if(fd>=0) break;
        !           305:                }
        !           306:        }
        !           307:        if(fd<0){
        !           308:                Xperror(file);
        !           309:                return;
        !           310:        }
        !           311:        /* set up for a new command loop */
        !           312:        start(dotcmds, 1, (struct var *)0);
        !           313:        pushredir(RCLOSE, fd, 0);
        !           314:        runq->cmdfile=zero;
        !           315:        runq->cmdfd=openfd(fd);
        !           316:        runq->iflag=iflag;
        !           317:        runq->iflast=0;
        !           318:        /* push $* value */
        !           319:        pushlist();
        !           320:        runq->argv->words=p->argv->words;
        !           321:        /* free caller's copy of $* */
        !           322:        av=p->argv;
        !           323:        p->argv=av->next;
        !           324:        efree((char *)av);
        !           325:        /* push $0 value */
        !           326:        pushlist();
        !           327:        pushword(zero);
        !           328:        ndot++;
        !           329: }
        !           330: void execflag(void){
        !           331:        char *letter, *val;
        !           332:        switch(count(runq->argv->words)){
        !           333:        case 2:
        !           334:                setstatus(flag[runq->argv->words->next->word[0]]?"":"flag not set");
        !           335:                break;
        !           336:        case 3:
        !           337:                letter=runq->argv->words->next->word;
        !           338:                val=runq->argv->words->next->next->word;
        !           339:                if(strlen(letter)==1){
        !           340:                        if(strcmp(val, "+")==0){
        !           341:                                flag[letter[0]]=flagset;
        !           342:                                break;
        !           343:                        }
        !           344:                        if(strcmp(val, "-")==0){
        !           345:                                flag[letter[0]]=0;
        !           346:                                break;
        !           347:                        }
        !           348:                }
        !           349:        default:
        !           350:                Xerror("Usage: flag [letter] [+-]");
        !           351:                return;
        !           352:        }
        !           353:        poplist();
        !           354: }
        !           355: void execwhatis(void){ /* mildly wrong -- should fork before writing */
        !           356:        word *a, *b, *path;
        !           357:        var *v;
        !           358:        struct builtin *bp;
        !           359:        char file[512];
        !           360:        struct io out[1];
        !           361:        int found, sep;
        !           362:        a=runq->argv->words->next;
        !           363:        if(a==0){
        !           364:                Xerror("Usage: whatis name ...");
        !           365:                return;
        !           366:        }
        !           367:        setstatus("");
        !           368:        out->fd=mapfd(1);
        !           369:        out->bufp=out->buf;
        !           370:        out->ebuf=&out->buf[NBUF];
        !           371:        out->strp=0;
        !           372:        for(;a;a=a->next){
        !           373:                v=vlook(a->word);
        !           374:                if(v->val){
        !           375:                        pfmt(out, "%s=", a->word);
        !           376:                        if(v->val->next==0)
        !           377:                                pfmt(out, "%q\n", v->val->word);
        !           378:                        else{
        !           379:                                sep='(';
        !           380:                                for(b=v->val;b && b->word;b=b->next){
        !           381:                                        pfmt(out, "%c%q", sep, b->word);
        !           382:                                        sep=' ';
        !           383:                                }
        !           384:                                pfmt(out, ")\n");
        !           385:                        }
        !           386:                        found=1;
        !           387:                }
        !           388:                else
        !           389:                        found=0;
        !           390:                v=gvlook(a->word);
        !           391:                if(v->fn) pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
        !           392:                else{
        !           393:                        for(bp=Builtin;bp->name;bp++)
        !           394:                                if(strcmp(a->word, bp->name)==0){
        !           395:                                        pfmt(out, "builtin %s\n", a->word);
        !           396:                                        break;
        !           397:                                }
        !           398:                        if(!bp->name){
        !           399:                                for(path=searchpath(a->word);path;path=path->next){
        !           400:                                        strcpy(file, path->word);
        !           401:                                        if(file[0]) strcat(file, "/");
        !           402:                                        strcat(file, a->word);
        !           403:                                        if(Executable(file)){
        !           404:                                                pfmt(out, "%s\n", file);
        !           405:                                                break;
        !           406:                                        }
        !           407:                                }
        !           408:                                if(!path && !found){
        !           409:                                        pfmt(err, "%s: not found\n", a->word);
        !           410:                                        setstatus("not found");
        !           411:                                }
        !           412:                        }
        !           413:                }
        !           414:        }
        !           415:        poplist();
        !           416:        flush(err);
        !           417: }
        !           418: void execwait(void){
        !           419:        switch(count(runq->argv->words)){
        !           420:        default: Xerror("Usage: wait [pid]"); return;
        !           421:        case 2: Waitfor(atoi(runq->argv->words->next->word), 0); break;
        !           422:        case 1: Waitfor(-1, 0); break;
        !           423:        }
        !           424:        poplist();
        !           425: }

unix.superglobalmegacorp.com

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