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

1.1     ! root        1: /*
        !             2:  * Unix 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 <errno.h>
        !             9: char Rcmain[]="/usr/lib/rcmain";
        !            10: char Fdprefix[]="/dev/fd/";
        !            11: int execumask(), execfinit();
        !            12: struct builtin Builtin[]={
        !            13:        "cd",           execcd,
        !            14:        "whatis",       execwhatis,
        !            15:        "eval",         execeval,
        !            16:        "exec",         execexec,       /* but with popword first */
        !            17:        "exit",         execexit,
        !            18:        "shift",        execshift,
        !            19:        "wait",         execwait,
        !            20:        "umask",        execumask,
        !            21:        ".",            execdot,
        !            22:        "finit",        execfinit,
        !            23:        "flag",         execflag,
        !            24:        0
        !            25: };
        !            26: #define        SEP     '\1'
        !            27: char **environp;
        !            28: struct word *enval(s)
        !            29: register char *s;
        !            30: {
        !            31:        register char *t, c;
        !            32:        register struct word *v;
        !            33:        for(t=s;*t && *t!=SEP;t++);
        !            34:        c=*t;
        !            35:        *t='\0';
        !            36:        v=newword(s, c=='\0'?(struct word *)0:enval(t+1));
        !            37:        *t=c;
        !            38:        return v;
        !            39: }
        !            40: Vinit(){
        !            41:        extern char **environ;
        !            42:        register char *s;
        !            43:        register char **env=environ;
        !            44:        environp=env;
        !            45:        for(;*env;env++){
        !            46:                for(s=*env;*s && *s!='(' && *s!='=';s++);
        !            47:                switch(*s){
        !            48:                case '\0':
        !            49:                        pfmt(err, "environment %q?\n", *env);
        !            50:                        break;
        !            51:                case '=':
        !            52:                        *s='\0';
        !            53:                        setvar(*env, enval(s+1));
        !            54:                        *s='=';
        !            55:                        break;
        !            56:                case '(':       /* ignore functions for now */
        !            57:                        break;
        !            58:                }
        !            59:        }
        !            60: }
        !            61: char **envp;
        !            62: Xrdfn(){
        !            63:        register char *s;
        !            64:        register int len;
        !            65:        for(;*envp;envp++){
        !            66:                for(s=*envp;*s && *s!='(' && *s!='=';s++);
        !            67:                switch(*s){
        !            68:                case '\0':
        !            69:                        pfmt(err, "environment %q?\n", *envp);
        !            70:                        break;
        !            71:                case '=':       /* ignore variables */
        !            72:                        break;
        !            73:                case '(':               /* Bourne again */
        !            74:                        s=*envp+3;
        !            75:                        envp++;
        !            76:                        len=strlen(s);
        !            77:                        s[len]='\n';
        !            78:                        execcmds(opencore(s, len+1));
        !            79:                        s[len]='\0';
        !            80:                        return;
        !            81:                }
        !            82:        }
        !            83:        Xreturn();
        !            84: }
        !            85: union code rdfns[4];
        !            86: execfinit(){
        !            87:        static int first=1;
        !            88:        if(first){
        !            89:                rdfns[0].i=1;
        !            90:                rdfns[1].f=Xrdfn;
        !            91:                rdfns[2].f=Xjump;
        !            92:                rdfns[3].i=1;
        !            93:                first=0;
        !            94:        }
        !            95:        Xpopm();
        !            96:        envp=environp;
        !            97:        start(rdfns, 1, runq->local);
        !            98: }
        !            99: cmpenv(a, b)
        !           100: char **a, **b;
        !           101: {
        !           102:        return strcmp(*a, *b);
        !           103: }
        !           104: char **mkenv(){
        !           105:        register char **env, **ep, *p, *q;
        !           106:        register struct var **h, *v;
        !           107:        register struct word *a;
        !           108:        register int nvar=0, nchr=0, sep;
        !           109:        /*
        !           110:         * Slightly kludgy loops look at locals then globals
        !           111:         */
        !           112:        for(h=var-1;h!=&var[NVAR];h++) for(v=h>=var?*h:runq->local;v;v=v->next){
        !           113:                if((v==vlook(v->name)) && v->val){
        !           114:                        nvar++;
        !           115:                        nchr+=strlen(v->name)+1;
        !           116:                        for(a=v->val;a;a=a->next)
        !           117:                                nchr+=strlen(a->word)+1;
        !           118:                }
        !           119:                if(v->fn){
        !           120:                        nvar++;
        !           121:                        nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8;
        !           122:                }
        !           123:        }
        !           124:        env=(char **)emalloc((nvar+1)*sizeof(char *)+nchr);
        !           125:        ep=env;
        !           126:        p=(char *)&env[nvar+1];
        !           127:        for(h=var-1;h!=&var[NVAR];h++) for(v=h>=var?*h:runq->local;v;v=v->next){
        !           128:                if((v==vlook(v->name)) && v->val){
        !           129:                        *ep++=p;
        !           130:                        q=v->name;
        !           131:                        while(*q) *p++=*q++;
        !           132:                        sep='=';
        !           133:                        for(a=v->val;a;a=a->next){
        !           134:                                *p++=sep;
        !           135:                                sep=SEP;
        !           136:                                q=a->word;
        !           137:                                while(*q) *p++=*q++;
        !           138:                        }
        !           139:                        *p++='\0';
        !           140:                }
        !           141:                if(v->fn){
        !           142:                        *ep++=p;
        !           143:                        *p++='#'; *p++='('; *p++=')';   /* to fool Bourne */
        !           144:                        *p++='f'; *p++='n'; *p++=' ';
        !           145:                        q=v->name;
        !           146:                        while(*q) *p++=*q++;
        !           147:                        *p++=' ';
        !           148:                        q=v->fn[v->pc-1].s;
        !           149:                        while(*q) *p++=*q++;
        !           150:                        *p++='\0';
        !           151:                }
        !           152:        }
        !           153:        *ep=0;
        !           154:        qsort((char *)env, nvar, sizeof ep[0], cmpenv);
        !           155:        return env;     
        !           156: }
        !           157: char *sigmsg[]={
        !           158: /*  0 normal  */ 0,
        !           159: /*  1 SIGHUP  */ "Hangup",
        !           160: /*  2 SIGINT  */ 0,
        !           161: /*  3 SIGQUIT */ "Quit",
        !           162: /*  4 SIGILL  */ "Illegal instruction",
        !           163: /*  5 SIGTRAP */ "Trace/BPT trap",
        !           164: /*  6 SIGIOT  */ "abort",
        !           165: /*  7 SIGEMT  */ "EMT trap",
        !           166: /*  8 SIGFPE  */ "Floating exception",
        !           167: /*  9 SIGKILL */ "Killed",
        !           168: /* 10 SIGBUS  */ "Bus error",
        !           169: /* 11 SIGSEGV */ "Memory fault",
        !           170: /* 12 SIGSYS  */ "Bad system call",
        !           171: /* 13 SIGPIPE */ 0,
        !           172: /* 14 SIGALRM */ "Alarm call",
        !           173: /* 15 SIGTERM */ "Terminated",
        !           174: /* 16 unused  */ "signal 16",
        !           175: /* 17 SIGSTOP */ "Process stopped",
        !           176: /* 18 unused  */ "signal 18",
        !           177: /* 19 SIGCONT */ "Process continued",
        !           178: /* 20 SIGCHLD */ "Child death",
        !           179: };
        !           180: Waitfor(pid, persist){
        !           181:        register int wpid, sig;
        !           182:        register struct thread *p;
        !           183:        int wstat;
        !           184:        char wstatstr[12];
        !           185:        for(;;){
        !           186:                errno=0;
        !           187:                wpid=wait(&wstat);
        !           188:                if(errno==EINTR && persist) continue;
        !           189:                if(wpid==-1) break;
        !           190:                sig=wstat&0177;
        !           191:                if(sig==0177){
        !           192:                        pfmt(err, "trace: ");
        !           193:                        sig=(wstat>>8)&0177;
        !           194:                }
        !           195:                if(sig>(sizeof sigmsg/sizeof sigmsg[0]) || sigmsg[sig]){
        !           196:                        if(pid!=wpid) pfmt(err, "%d: ", wpid);
        !           197:                        if(sig<=(sizeof sigmsg/sizeof sigmsg[0]))
        !           198:                                pfmt(err, "%s", sigmsg[sig]);
        !           199:                        else if(sig==0177) pfmt(err, "stopped by ptrace");
        !           200:                        else pfmt(err, "signal %d", sig);
        !           201:                        if(wstat&0200)pfmt(err, " -- core dumped");
        !           202:                        pfmt(err, "\n");
        !           203:                }
        !           204:                wstat=sig?sig+1000:(wstat>>8)&0xFF;
        !           205:                if(wpid==pid){
        !           206:                        itoa(wstatstr, wstat);
        !           207:                        setstatus(wstatstr);
        !           208:                        break;
        !           209:                }
        !           210:                else{
        !           211:                        for(p=runq->ret;p;p=p->ret)
        !           212:                                if(p->pid==wpid){
        !           213:                                        p->pid=-1;
        !           214:                                        itoa(p->status, wstat);
        !           215:                                        break;
        !           216:                                }
        !           217:                }
        !           218:        }
        !           219: }
        !           220: char **mkargv(a)
        !           221: register struct word *a;
        !           222: {
        !           223:        char **argv=(char **)emalloc((count(a)+2)*sizeof(char *));
        !           224:        register char **argp=argv+1;    /* leave one at front for runcoms */
        !           225:        for(;a;a=a->next) *argp++=a->word;
        !           226:        *argp=0;
        !           227:        return argv;
        !           228: }
        !           229: Updenv(){}
        !           230: Execute(args, path)
        !           231: register struct word *args, *path;
        !           232: {
        !           233:        register char *msg="not found";
        !           234:        register int txtbusy=0;
        !           235:        char **env=mkenv();
        !           236:        char **argv=mkargv(args);
        !           237:        char file[512];
        !           238:        for(;path;path=path->next){
        !           239:                strcpy(file, path->word);
        !           240:                if(file[0]) strcat(file, "/");
        !           241:                strcat(file, argv[1]);
        !           242:        ReExec:
        !           243:                execve(file, argv+1, env);
        !           244:                switch(errno){
        !           245:                case ENOEXEC:
        !           246:                        pfmt(err, "%s: Bourne again\n", argv[1]);
        !           247:                        argv[0]="sh";
        !           248:                        argv[1]=strdup(file);
        !           249:                        execve("/bin/sh", argv, env);
        !           250:                        goto Bad;
        !           251:                case ETXTBSY:
        !           252:                        if(++txtbusy!=5){
        !           253:                                sleep(txtbusy);
        !           254:                                goto ReExec;
        !           255:                        }
        !           256:                        msg="text busy"; goto Bad;
        !           257:                case EACCES: msg="no access"; break;
        !           258:                case ENOMEM: msg="not enough memory"; goto Bad;
        !           259:                case E2BIG: msg="too big"; goto Bad;
        !           260:                }
        !           261:        }
        !           262: Bad:
        !           263:        pfmt(err, "%s: %s\n", argv[1], msg);
        !           264:        efree((char *)env);
        !           265:        efree((char *)argv);
        !           266: }
        !           267: #define        NDIR    14              /* should get this from param.h */
        !           268: Globsize(p)
        !           269: register char *p;
        !           270: {
        !           271:        int isglob=0, globlen=NDIR+1;
        !           272:        for(;*p;p++){
        !           273:                if(*p==GLOB){
        !           274:                        p++;
        !           275:                        if(*p!=GLOB) isglob++;
        !           276:                        globlen+=*p=='*'?NDIR:1;
        !           277:                }
        !           278:                else
        !           279:                        globlen++;
        !           280:        }
        !           281:        return isglob?globlen:0;
        !           282: }
        !           283: #include <sys/types.h>
        !           284: #include <ndir.h>
        !           285: #define        NDIRLIST        50
        !           286: DIR *dirlist[NDIRLIST];
        !           287: Opendir(name)
        !           288: char *name;
        !           289: {
        !           290:        register DIR **dp;
        !           291:        for(dp=dirlist;dp!=&dirlist[NDIRLIST];dp++)
        !           292:                if(*dp==0){
        !           293:                        *dp=opendir(name);
        !           294:                        return *dp?dp-dirlist:-1;
        !           295:                }
        !           296:        return -1;
        !           297: }
        !           298: Readdir(f, p)
        !           299: register int f;
        !           300: register char *p;
        !           301: {
        !           302:        struct direct *dp=readdir(dirlist[f]);
        !           303:        if(dp==0) return 0;
        !           304:        strcpy(p, dp->d_name);
        !           305:        return 1;
        !           306: }
        !           307: Closedir(f){
        !           308:        closedir(dirlist[f]);
        !           309:        dirlist[f]=0;
        !           310: }
        !           311: char *Signame[]={
        !           312:        "sigexit",      "sighup",       "sigint",       "sigquit",
        !           313:        "sigill",       "sigtrap",      "sigiot",       "sigemt",
        !           314:        "sigfpe",       "sigkill",      "sigbus",       "sigsegv",
        !           315:        "sigsys",       "sigpipe",      "sigalrm",      "sigterm",
        !           316:        "sig16",        "sigstop",      "sigtstp",      "sigcont",
        !           317:        "sigchld",      "sigttin",      "sigttou",      "sigtint",
        !           318:        "sigxcpu",      "sigxfsz",      "sig26",        "sig27",
        !           319:        "sig28",        "sig29",        "sig30",        "sig31",
        !           320:        0,
        !           321: };
        !           322: int gettrap(sig){
        !           323:        signal(sig, gettrap);
        !           324:        trap[sig]++;
        !           325:        ntrap++;
        !           326:        if(ntrap>=NSIG){
        !           327:                pfmt(err, "rc: Too many traps (trap %d), dumping core\n", sig);
        !           328:                signal(SIGIOT, (int (*)())0);
        !           329:                kill(getpid(), SIGIOT);
        !           330:        }
        !           331: }
        !           332: Trapinit(){
        !           333:        register int i;
        !           334:        register int (*sig)();
        !           335:        if(1 || flag['d']){     /* wrong!!! */
        !           336:                sig=signal(SIGINT, gettrap);
        !           337:                if(sig==SIG_IGN) signal(SIGINT, SIG_IGN);
        !           338:        }
        !           339:        else{
        !           340:                for(i=1;i<=NSIG;i++) if(i!=SIGCHLD){
        !           341:                        sig=signal(i, gettrap);
        !           342:                        if(sig==SIG_IGN) signal(i, SIG_IGN);
        !           343:                }
        !           344:        }
        !           345: }
        !           346: Unlink(name)
        !           347: char *name;
        !           348: {
        !           349:        return unlink(name);
        !           350: }
        !           351: Write(fd, buf, cnt)
        !           352: char *buf;
        !           353: {
        !           354:        return write(fd, buf, cnt);
        !           355: }
        !           356: Read(fd, buf, cnt)
        !           357: char *buf;
        !           358: {
        !           359:        return read(fd, buf, cnt);
        !           360: }
        !           361: Seek(fd, cnt, whence)
        !           362: long cnt;
        !           363: {
        !           364:        return lseek(fd, cnt, whence);
        !           365: }
        !           366: Executable(file)
        !           367: char *file;
        !           368: {
        !           369:        return(access(file, 01)==0);
        !           370: }
        !           371: Creat(file)
        !           372: char *file;
        !           373: {
        !           374:        return creat(file, 0666);
        !           375: }
        !           376: Dup(a, b){
        !           377:        return dup2(a, b);
        !           378: }
        !           379: Dup1(a){
        !           380:        return dup(a);
        !           381: }
        !           382: /*
        !           383:  * Wrong:  should go through components of a|b|c and return the maximum.
        !           384:  */
        !           385: Exit(stat)
        !           386: register char *stat;
        !           387: {
        !           388:        register int n=0;
        !           389:        while(*stat){
        !           390:                if(*stat!='|'){
        !           391:                        if(*stat<'0' || '9'<*stat) exit(1);
        !           392:                        else n=n*10+*stat-'0';
        !           393:                }
        !           394:                stat++;
        !           395:        }
        !           396:        exit(n);
        !           397: }
        !           398: Eintr(){
        !           399:        return errno==EINTR;
        !           400: }
        !           401: Noerror(){
        !           402:        errno=0;
        !           403: }
        !           404: Isatty(fd){
        !           405:        return isatty(fd);
        !           406: }
        !           407: Abort(){
        !           408:        abort();
        !           409: }
        !           410: execumask(){           /* wrong -- should fork before writing */
        !           411:        register int m;
        !           412:        struct io out[1];
        !           413:        switch(count(runq->argv->words)){
        !           414:        default:
        !           415:                pfmt(err, "Usage: umask [umask]\n");
        !           416:                setstatus("umask usage");
        !           417:                poplist();
        !           418:                return;
        !           419:        case 2: umask(octal(runq->argv->words->next->word)); break;
        !           420:        case 1: 
        !           421:                umask(m=umask(0));
        !           422:                out->fd=mapfd(1);
        !           423:                out->bufp=out->buf;
        !           424:                out->ebuf=&out->buf[NBUF];
        !           425:                out->strp=0;
        !           426:                pfmt(out, "%o\n", m);
        !           427:                break;
        !           428:        }
        !           429:        setstatus("");
        !           430:        poplist();
        !           431: }
        !           432: Memcpy(a, b, n)
        !           433: char *a, *b;
        !           434: {
        !           435:        memmove(a, b, n);
        !           436: }
        !           437: void *Malloc(n){
        !           438:        return (void *)malloc(n);
        !           439: }

unix.superglobalmegacorp.com

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