|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.