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