xref: /plan9-contrib/sys/src/cmd/rc/unix.c (revision 6b6b9ac8b0b103b1e30e4d019522a78c950fce74)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier  * Unix versions of system-specific functions
33e12c5d1SDavid du Colombier  *	By convention, exported routines herein have names beginning with an
43e12c5d1SDavid du Colombier  *	upper case letter.
53e12c5d1SDavid du Colombier  */
63e12c5d1SDavid du Colombier #include "rc.h"
73e12c5d1SDavid du Colombier #include "exec.h"
83e12c5d1SDavid du Colombier #include <errno.h>
93e12c5d1SDavid du Colombier char Rcmain[]="/usr/lib/rcmain";
103e12c5d1SDavid du Colombier char Fdprefix[]="/dev/fd/";
113e12c5d1SDavid du Colombier int execumask(), execfinit();
123e12c5d1SDavid du Colombier struct builtin Builtin[]={
133e12c5d1SDavid du Colombier 	"cd",		execcd,
143e12c5d1SDavid du Colombier 	"whatis",	execwhatis,
153e12c5d1SDavid du Colombier 	"eval",		execeval,
163e12c5d1SDavid du Colombier 	"exec",		execexec,	/* but with popword first */
173e12c5d1SDavid du Colombier 	"exit",		execexit,
183e12c5d1SDavid du Colombier 	"shift",	execshift,
193e12c5d1SDavid du Colombier 	"wait",		execwait,
203e12c5d1SDavid du Colombier 	"umask",	execumask,
213e12c5d1SDavid du Colombier 	".",		execdot,
223e12c5d1SDavid du Colombier 	"finit",	execfinit,
233e12c5d1SDavid du Colombier 	"flag",		execflag,
243e12c5d1SDavid du Colombier 	0
253e12c5d1SDavid du Colombier };
263e12c5d1SDavid du Colombier #define	SEP	'\1'
273e12c5d1SDavid du Colombier char **environp;
283e12c5d1SDavid du Colombier struct word *enval(s)
293e12c5d1SDavid du Colombier register char *s;
303e12c5d1SDavid du Colombier {
313e12c5d1SDavid du Colombier 	register char *t, c;
323e12c5d1SDavid du Colombier 	register struct word *v;
333e12c5d1SDavid du Colombier 	for(t=s;*t && *t!=SEP;t++);
343e12c5d1SDavid du Colombier 	c=*t;
353e12c5d1SDavid du Colombier 	*t='\0';
363e12c5d1SDavid du Colombier 	v=newword(s, c=='\0'?(struct word *)0:enval(t+1));
373e12c5d1SDavid du Colombier 	*t=c;
383e12c5d1SDavid du Colombier 	return v;
393e12c5d1SDavid du Colombier }
403e12c5d1SDavid du Colombier Vinit(){
413e12c5d1SDavid du Colombier 	extern char **environ;
423e12c5d1SDavid du Colombier 	register char *s;
433e12c5d1SDavid du Colombier 	register char **env=environ;
443e12c5d1SDavid du Colombier 	environp=env;
453e12c5d1SDavid du Colombier 	for(;*env;env++){
463e12c5d1SDavid du Colombier 		for(s=*env;*s && *s!='(' && *s!='=';s++);
473e12c5d1SDavid du Colombier 		switch(*s){
483e12c5d1SDavid du Colombier 		case '\0':
493e12c5d1SDavid du Colombier 			pfmt(err, "environment %q?\n", *env);
503e12c5d1SDavid du Colombier 			break;
513e12c5d1SDavid du Colombier 		case '=':
523e12c5d1SDavid du Colombier 			*s='\0';
533e12c5d1SDavid du Colombier 			setvar(*env, enval(s+1));
543e12c5d1SDavid du Colombier 			*s='=';
553e12c5d1SDavid du Colombier 			break;
563e12c5d1SDavid du Colombier 		case '(':	/* ignore functions for now */
573e12c5d1SDavid du Colombier 			break;
583e12c5d1SDavid du Colombier 		}
593e12c5d1SDavid du Colombier 	}
603e12c5d1SDavid du Colombier }
613e12c5d1SDavid du Colombier char **envp;
623e12c5d1SDavid du Colombier Xrdfn(){
633e12c5d1SDavid du Colombier 	register char *s;
643e12c5d1SDavid du Colombier 	register int len;
653e12c5d1SDavid du Colombier 	for(;*envp;envp++){
663e12c5d1SDavid du Colombier 		for(s=*envp;*s && *s!='(' && *s!='=';s++);
673e12c5d1SDavid du Colombier 		switch(*s){
683e12c5d1SDavid du Colombier 		case '\0':
693e12c5d1SDavid du Colombier 			pfmt(err, "environment %q?\n", *envp);
703e12c5d1SDavid du Colombier 			break;
713e12c5d1SDavid du Colombier 		case '=':	/* ignore variables */
723e12c5d1SDavid du Colombier 			break;
733e12c5d1SDavid du Colombier 		case '(':		/* Bourne again */
743e12c5d1SDavid du Colombier 			s=*envp+3;
753e12c5d1SDavid du Colombier 			envp++;
763e12c5d1SDavid du Colombier 			len=strlen(s);
773e12c5d1SDavid du Colombier 			s[len]='\n';
783e12c5d1SDavid du Colombier 			execcmds(opencore(s, len+1));
793e12c5d1SDavid du Colombier 			s[len]='\0';
803e12c5d1SDavid du Colombier 			return;
813e12c5d1SDavid du Colombier 		}
823e12c5d1SDavid du Colombier 	}
833e12c5d1SDavid du Colombier 	Xreturn();
843e12c5d1SDavid du Colombier }
853e12c5d1SDavid du Colombier union code rdfns[4];
863e12c5d1SDavid du Colombier execfinit(){
873e12c5d1SDavid du Colombier 	static int first=1;
883e12c5d1SDavid du Colombier 	if(first){
893e12c5d1SDavid du Colombier 		rdfns[0].i=1;
903e12c5d1SDavid du Colombier 		rdfns[1].f=Xrdfn;
913e12c5d1SDavid du Colombier 		rdfns[2].f=Xjump;
923e12c5d1SDavid du Colombier 		rdfns[3].i=1;
933e12c5d1SDavid du Colombier 		first=0;
943e12c5d1SDavid du Colombier 	}
953e12c5d1SDavid du Colombier 	Xpopm();
963e12c5d1SDavid du Colombier 	envp=environp;
973e12c5d1SDavid du Colombier 	start(rdfns, 1, runq->local);
983e12c5d1SDavid du Colombier }
993e12c5d1SDavid du Colombier cmpenv(a, b)
1003e12c5d1SDavid du Colombier char **a, **b;
1013e12c5d1SDavid du Colombier {
1023e12c5d1SDavid du Colombier 	return strcmp(*a, *b);
1033e12c5d1SDavid du Colombier }
1043e12c5d1SDavid du Colombier char **mkenv(){
1053e12c5d1SDavid du Colombier 	register char **env, **ep, *p, *q;
1063e12c5d1SDavid du Colombier 	register struct var **h, *v;
1073e12c5d1SDavid du Colombier 	register struct word *a;
1083e12c5d1SDavid du Colombier 	register int nvar=0, nchr=0, sep;
1093e12c5d1SDavid du Colombier 	/*
1103e12c5d1SDavid du Colombier 	 * Slightly kludgy loops look at locals then globals
1113e12c5d1SDavid du Colombier 	 */
1123e12c5d1SDavid du Colombier 	for(h=var-1;h!=&var[NVAR];h++) for(v=h>=var?*h:runq->local;v;v=v->next){
1133e12c5d1SDavid du Colombier 		if((v==vlook(v->name)) && v->val){
1143e12c5d1SDavid du Colombier 			nvar++;
1153e12c5d1SDavid du Colombier 			nchr+=strlen(v->name)+1;
1163e12c5d1SDavid du Colombier 			for(a=v->val;a;a=a->next)
1173e12c5d1SDavid du Colombier 				nchr+=strlen(a->word)+1;
1183e12c5d1SDavid du Colombier 		}
1193e12c5d1SDavid du Colombier 		if(v->fn){
1203e12c5d1SDavid du Colombier 			nvar++;
1213e12c5d1SDavid du Colombier 			nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8;
1223e12c5d1SDavid du Colombier 		}
1233e12c5d1SDavid du Colombier 	}
1243e12c5d1SDavid du Colombier 	env=(char **)emalloc((nvar+1)*sizeof(char *)+nchr);
1253e12c5d1SDavid du Colombier 	ep=env;
1263e12c5d1SDavid du Colombier 	p=(char *)&env[nvar+1];
1273e12c5d1SDavid du Colombier 	for(h=var-1;h!=&var[NVAR];h++) for(v=h>=var?*h:runq->local;v;v=v->next){
1283e12c5d1SDavid du Colombier 		if((v==vlook(v->name)) && v->val){
1293e12c5d1SDavid du Colombier 			*ep++=p;
1303e12c5d1SDavid du Colombier 			q=v->name;
1313e12c5d1SDavid du Colombier 			while(*q) *p++=*q++;
1323e12c5d1SDavid du Colombier 			sep='=';
1333e12c5d1SDavid du Colombier 			for(a=v->val;a;a=a->next){
1343e12c5d1SDavid du Colombier 				*p++=sep;
1353e12c5d1SDavid du Colombier 				sep=SEP;
1363e12c5d1SDavid du Colombier 				q=a->word;
1373e12c5d1SDavid du Colombier 				while(*q) *p++=*q++;
1383e12c5d1SDavid du Colombier 			}
1393e12c5d1SDavid du Colombier 			*p++='\0';
1403e12c5d1SDavid du Colombier 		}
1413e12c5d1SDavid du Colombier 		if(v->fn){
1423e12c5d1SDavid du Colombier 			*ep++=p;
1433e12c5d1SDavid du Colombier 			*p++='#'; *p++='('; *p++=')';	/* to fool Bourne */
1443e12c5d1SDavid du Colombier 			*p++='f'; *p++='n'; *p++=' ';
1453e12c5d1SDavid du Colombier 			q=v->name;
1463e12c5d1SDavid du Colombier 			while(*q) *p++=*q++;
1473e12c5d1SDavid du Colombier 			*p++=' ';
1483e12c5d1SDavid du Colombier 			q=v->fn[v->pc-1].s;
1493e12c5d1SDavid du Colombier 			while(*q) *p++=*q++;
1503e12c5d1SDavid du Colombier 			*p++='\0';
1513e12c5d1SDavid du Colombier 		}
1523e12c5d1SDavid du Colombier 	}
1533e12c5d1SDavid du Colombier 	*ep=0;
1543e12c5d1SDavid du Colombier 	qsort((char *)env, nvar, sizeof ep[0], cmpenv);
1553e12c5d1SDavid du Colombier 	return env;
1563e12c5d1SDavid du Colombier }
1573e12c5d1SDavid du Colombier char *sigmsg[]={
1583e12c5d1SDavid du Colombier /*  0 normal  */ 0,
1593e12c5d1SDavid du Colombier /*  1 SIGHUP  */ "Hangup",
1603e12c5d1SDavid du Colombier /*  2 SIGINT  */ 0,
1613e12c5d1SDavid du Colombier /*  3 SIGQUIT */ "Quit",
1623e12c5d1SDavid du Colombier /*  4 SIGILL  */ "Illegal instruction",
1633e12c5d1SDavid du Colombier /*  5 SIGTRAP */ "Trace/BPT trap",
1643e12c5d1SDavid du Colombier /*  6 SIGIOT  */ "abort",
1653e12c5d1SDavid du Colombier /*  7 SIGEMT  */ "EMT trap",
1663e12c5d1SDavid du Colombier /*  8 SIGFPE  */ "Floating exception",
1673e12c5d1SDavid du Colombier /*  9 SIGKILL */ "Killed",
1683e12c5d1SDavid du Colombier /* 10 SIGBUS  */ "Bus error",
1693e12c5d1SDavid du Colombier /* 11 SIGSEGV */ "Memory fault",
1703e12c5d1SDavid du Colombier /* 12 SIGSYS  */ "Bad system call",
1713e12c5d1SDavid du Colombier /* 13 SIGPIPE */ 0,
1723e12c5d1SDavid du Colombier /* 14 SIGALRM */ "Alarm call",
1733e12c5d1SDavid du Colombier /* 15 SIGTERM */ "Terminated",
1743e12c5d1SDavid du Colombier /* 16 unused  */ "signal 16",
1753e12c5d1SDavid du Colombier /* 17 SIGSTOP */ "Process stopped",
1763e12c5d1SDavid du Colombier /* 18 unused  */ "signal 18",
1773e12c5d1SDavid du Colombier /* 19 SIGCONT */ "Process continued",
1783e12c5d1SDavid du Colombier /* 20 SIGCHLD */ "Child death",
1793e12c5d1SDavid du Colombier };
1803e12c5d1SDavid du Colombier Waitfor(pid, persist){
1813e12c5d1SDavid du Colombier 	register int wpid, sig;
1823e12c5d1SDavid du Colombier 	register struct thread *p;
1833e12c5d1SDavid du Colombier 	int wstat;
1843e12c5d1SDavid du Colombier 	char wstatstr[12];
1853e12c5d1SDavid du Colombier 	for(;;){
1863e12c5d1SDavid du Colombier 		errno=0;
1873e12c5d1SDavid du Colombier 		wpid=wait(&wstat);
1883e12c5d1SDavid du Colombier 		if(errno==EINTR && persist) continue;
1893e12c5d1SDavid du Colombier 		if(wpid==-1) break;
1903e12c5d1SDavid du Colombier 		sig=wstat&0177;
1913e12c5d1SDavid du Colombier 		if(sig==0177){
1923e12c5d1SDavid du Colombier 			pfmt(err, "trace: ");
1933e12c5d1SDavid du Colombier 			sig=(wstat>>8)&0177;
1943e12c5d1SDavid du Colombier 		}
1953e12c5d1SDavid du Colombier 		if(sig>(sizeof sigmsg/sizeof sigmsg[0]) || sigmsg[sig]){
1963e12c5d1SDavid du Colombier 			if(pid!=wpid) pfmt(err, "%d: ", wpid);
1973e12c5d1SDavid du Colombier 			if(sig<=(sizeof sigmsg/sizeof sigmsg[0]))
1983e12c5d1SDavid du Colombier 				pfmt(err, "%s", sigmsg[sig]);
1993e12c5d1SDavid du Colombier 			else if(sig==0177) pfmt(err, "stopped by ptrace");
2003e12c5d1SDavid du Colombier 			else pfmt(err, "signal %d", sig);
2013e12c5d1SDavid du Colombier 			if(wstat&0200)pfmt(err, " -- core dumped");
2023e12c5d1SDavid du Colombier 			pfmt(err, "\n");
2033e12c5d1SDavid du Colombier 		}
2043e12c5d1SDavid du Colombier 		wstat=sig?sig+1000:(wstat>>8)&0xFF;
2053e12c5d1SDavid du Colombier 		if(wpid==pid){
2063e12c5d1SDavid du Colombier 			itoa(wstatstr, wstat);
2073e12c5d1SDavid du Colombier 			setstatus(wstatstr);
2083e12c5d1SDavid du Colombier 			break;
2093e12c5d1SDavid du Colombier 		}
2103e12c5d1SDavid du Colombier 		else{
2113e12c5d1SDavid du Colombier 			for(p=runq->ret;p;p=p->ret)
2123e12c5d1SDavid du Colombier 				if(p->pid==wpid){
2133e12c5d1SDavid du Colombier 					p->pid=-1;
2143e12c5d1SDavid du Colombier 					itoa(p->status, wstat);
2153e12c5d1SDavid du Colombier 					break;
2163e12c5d1SDavid du Colombier 				}
2173e12c5d1SDavid du Colombier 		}
2183e12c5d1SDavid du Colombier 	}
2193e12c5d1SDavid du Colombier }
2203e12c5d1SDavid du Colombier char **mkargv(a)
2213e12c5d1SDavid du Colombier register struct word *a;
2223e12c5d1SDavid du Colombier {
2233e12c5d1SDavid du Colombier 	char **argv=(char **)emalloc((count(a)+2)*sizeof(char *));
2243e12c5d1SDavid du Colombier 	register char **argp=argv+1;	/* leave one at front for runcoms */
2253e12c5d1SDavid du Colombier 	for(;a;a=a->next) *argp++=a->word;
2263e12c5d1SDavid du Colombier 	*argp=0;
2273e12c5d1SDavid du Colombier 	return argv;
2283e12c5d1SDavid du Colombier }
2293e12c5d1SDavid du Colombier Updenv(){}
2303e12c5d1SDavid du Colombier Execute(args, path)
2313e12c5d1SDavid du Colombier register struct word *args, *path;
2323e12c5d1SDavid du Colombier {
2333e12c5d1SDavid du Colombier 	register char *msg="not found";
2343e12c5d1SDavid du Colombier 	register int txtbusy=0;
2353e12c5d1SDavid du Colombier 	char **env=mkenv();
2363e12c5d1SDavid du Colombier 	char **argv=mkargv(args);
2373e12c5d1SDavid du Colombier 	char file[512];
2383e12c5d1SDavid du Colombier 	for(;path;path=path->next){
2393e12c5d1SDavid du Colombier 		strcpy(file, path->word);
2403e12c5d1SDavid du Colombier 		if(file[0]) strcat(file, "/");
2413e12c5d1SDavid du Colombier 		strcat(file, argv[1]);
2423e12c5d1SDavid du Colombier 	ReExec:
2433e12c5d1SDavid du Colombier 		execve(file, argv+1, env);
2443e12c5d1SDavid du Colombier 		switch(errno){
2453e12c5d1SDavid du Colombier 		case ENOEXEC:
2463e12c5d1SDavid du Colombier 			pfmt(err, "%s: Bourne again\n", argv[1]);
2473e12c5d1SDavid du Colombier 			argv[0]="sh";
2483e12c5d1SDavid du Colombier 			argv[1]=strdup(file);
2493e12c5d1SDavid du Colombier 			execve("/bin/sh", argv, env);
2503e12c5d1SDavid du Colombier 			goto Bad;
2513e12c5d1SDavid du Colombier 		case ETXTBSY:
2523e12c5d1SDavid du Colombier 			if(++txtbusy!=5){
2533e12c5d1SDavid du Colombier 				sleep(txtbusy);
2543e12c5d1SDavid du Colombier 				goto ReExec;
2553e12c5d1SDavid du Colombier 			}
2563e12c5d1SDavid du Colombier 			msg="text busy"; goto Bad;
2573e12c5d1SDavid du Colombier 		case EACCES: msg="no access"; break;
2583e12c5d1SDavid du Colombier 		case ENOMEM: msg="not enough memory"; goto Bad;
2593e12c5d1SDavid du Colombier 		case E2BIG: msg="too big"; goto Bad;
2603e12c5d1SDavid du Colombier 		}
2613e12c5d1SDavid du Colombier 	}
2623e12c5d1SDavid du Colombier Bad:
2633e12c5d1SDavid du Colombier 	pfmt(err, "%s: %s\n", argv[1], msg);
2643e12c5d1SDavid du Colombier 	efree((char *)env);
2653e12c5d1SDavid du Colombier 	efree((char *)argv);
2663e12c5d1SDavid du Colombier }
2673e12c5d1SDavid du Colombier #define	NDIR	14		/* should get this from param.h */
2683e12c5d1SDavid du Colombier Globsize(p)
2693e12c5d1SDavid du Colombier register char *p;
2703e12c5d1SDavid du Colombier {
2713e12c5d1SDavid du Colombier 	int isglob=0, globlen=NDIR+1;
2723e12c5d1SDavid du Colombier 	for(;*p;p++){
2733e12c5d1SDavid du Colombier 		if(*p==GLOB){
2743e12c5d1SDavid du Colombier 			p++;
2753e12c5d1SDavid du Colombier 			if(*p!=GLOB) isglob++;
2763e12c5d1SDavid du Colombier 			globlen+=*p=='*'?NDIR:1;
2773e12c5d1SDavid du Colombier 		}
2783e12c5d1SDavid du Colombier 		else
2793e12c5d1SDavid du Colombier 			globlen++;
2803e12c5d1SDavid du Colombier 	}
2813e12c5d1SDavid du Colombier 	return isglob?globlen:0;
2823e12c5d1SDavid du Colombier }
2833e12c5d1SDavid du Colombier #include <sys/types.h>
2843e12c5d1SDavid du Colombier #include <ndir.h>
2853e12c5d1SDavid du Colombier #define	NDIRLIST	50
2863e12c5d1SDavid du Colombier DIR *dirlist[NDIRLIST];
2873e12c5d1SDavid du Colombier Opendir(name)
2883e12c5d1SDavid du Colombier char *name;
2893e12c5d1SDavid du Colombier {
2903e12c5d1SDavid du Colombier 	register DIR **dp;
2913e12c5d1SDavid du Colombier 	for(dp=dirlist;dp!=&dirlist[NDIRLIST];dp++)
2923e12c5d1SDavid du Colombier 		if(*dp==0){
2933e12c5d1SDavid du Colombier 			*dp=opendir(name);
2943e12c5d1SDavid du Colombier 			return *dp?dp-dirlist:-1;
2953e12c5d1SDavid du Colombier 		}
2963e12c5d1SDavid du Colombier 	return -1;
2973e12c5d1SDavid du Colombier }
298*6b6b9ac8SDavid du Colombier Readdir(f, p, onlydirs)
2993e12c5d1SDavid du Colombier register int f;
3003e12c5d1SDavid du Colombier register char *p;
301*6b6b9ac8SDavid du Colombier register int onlydirs;	/* ignored, just advisory */
3023e12c5d1SDavid du Colombier {
3033e12c5d1SDavid du Colombier 	struct direct *dp=readdir(dirlist[f]);
3043e12c5d1SDavid du Colombier 	if(dp==0) return 0;
3053e12c5d1SDavid du Colombier 	strcpy(p, dp->d_name);
3063e12c5d1SDavid du Colombier 	return 1;
3073e12c5d1SDavid du Colombier }
3083e12c5d1SDavid du Colombier Closedir(f){
3093e12c5d1SDavid du Colombier 	closedir(dirlist[f]);
3103e12c5d1SDavid du Colombier 	dirlist[f]=0;
3113e12c5d1SDavid du Colombier }
3123e12c5d1SDavid du Colombier char *Signame[]={
3133e12c5d1SDavid du Colombier 	"sigexit",	"sighup",	"sigint",	"sigquit",
3143e12c5d1SDavid du Colombier 	"sigill",	"sigtrap",	"sigiot",	"sigemt",
3153e12c5d1SDavid du Colombier 	"sigfpe",	"sigkill",	"sigbus",	"sigsegv",
3163e12c5d1SDavid du Colombier 	"sigsys",	"sigpipe",	"sigalrm",	"sigterm",
3173e12c5d1SDavid du Colombier 	"sig16",	"sigstop",	"sigtstp",	"sigcont",
3183e12c5d1SDavid du Colombier 	"sigchld",	"sigttin",	"sigttou",	"sigtint",
3193e12c5d1SDavid du Colombier 	"sigxcpu",	"sigxfsz",	"sig26",	"sig27",
3203e12c5d1SDavid du Colombier 	"sig28",	"sig29",	"sig30",	"sig31",
3213e12c5d1SDavid du Colombier 	0,
3223e12c5d1SDavid du Colombier };
3233e12c5d1SDavid du Colombier int gettrap(sig){
3243e12c5d1SDavid du Colombier 	signal(sig, gettrap);
3253e12c5d1SDavid du Colombier 	trap[sig]++;
3263e12c5d1SDavid du Colombier 	ntrap++;
3273e12c5d1SDavid du Colombier 	if(ntrap>=NSIG){
3283e12c5d1SDavid du Colombier 		pfmt(err, "rc: Too many traps (trap %d), dumping core\n", sig);
3293e12c5d1SDavid du Colombier 		signal(SIGIOT, (int (*)())0);
3303e12c5d1SDavid du Colombier 		kill(getpid(), SIGIOT);
3313e12c5d1SDavid du Colombier 	}
3323e12c5d1SDavid du Colombier }
3333e12c5d1SDavid du Colombier Trapinit(){
3343e12c5d1SDavid du Colombier 	register int i;
3353e12c5d1SDavid du Colombier 	register int (*sig)();
3363e12c5d1SDavid du Colombier 	if(1 || flag['d']){	/* wrong!!! */
3373e12c5d1SDavid du Colombier 		sig=signal(SIGINT, gettrap);
3383e12c5d1SDavid du Colombier 		if(sig==SIG_IGN) signal(SIGINT, SIG_IGN);
3393e12c5d1SDavid du Colombier 	}
3403e12c5d1SDavid du Colombier 	else{
3413e12c5d1SDavid du Colombier 		for(i=1;i<=NSIG;i++) if(i!=SIGCHLD){
3423e12c5d1SDavid du Colombier 			sig=signal(i, gettrap);
3433e12c5d1SDavid du Colombier 			if(sig==SIG_IGN) signal(i, SIG_IGN);
3443e12c5d1SDavid du Colombier 		}
3453e12c5d1SDavid du Colombier 	}
3463e12c5d1SDavid du Colombier }
3473e12c5d1SDavid du Colombier Unlink(name)
3483e12c5d1SDavid du Colombier char *name;
3493e12c5d1SDavid du Colombier {
3503e12c5d1SDavid du Colombier 	return unlink(name);
3513e12c5d1SDavid du Colombier }
3523e12c5d1SDavid du Colombier Write(fd, buf, cnt)
3533e12c5d1SDavid du Colombier char *buf;
3543e12c5d1SDavid du Colombier {
3553e12c5d1SDavid du Colombier 	return write(fd, buf, cnt);
3563e12c5d1SDavid du Colombier }
3573e12c5d1SDavid du Colombier Read(fd, buf, cnt)
3583e12c5d1SDavid du Colombier char *buf;
3593e12c5d1SDavid du Colombier {
3603e12c5d1SDavid du Colombier 	return read(fd, buf, cnt);
3613e12c5d1SDavid du Colombier }
3623e12c5d1SDavid du Colombier Seek(fd, cnt, whence)
3633e12c5d1SDavid du Colombier long cnt;
3643e12c5d1SDavid du Colombier {
3653e12c5d1SDavid du Colombier 	return lseek(fd, cnt, whence);
3663e12c5d1SDavid du Colombier }
3673e12c5d1SDavid du Colombier Executable(file)
3683e12c5d1SDavid du Colombier char *file;
3693e12c5d1SDavid du Colombier {
3703e12c5d1SDavid du Colombier 	return(access(file, 01)==0);
3713e12c5d1SDavid du Colombier }
3723e12c5d1SDavid du Colombier Creat(file)
3733e12c5d1SDavid du Colombier char *file;
3743e12c5d1SDavid du Colombier {
3753e12c5d1SDavid du Colombier 	return creat(file, 0666);
3763e12c5d1SDavid du Colombier }
3773e12c5d1SDavid du Colombier Dup(a, b){
3783e12c5d1SDavid du Colombier 	return dup2(a, b);
3793e12c5d1SDavid du Colombier }
3803e12c5d1SDavid du Colombier Dup1(a){
3813e12c5d1SDavid du Colombier 	return dup(a);
3823e12c5d1SDavid du Colombier }
3833e12c5d1SDavid du Colombier /*
3843e12c5d1SDavid du Colombier  * Wrong:  should go through components of a|b|c and return the maximum.
3853e12c5d1SDavid du Colombier  */
3863e12c5d1SDavid du Colombier Exit(stat)
3873e12c5d1SDavid du Colombier register char *stat;
3883e12c5d1SDavid du Colombier {
3893e12c5d1SDavid du Colombier 	register int n=0;
3903e12c5d1SDavid du Colombier 	while(*stat){
3913e12c5d1SDavid du Colombier 		if(*stat!='|'){
3923e12c5d1SDavid du Colombier 			if(*stat<'0' || '9'<*stat) exit(1);
3933e12c5d1SDavid du Colombier 			else n=n*10+*stat-'0';
3943e12c5d1SDavid du Colombier 		}
3953e12c5d1SDavid du Colombier 		stat++;
3963e12c5d1SDavid du Colombier 	}
3973e12c5d1SDavid du Colombier 	exit(n);
3983e12c5d1SDavid du Colombier }
3993e12c5d1SDavid du Colombier Eintr(){
4003e12c5d1SDavid du Colombier 	return errno==EINTR;
4013e12c5d1SDavid du Colombier }
4023e12c5d1SDavid du Colombier Noerror(){
4033e12c5d1SDavid du Colombier 	errno=0;
4043e12c5d1SDavid du Colombier }
4053e12c5d1SDavid du Colombier Isatty(fd){
4063e12c5d1SDavid du Colombier 	return isatty(fd);
4073e12c5d1SDavid du Colombier }
4083e12c5d1SDavid du Colombier Abort(){
4093e12c5d1SDavid du Colombier 	abort();
4103e12c5d1SDavid du Colombier }
4113e12c5d1SDavid du Colombier execumask(){		/* wrong -- should fork before writing */
4123e12c5d1SDavid du Colombier 	register int m;
4133e12c5d1SDavid du Colombier 	struct io out[1];
4143e12c5d1SDavid du Colombier 	switch(count(runq->argv->words)){
4153e12c5d1SDavid du Colombier 	default:
4163e12c5d1SDavid du Colombier 		pfmt(err, "Usage: umask [umask]\n");
4173e12c5d1SDavid du Colombier 		setstatus("umask usage");
4183e12c5d1SDavid du Colombier 		poplist();
4193e12c5d1SDavid du Colombier 		return;
4203e12c5d1SDavid du Colombier 	case 2: umask(octal(runq->argv->words->next->word)); break;
4213e12c5d1SDavid du Colombier 	case 1:
4223e12c5d1SDavid du Colombier 		umask(m=umask(0));
4233e12c5d1SDavid du Colombier 		out->fd=mapfd(1);
4243e12c5d1SDavid du Colombier 		out->bufp=out->buf;
4253e12c5d1SDavid du Colombier 		out->ebuf=&out->buf[NBUF];
4263e12c5d1SDavid du Colombier 		out->strp=0;
4273e12c5d1SDavid du Colombier 		pfmt(out, "%o\n", m);
4283e12c5d1SDavid du Colombier 		break;
4293e12c5d1SDavid du Colombier 	}
4303e12c5d1SDavid du Colombier 	setstatus("");
4313e12c5d1SDavid du Colombier 	poplist();
4323e12c5d1SDavid du Colombier }
4333e12c5d1SDavid du Colombier Memcpy(a, b, n)
4343e12c5d1SDavid du Colombier char *a, *b;
4353e12c5d1SDavid du Colombier {
4363e12c5d1SDavid du Colombier 	memmove(a, b, n);
4373e12c5d1SDavid du Colombier }
4383e12c5d1SDavid du Colombier void *Malloc(n){
4393e12c5d1SDavid du Colombier 	return (void *)malloc(n);
4403e12c5d1SDavid du Colombier }
441