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