123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- /*
- * Unix versions of system-specific functions
- * By convention, exported routines herein have names beginning with an
- * upper case letter.
- */
- #include "rc.h"
- #include "exec.h"
- #include <errno.h>
- char Rcmain[]="/usr/lib/rcmain";
- char Fdprefix[]="/dev/fd/";
- int execumask(), execfinit();
- struct builtin Builtin[]={
- "cd", execcd,
- "whatis", execwhatis,
- "eval", execeval,
- "exec", execexec, /* but with popword first */
- "exit", execexit,
- "shift", execshift,
- "wait", execwait,
- "umask", execumask,
- ".", execdot,
- "finit", execfinit,
- "flag", execflag,
- 0
- };
- #define SEP '\1'
- char **environp;
- struct word *enval(s)
- register char *s;
- {
- register char *t, c;
- register struct word *v;
- for(t=s;*t && *t!=SEP;t++);
- c=*t;
- *t='\0';
- v=newword(s, c=='\0'?(struct word *)0:enval(t+1));
- *t=c;
- return v;
- }
- Vinit(){
- extern char **environ;
- register char *s;
- register char **env=environ;
- environp=env;
- for(;*env;env++){
- for(s=*env;*s && *s!='(' && *s!='=';s++);
- switch(*s){
- case '\0':
- pfmt(err, "environment %q?\n", *env);
- break;
- case '=':
- *s='\0';
- setvar(*env, enval(s+1));
- *s='=';
- break;
- case '(': /* ignore functions for now */
- break;
- }
- }
- }
- char **envp;
- Xrdfn(){
- register char *s;
- register int len;
- for(;*envp;envp++){
- for(s=*envp;*s && *s!='(' && *s!='=';s++);
- switch(*s){
- case '\0':
- pfmt(err, "environment %q?\n", *envp);
- break;
- case '=': /* ignore variables */
- break;
- case '(': /* Bourne again */
- s=*envp+3;
- envp++;
- len=strlen(s);
- s[len]='\n';
- execcmds(opencore(s, len+1));
- s[len]='\0';
- return;
- }
- }
- Xreturn();
- }
- union code rdfns[4];
- execfinit(){
- static int first=1;
- if(first){
- rdfns[0].i=1;
- rdfns[1].f=Xrdfn;
- rdfns[2].f=Xjump;
- rdfns[3].i=1;
- first=0;
- }
- Xpopm();
- envp=environp;
- start(rdfns, 1, runq->local);
- }
- cmpenv(a, b)
- char **a, **b;
- {
- return strcmp(*a, *b);
- }
- char **mkenv(){
- register char **env, **ep, *p, *q;
- register struct var **h, *v;
- register struct word *a;
- register int nvar=0, nchr=0, sep;
- /*
- * Slightly kludgy loops look at locals then globals
- */
- for(h=var-1;h!=&var[NVAR];h++) for(v=h>=var?*h:runq->local;v;v=v->next){
- if((v==vlook(v->name)) && v->val){
- nvar++;
- nchr+=strlen(v->name)+1;
- for(a=v->val;a;a=a->next)
- nchr+=strlen(a->word)+1;
- }
- if(v->fn){
- nvar++;
- nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8;
- }
- }
- env=(char **)emalloc((nvar+1)*sizeof(char *)+nchr);
- ep=env;
- p=(char *)&env[nvar+1];
- for(h=var-1;h!=&var[NVAR];h++) for(v=h>=var?*h:runq->local;v;v=v->next){
- if((v==vlook(v->name)) && v->val){
- *ep++=p;
- q=v->name;
- while(*q) *p++=*q++;
- sep='=';
- for(a=v->val;a;a=a->next){
- *p++=sep;
- sep=SEP;
- q=a->word;
- while(*q) *p++=*q++;
- }
- *p++='\0';
- }
- if(v->fn){
- *ep++=p;
- *p++='#'; *p++='('; *p++=')'; /* to fool Bourne */
- *p++='f'; *p++='n'; *p++=' ';
- q=v->name;
- while(*q) *p++=*q++;
- *p++=' ';
- q=v->fn[v->pc-1].s;
- while(*q) *p++=*q++;
- *p++='\0';
- }
- }
- *ep=0;
- qsort((char *)env, nvar, sizeof ep[0], cmpenv);
- return env;
- }
- char *sigmsg[]={
- /* 0 normal */ 0,
- /* 1 SIGHUP */ "Hangup",
- /* 2 SIGINT */ 0,
- /* 3 SIGQUIT */ "Quit",
- /* 4 SIGILL */ "Illegal instruction",
- /* 5 SIGTRAP */ "Trace/BPT trap",
- /* 6 SIGIOT */ "abort",
- /* 7 SIGEMT */ "EMT trap",
- /* 8 SIGFPE */ "Floating exception",
- /* 9 SIGKILL */ "Killed",
- /* 10 SIGBUS */ "Bus error",
- /* 11 SIGSEGV */ "Memory fault",
- /* 12 SIGSYS */ "Bad system call",
- /* 13 SIGPIPE */ 0,
- /* 14 SIGALRM */ "Alarm call",
- /* 15 SIGTERM */ "Terminated",
- /* 16 unused */ "signal 16",
- /* 17 SIGSTOP */ "Process stopped",
- /* 18 unused */ "signal 18",
- /* 19 SIGCONT */ "Process continued",
- /* 20 SIGCHLD */ "Child death",
- };
- Waitfor(pid, persist){
- register int wpid, sig;
- register struct thread *p;
- int wstat;
- char wstatstr[12];
- for(;;){
- errno=0;
- wpid=wait(&wstat);
- if(errno==EINTR && persist) continue;
- if(wpid==-1) break;
- sig=wstat&0177;
- if(sig==0177){
- pfmt(err, "trace: ");
- sig=(wstat>>8)&0177;
- }
- if(sig>(sizeof sigmsg/sizeof sigmsg[0]) || sigmsg[sig]){
- if(pid!=wpid) pfmt(err, "%d: ", wpid);
- if(sig<=(sizeof sigmsg/sizeof sigmsg[0]))
- pfmt(err, "%s", sigmsg[sig]);
- else if(sig==0177) pfmt(err, "stopped by ptrace");
- else pfmt(err, "signal %d", sig);
- if(wstat&0200)pfmt(err, " -- core dumped");
- pfmt(err, "\n");
- }
- wstat=sig?sig+1000:(wstat>>8)&0xFF;
- if(wpid==pid){
- itoa(wstatstr, wstat);
- setstatus(wstatstr);
- break;
- }
- else{
- for(p=runq->ret;p;p=p->ret)
- if(p->pid==wpid){
- p->pid=-1;
- itoa(p->status, wstat);
- break;
- }
- }
- }
- }
- char **mkargv(a)
- register struct word *a;
- {
- char **argv=(char **)emalloc((count(a)+2)*sizeof(char *));
- register char **argp=argv+1; /* leave one at front for runcoms */
- for(;a;a=a->next) *argp++=a->word;
- *argp=0;
- return argv;
- }
- Updenv(){}
- Execute(args, path)
- register struct word *args, *path;
- {
- register char *msg="not found";
- register int txtbusy=0;
- char **env=mkenv();
- char **argv=mkargv(args);
- char file[512];
- for(;path;path=path->next){
- strcpy(file, path->word);
- if(file[0]) strcat(file, "/");
- strcat(file, argv[1]);
- ReExec:
- execve(file, argv+1, env);
- switch(errno){
- case ENOEXEC:
- pfmt(err, "%s: Bourne again\n", argv[1]);
- argv[0]="sh";
- argv[1]=strdup(file);
- execve("/bin/sh", argv, env);
- goto Bad;
- case ETXTBSY:
- if(++txtbusy!=5){
- sleep(txtbusy);
- goto ReExec;
- }
- msg="text busy"; goto Bad;
- case EACCES: msg="no access"; break;
- case ENOMEM: msg="not enough memory"; goto Bad;
- case E2BIG: msg="too big"; goto Bad;
- }
- }
- Bad:
- pfmt(err, "%s: %s\n", argv[1], msg);
- efree((char *)env);
- efree((char *)argv);
- }
- #define NDIR 14 /* should get this from param.h */
- Globsize(p)
- register char *p;
- {
- int isglob=0, globlen=NDIR+1;
- for(;*p;p++){
- if(*p==GLOB){
- p++;
- if(*p!=GLOB) isglob++;
- globlen+=*p=='*'?NDIR:1;
- }
- else
- globlen++;
- }
- return isglob?globlen:0;
- }
- #include <sys/types.h>
- #include <ndir.h>
- #define NDIRLIST 50
- DIR *dirlist[NDIRLIST];
- Opendir(name)
- char *name;
- {
- register DIR **dp;
- for(dp=dirlist;dp!=&dirlist[NDIRLIST];dp++)
- if(*dp==0){
- *dp=opendir(name);
- return *dp?dp-dirlist:-1;
- }
- return -1;
- }
- Readdir(f, p)
- register int f;
- register char *p;
- {
- struct direct *dp=readdir(dirlist[f]);
- if(dp==0) return 0;
- strcpy(p, dp->d_name);
- return 1;
- }
- Closedir(f){
- closedir(dirlist[f]);
- dirlist[f]=0;
- }
- char *Signame[]={
- "sigexit", "sighup", "sigint", "sigquit",
- "sigill", "sigtrap", "sigiot", "sigemt",
- "sigfpe", "sigkill", "sigbus", "sigsegv",
- "sigsys", "sigpipe", "sigalrm", "sigterm",
- "sig16", "sigstop", "sigtstp", "sigcont",
- "sigchld", "sigttin", "sigttou", "sigtint",
- "sigxcpu", "sigxfsz", "sig26", "sig27",
- "sig28", "sig29", "sig30", "sig31",
- 0,
- };
- int gettrap(sig){
- signal(sig, gettrap);
- trap[sig]++;
- ntrap++;
- if(ntrap>=NSIG){
- pfmt(err, "rc: Too many traps (trap %d), dumping core\n", sig);
- signal(SIGIOT, (int (*)())0);
- kill(getpid(), SIGIOT);
- }
- }
- Trapinit(){
- register int i;
- register int (*sig)();
- if(1 || flag['d']){ /* wrong!!! */
- sig=signal(SIGINT, gettrap);
- if(sig==SIG_IGN) signal(SIGINT, SIG_IGN);
- }
- else{
- for(i=1;i<=NSIG;i++) if(i!=SIGCHLD){
- sig=signal(i, gettrap);
- if(sig==SIG_IGN) signal(i, SIG_IGN);
- }
- }
- }
- Unlink(name)
- char *name;
- {
- return unlink(name);
- }
- Write(fd, buf, cnt)
- char *buf;
- {
- return write(fd, buf, cnt);
- }
- Read(fd, buf, cnt)
- char *buf;
- {
- return read(fd, buf, cnt);
- }
- Seek(fd, cnt, whence)
- long cnt;
- {
- return lseek(fd, cnt, whence);
- }
- Executable(file)
- char *file;
- {
- return(access(file, 01)==0);
- }
- Creat(file)
- char *file;
- {
- return creat(file, 0666);
- }
- Dup(a, b){
- return dup2(a, b);
- }
- Dup1(a){
- return dup(a);
- }
- /*
- * Wrong: should go through components of a|b|c and return the maximum.
- */
- Exit(stat)
- register char *stat;
- {
- register int n=0;
- while(*stat){
- if(*stat!='|'){
- if(*stat<'0' || '9'<*stat) exit(1);
- else n=n*10+*stat-'0';
- }
- stat++;
- }
- exit(n);
- }
- Eintr(){
- return errno==EINTR;
- }
- Noerror(){
- errno=0;
- }
- Isatty(fd){
- return isatty(fd);
- }
- Abort(){
- abort();
- }
- execumask(){ /* wrong -- should fork before writing */
- register int m;
- struct io out[1];
- switch(count(runq->argv->words)){
- default:
- pfmt(err, "Usage: umask [umask]\n");
- setstatus("umask usage");
- poplist();
- return;
- case 2: umask(octal(runq->argv->words->next->word)); break;
- case 1:
- umask(m=umask(0));
- out->fd=mapfd(1);
- out->bufp=out->buf;
- out->ebuf=&out->buf[NBUF];
- out->strp=0;
- pfmt(out, "%o\n", m);
- break;
- }
- setstatus("");
- poplist();
- }
- Memcpy(a, b, n)
- char *a, *b;
- {
- memmove(a, b, n);
- }
- void *Malloc(n){
- return (void *)malloc(n);
- }
|