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