xref: /plan9/sys/src/cmd/rc/unix.c (revision 1936bb650459bace06c38a45b60888b47e5cd459)
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"
7*1936bb65SDavid du Colombier #include "io.h"
83e12c5d1SDavid du Colombier #include "exec.h"
9*1936bb65SDavid du Colombier #include "getflags.h"
103e12c5d1SDavid du Colombier #include <errno.h>
11*1936bb65SDavid du Colombier 
123e12c5d1SDavid du Colombier char Rcmain[]="/usr/lib/rcmain";
133e12c5d1SDavid du Colombier char Fdprefix[]="/dev/fd/";
14*1936bb65SDavid du Colombier 
15*1936bb65SDavid du Colombier void execfinit(void);
16*1936bb65SDavid du Colombier 
173e12c5d1SDavid du Colombier struct builtin Builtin[] = {
183e12c5d1SDavid du Colombier 	"cd",		execcd,
193e12c5d1SDavid du Colombier 	"whatis",	execwhatis,
203e12c5d1SDavid du Colombier 	"eval",		execeval,
213e12c5d1SDavid du Colombier 	"exec",		execexec,	/* but with popword first */
223e12c5d1SDavid du Colombier 	"exit",		execexit,
233e12c5d1SDavid du Colombier 	"shift",	execshift,
243e12c5d1SDavid du Colombier 	"wait",		execwait,
253e12c5d1SDavid du Colombier 	"umask",	execumask,
263e12c5d1SDavid du Colombier 	".",		execdot,
273e12c5d1SDavid du Colombier 	"finit",	execfinit,
283e12c5d1SDavid du Colombier 	"flag",		execflag,
293e12c5d1SDavid du Colombier 	0
303e12c5d1SDavid du Colombier };
313e12c5d1SDavid du Colombier #define	SEP	'\1'
323e12c5d1SDavid du Colombier char **environp;
33dc5a79c1SDavid du Colombier 
34dc5a79c1SDavid du Colombier struct word*
35dc5a79c1SDavid du Colombier enval(s)
363e12c5d1SDavid du Colombier register char *s;
373e12c5d1SDavid du Colombier {
38dc5a79c1SDavid du Colombier 	char *t, c;
39dc5a79c1SDavid du Colombier 	struct word *v;
403e12c5d1SDavid du Colombier 	for(t = s;*t && *t!=SEP;t++);
413e12c5d1SDavid du Colombier 	c=*t;
423e12c5d1SDavid du Colombier 	*t='\0';
433e12c5d1SDavid du Colombier 	v = newword(s, c=='\0'?(struct word *)0:enval(t+1));
443e12c5d1SDavid du Colombier 	*t = c;
453e12c5d1SDavid du Colombier 	return v;
463e12c5d1SDavid du Colombier }
47*1936bb65SDavid du Colombier 
48*1936bb65SDavid du Colombier void
49*1936bb65SDavid du Colombier Vinit(void)
50*1936bb65SDavid du Colombier {
513e12c5d1SDavid du Colombier 	extern char **environ;
52dc5a79c1SDavid du Colombier 	char *s;
53dc5a79c1SDavid du Colombier 	char **env = environ;
543e12c5d1SDavid du Colombier 	environp = env;
553e12c5d1SDavid du Colombier 	for(;*env;env++){
563e12c5d1SDavid du Colombier 		for(s=*env;*s && *s!='(' && *s!='=';s++);
573e12c5d1SDavid du Colombier 		switch(*s){
583e12c5d1SDavid du Colombier 		case '\0':
593e12c5d1SDavid du Colombier 			pfmt(err, "environment %q?\n", *env);
603e12c5d1SDavid du Colombier 			break;
613e12c5d1SDavid du Colombier 		case '=':
623e12c5d1SDavid du Colombier 			*s='\0';
633e12c5d1SDavid du Colombier 			setvar(*env, enval(s+1));
643e12c5d1SDavid du Colombier 			*s='=';
653e12c5d1SDavid du Colombier 			break;
663e12c5d1SDavid du Colombier 		case '(':	/* ignore functions for now */
673e12c5d1SDavid du Colombier 			break;
683e12c5d1SDavid du Colombier 		}
693e12c5d1SDavid du Colombier 	}
703e12c5d1SDavid du Colombier }
71*1936bb65SDavid du Colombier 
723e12c5d1SDavid du Colombier char **envp;
73*1936bb65SDavid du Colombier 
74*1936bb65SDavid du Colombier void
75*1936bb65SDavid du Colombier Xrdfn(void)
76*1936bb65SDavid du Colombier {
77dc5a79c1SDavid du Colombier 	char *s;
78dc5a79c1SDavid du Colombier 	int len;
793e12c5d1SDavid du Colombier 	for(;*envp;envp++){
803e12c5d1SDavid du Colombier 		for(s=*envp;*s && *s!='(' && *s!='=';s++);
813e12c5d1SDavid du Colombier 		switch(*s){
823e12c5d1SDavid du Colombier 		case '\0':
833e12c5d1SDavid du Colombier 			pfmt(err, "environment %q?\n", *envp);
843e12c5d1SDavid du Colombier 			break;
853e12c5d1SDavid du Colombier 		case '=':	/* ignore variables */
863e12c5d1SDavid du Colombier 			break;
873e12c5d1SDavid du Colombier 		case '(':		/* Bourne again */
883e12c5d1SDavid du Colombier 			s=*envp+3;
893e12c5d1SDavid du Colombier 			envp++;
903e12c5d1SDavid du Colombier 			len = strlen(s);
913e12c5d1SDavid du Colombier 			s[len]='\n';
923e12c5d1SDavid du Colombier 			execcmds(opencore(s, len+1));
933e12c5d1SDavid du Colombier 			s[len]='\0';
943e12c5d1SDavid du Colombier 			return;
953e12c5d1SDavid du Colombier 		}
963e12c5d1SDavid du Colombier 	}
973e12c5d1SDavid du Colombier 	Xreturn();
983e12c5d1SDavid du Colombier }
99*1936bb65SDavid du Colombier 
1003e12c5d1SDavid du Colombier union code rdfns[4];
101*1936bb65SDavid du Colombier 
102*1936bb65SDavid du Colombier void
103*1936bb65SDavid du Colombier execfinit(void)
104*1936bb65SDavid du Colombier {
1053e12c5d1SDavid du Colombier 	static int first = 1;
1063e12c5d1SDavid du Colombier 	if(first){
1073e12c5d1SDavid du Colombier 		rdfns[0].i = 1;
1083e12c5d1SDavid du Colombier 		rdfns[1].f = Xrdfn;
1093e12c5d1SDavid du Colombier 		rdfns[2].f = Xjump;
1103e12c5d1SDavid du Colombier 		rdfns[3].i = 1;
1113e12c5d1SDavid du Colombier 		first = 0;
1123e12c5d1SDavid du Colombier 	}
1133e12c5d1SDavid du Colombier 	Xpopm();
1143e12c5d1SDavid du Colombier 	envp = environp;
1153e12c5d1SDavid du Colombier 	start(rdfns, 1, runq->local);
1163e12c5d1SDavid du Colombier }
117*1936bb65SDavid du Colombier 
118*1936bb65SDavid du Colombier int
119*1936bb65SDavid du Colombier cmpenv(const void *aa, const void *ab)
1203e12c5d1SDavid du Colombier {
121*1936bb65SDavid du Colombier 	char **a = aa, **b = ab;
122*1936bb65SDavid du Colombier 
1233e12c5d1SDavid du Colombier 	return strcmp(*a, *b);
1243e12c5d1SDavid du Colombier }
125dc5a79c1SDavid du Colombier 
126*1936bb65SDavid du Colombier char **
127*1936bb65SDavid du Colombier mkenv(void)
128dc5a79c1SDavid du Colombier {
129dc5a79c1SDavid du Colombier 	char **env, **ep, *p, *q;
130dc5a79c1SDavid du Colombier 	struct var **h, *v;
131dc5a79c1SDavid du Colombier 	struct word *a;
132dc5a79c1SDavid du Colombier 	int nvar = 0, nchr = 0, sep;
133*1936bb65SDavid du Colombier 
1343e12c5d1SDavid du Colombier 	/*
135*1936bb65SDavid du Colombier 	 * Slightly kludgy loops look at locals then globals.
136*1936bb65SDavid du Colombier 	 * locals no longer exist - geoff
1373e12c5d1SDavid du Colombier 	 */
138*1936bb65SDavid du Colombier 	for(h = gvar-1; h != &gvar[NVAR]; h++)
139*1936bb65SDavid du Colombier 	for(v = h >= gvar? *h: runq->local; v ;v = v->next){
1403e12c5d1SDavid du Colombier 		if((v==vlook(v->name)) && v->val){
1413e12c5d1SDavid du Colombier 			nvar++;
1423e12c5d1SDavid du Colombier 			nchr+=strlen(v->name)+1;
1433e12c5d1SDavid du Colombier 			for(a = v->val;a;a = a->next)
1443e12c5d1SDavid du Colombier 				nchr+=strlen(a->word)+1;
1453e12c5d1SDavid du Colombier 		}
1463e12c5d1SDavid du Colombier 		if(v->fn){
1473e12c5d1SDavid du Colombier 			nvar++;
1483e12c5d1SDavid du Colombier 			nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8;
1493e12c5d1SDavid du Colombier 		}
1503e12c5d1SDavid du Colombier 	}
1513e12c5d1SDavid du Colombier 	env = (char **)emalloc((nvar+1)*sizeof(char *)+nchr);
1523e12c5d1SDavid du Colombier 	ep = env;
1533e12c5d1SDavid du Colombier 	p = (char *)&env[nvar+1];
154*1936bb65SDavid du Colombier 	for(h = gvar-1; h != &gvar[NVAR]; h++)
155*1936bb65SDavid du Colombier 	for(v = h >= gvar? *h: runq->local;v;v = v->next){
1563e12c5d1SDavid du Colombier 		if((v==vlook(v->name)) && v->val){
1573e12c5d1SDavid du Colombier 			*ep++=p;
1583e12c5d1SDavid du Colombier 			q = v->name;
1593e12c5d1SDavid du Colombier 			while(*q) *p++=*q++;
1603e12c5d1SDavid du Colombier 			sep='=';
1613e12c5d1SDavid du Colombier 			for(a = v->val;a;a = a->next){
1623e12c5d1SDavid du Colombier 				*p++=sep;
1633e12c5d1SDavid du Colombier 				sep = SEP;
1643e12c5d1SDavid du Colombier 				q = a->word;
1653e12c5d1SDavid du Colombier 				while(*q) *p++=*q++;
1663e12c5d1SDavid du Colombier 			}
1673e12c5d1SDavid du Colombier 			*p++='\0';
1683e12c5d1SDavid du Colombier 		}
1693e12c5d1SDavid du Colombier 		if(v->fn){
1703e12c5d1SDavid du Colombier 			*ep++=p;
1713e12c5d1SDavid du Colombier 			*p++='#'; *p++='('; *p++=')';	/* to fool Bourne */
1723e12c5d1SDavid du Colombier 			*p++='f'; *p++='n'; *p++=' ';
1733e12c5d1SDavid du Colombier 			q = v->name;
1743e12c5d1SDavid du Colombier 			while(*q) *p++=*q++;
1753e12c5d1SDavid du Colombier 			*p++=' ';
1763e12c5d1SDavid du Colombier 			q = v->fn[v->pc-1].s;
1773e12c5d1SDavid du Colombier 			while(*q) *p++=*q++;
1783e12c5d1SDavid du Colombier 			*p++='\0';
1793e12c5d1SDavid du Colombier 		}
1803e12c5d1SDavid du Colombier 	}
1813e12c5d1SDavid du Colombier 	*ep = 0;
182*1936bb65SDavid du Colombier 	qsort((void *)env, nvar, sizeof ep[0], cmpenv);
1833e12c5d1SDavid du Colombier 	return env;
1843e12c5d1SDavid du Colombier }
1853e12c5d1SDavid du Colombier char *sigmsg[] = {
1863e12c5d1SDavid du Colombier /*  0 normal  */ 0,
1873e12c5d1SDavid du Colombier /*  1 SIGHUP  */ "Hangup",
1883e12c5d1SDavid du Colombier /*  2 SIGINT  */ 0,
1893e12c5d1SDavid du Colombier /*  3 SIGQUIT */ "Quit",
1903e12c5d1SDavid du Colombier /*  4 SIGILL  */ "Illegal instruction",
1913e12c5d1SDavid du Colombier /*  5 SIGTRAP */ "Trace/BPT trap",
1923e12c5d1SDavid du Colombier /*  6 SIGIOT  */ "abort",
1933e12c5d1SDavid du Colombier /*  7 SIGEMT  */ "EMT trap",
1943e12c5d1SDavid du Colombier /*  8 SIGFPE  */ "Floating exception",
1953e12c5d1SDavid du Colombier /*  9 SIGKILL */ "Killed",
1963e12c5d1SDavid du Colombier /* 10 SIGBUS  */ "Bus error",
1973e12c5d1SDavid du Colombier /* 11 SIGSEGV */ "Memory fault",
1983e12c5d1SDavid du Colombier /* 12 SIGSYS  */ "Bad system call",
1993e12c5d1SDavid du Colombier /* 13 SIGPIPE */ 0,
2003e12c5d1SDavid du Colombier /* 14 SIGALRM */ "Alarm call",
2013e12c5d1SDavid du Colombier /* 15 SIGTERM */ "Terminated",
2023e12c5d1SDavid du Colombier /* 16 unused  */ "signal 16",
2033e12c5d1SDavid du Colombier /* 17 SIGSTOP */ "Process stopped",
2043e12c5d1SDavid du Colombier /* 18 unused  */ "signal 18",
2053e12c5d1SDavid du Colombier /* 19 SIGCONT */ "Process continued",
2063e12c5d1SDavid du Colombier /* 20 SIGCHLD */ "Child death",
2073e12c5d1SDavid du Colombier };
208*1936bb65SDavid du Colombier 
209*1936bb65SDavid du Colombier void
210*1936bb65SDavid du Colombier Waitfor(int pid, int persist)
211*1936bb65SDavid du Colombier {
212dc5a79c1SDavid du Colombier 	int wpid, sig;
213dc5a79c1SDavid du Colombier 	struct thread *p;
2143e12c5d1SDavid du Colombier 	int wstat;
2153e12c5d1SDavid du Colombier 	char wstatstr[12];
216*1936bb65SDavid du Colombier 
2173e12c5d1SDavid du Colombier 	for(;;){
2183e12c5d1SDavid du Colombier 		errno = 0;
2193e12c5d1SDavid du Colombier 		wpid = wait(&wstat);
220dc5a79c1SDavid du Colombier 		if(errno==EINTR && persist)
221dc5a79c1SDavid du Colombier 			continue;
222dc5a79c1SDavid du Colombier 		if(wpid==-1)
223dc5a79c1SDavid du Colombier 			break;
2243e12c5d1SDavid du Colombier 		sig = wstat&0177;
2253e12c5d1SDavid du Colombier 		if(sig==0177){
2263e12c5d1SDavid du Colombier 			pfmt(err, "trace: ");
2273e12c5d1SDavid du Colombier 			sig = (wstat>>8)&0177;
2283e12c5d1SDavid du Colombier 		}
2293e12c5d1SDavid du Colombier 		if(sig>(sizeof sigmsg/sizeof sigmsg[0]) || sigmsg[sig]){
230dc5a79c1SDavid du Colombier 			if(pid!=wpid)
231dc5a79c1SDavid du Colombier 				pfmt(err, "%d: ", wpid);
2323e12c5d1SDavid du Colombier 			if(sig<=(sizeof sigmsg/sizeof sigmsg[0]))
2333e12c5d1SDavid du Colombier 				pfmt(err, "%s", sigmsg[sig]);
2343e12c5d1SDavid du Colombier 			else if(sig==0177) pfmt(err, "stopped by ptrace");
2353e12c5d1SDavid du Colombier 			else pfmt(err, "signal %d", sig);
2363e12c5d1SDavid du Colombier 			if(wstat&0200)pfmt(err, " -- core dumped");
2373e12c5d1SDavid du Colombier 			pfmt(err, "\n");
2383e12c5d1SDavid du Colombier 		}
2393e12c5d1SDavid du Colombier 		wstat = sig?sig+1000:(wstat>>8)&0xFF;
2403e12c5d1SDavid du Colombier 		if(wpid==pid){
241dc5a79c1SDavid du Colombier 			inttoascii(wstatstr, wstat);
2423e12c5d1SDavid du Colombier 			setstatus(wstatstr);
2433e12c5d1SDavid du Colombier 			break;
2443e12c5d1SDavid du Colombier 		}
2453e12c5d1SDavid du Colombier 		else{
2463e12c5d1SDavid du Colombier 			for(p = runq->ret;p;p = p->ret)
2473e12c5d1SDavid du Colombier 				if(p->pid==wpid){
2483e12c5d1SDavid du Colombier 					p->pid=-1;
249dc5a79c1SDavid du Colombier 					inttoascii(p->status, wstat);
2503e12c5d1SDavid du Colombier 					break;
2513e12c5d1SDavid du Colombier 				}
2523e12c5d1SDavid du Colombier 		}
2533e12c5d1SDavid du Colombier 	}
2543e12c5d1SDavid du Colombier }
255dc5a79c1SDavid du Colombier 
256*1936bb65SDavid du Colombier char **
257*1936bb65SDavid du Colombier mkargv(a)
2583e12c5d1SDavid du Colombier register struct word *a;
2593e12c5d1SDavid du Colombier {
2603e12c5d1SDavid du Colombier 	char **argv = (char **)emalloc((count(a)+2)*sizeof(char *));
261dc5a79c1SDavid du Colombier 	char **argp = argv+1;	/* leave one at front for runcoms */
262*1936bb65SDavid du Colombier 
263*1936bb65SDavid du Colombier 	for(;a;a = a->next)
264*1936bb65SDavid du Colombier 		*argp++=a->word;
2653e12c5d1SDavid du Colombier 	*argp = 0;
2663e12c5d1SDavid du Colombier 	return argv;
2673e12c5d1SDavid du Colombier }
268*1936bb65SDavid du Colombier 
269*1936bb65SDavid du Colombier void
270*1936bb65SDavid du Colombier Updenv(void)
271*1936bb65SDavid du Colombier {
272*1936bb65SDavid du Colombier }
273*1936bb65SDavid du Colombier 
274*1936bb65SDavid du Colombier void
275*1936bb65SDavid du Colombier Execute(struct word *args, struct word *path)
2763e12c5d1SDavid du Colombier {
277dc5a79c1SDavid du Colombier 	char *msg="not found";
278dc5a79c1SDavid du Colombier 	int txtbusy = 0;
2793e12c5d1SDavid du Colombier 	char **env = mkenv();
2803e12c5d1SDavid du Colombier 	char **argv = mkargv(args);
2813e12c5d1SDavid du Colombier 	char file[512];
282*1936bb65SDavid du Colombier 
2833e12c5d1SDavid du Colombier 	for(;path;path = path->next){
2843e12c5d1SDavid du Colombier 		strcpy(file, path->word);
285dc5a79c1SDavid du Colombier 		if(file[0])
286dc5a79c1SDavid du Colombier 			strcat(file, "/");
2873e12c5d1SDavid du Colombier 		strcat(file, argv[1]);
2883e12c5d1SDavid du Colombier ReExec:
2893e12c5d1SDavid du Colombier 		execve(file, argv+1, env);
2903e12c5d1SDavid du Colombier 		switch(errno){
2913e12c5d1SDavid du Colombier 		case ENOEXEC:
2923e12c5d1SDavid du Colombier 			pfmt(err, "%s: Bourne again\n", argv[1]);
2933e12c5d1SDavid du Colombier 			argv[0]="sh";
2943e12c5d1SDavid du Colombier 			argv[1] = strdup(file);
2953e12c5d1SDavid du Colombier 			execve("/bin/sh", argv, env);
2963e12c5d1SDavid du Colombier 			goto Bad;
2973e12c5d1SDavid du Colombier 		case ETXTBSY:
2983e12c5d1SDavid du Colombier 			if(++txtbusy!=5){
2993e12c5d1SDavid du Colombier 				sleep(txtbusy);
3003e12c5d1SDavid du Colombier 				goto ReExec;
3013e12c5d1SDavid du Colombier 			}
3023e12c5d1SDavid du Colombier 			msg="text busy"; goto Bad;
303dc5a79c1SDavid du Colombier 		case EACCES:
304dc5a79c1SDavid du Colombier 			msg="no access";
305dc5a79c1SDavid du Colombier 			break;
306dc5a79c1SDavid du Colombier 		case ENOMEM:
307dc5a79c1SDavid du Colombier 			msg="not enough memory"; goto Bad;
308dc5a79c1SDavid du Colombier 		case E2BIG:
309dc5a79c1SDavid du Colombier 			msg="too big"; goto Bad;
3103e12c5d1SDavid du Colombier 		}
3113e12c5d1SDavid du Colombier 	}
3123e12c5d1SDavid du Colombier Bad:
3133e12c5d1SDavid du Colombier 	pfmt(err, "%s: %s\n", argv[1], msg);
3143e12c5d1SDavid du Colombier 	efree((char *)env);
3153e12c5d1SDavid du Colombier 	efree((char *)argv);
3163e12c5d1SDavid du Colombier }
317*1936bb65SDavid du Colombier 
3183e12c5d1SDavid du Colombier #define	NDIR	14		/* should get this from param.h */
319*1936bb65SDavid du Colombier 
3203e12c5d1SDavid du Colombier Globsize(p)
3213e12c5d1SDavid du Colombier register char *p;
3223e12c5d1SDavid du Colombier {
3233e12c5d1SDavid du Colombier 	int isglob = 0, globlen = NDIR+1;
3243e12c5d1SDavid du Colombier 	for(;*p;p++){
3253e12c5d1SDavid du Colombier 		if(*p==GLOB){
3263e12c5d1SDavid du Colombier 			p++;
327dc5a79c1SDavid du Colombier 			if(*p!=GLOB)
328dc5a79c1SDavid du Colombier 				isglob++;
3293e12c5d1SDavid du Colombier 			globlen+=*p=='*'?NDIR:1;
3303e12c5d1SDavid du Colombier 		}
3313e12c5d1SDavid du Colombier 		else
3323e12c5d1SDavid du Colombier 			globlen++;
3333e12c5d1SDavid du Colombier 	}
3343e12c5d1SDavid du Colombier 	return isglob?globlen:0;
3353e12c5d1SDavid du Colombier }
336*1936bb65SDavid du Colombier 
3373e12c5d1SDavid du Colombier #include <sys/types.h>
338*1936bb65SDavid du Colombier #include <dirent.h>
339*1936bb65SDavid du Colombier 
3403e12c5d1SDavid du Colombier #define	NDIRLIST	50
341*1936bb65SDavid du Colombier 
3423e12c5d1SDavid du Colombier DIR *dirlist[NDIRLIST];
343*1936bb65SDavid du Colombier 
3443e12c5d1SDavid du Colombier Opendir(name)
3453e12c5d1SDavid du Colombier char *name;
3463e12c5d1SDavid du Colombier {
347dc5a79c1SDavid du Colombier 	DIR **dp;
3483e12c5d1SDavid du Colombier 	for(dp = dirlist;dp!=&dirlist[NDIRLIST];dp++)
3493e12c5d1SDavid du Colombier 		if(*dp==0){
3503e12c5d1SDavid du Colombier 			*dp = opendir(name);
3513e12c5d1SDavid du Colombier 			return *dp?dp-dirlist:-1;
3523e12c5d1SDavid du Colombier 		}
3533e12c5d1SDavid du Colombier 	return -1;
3543e12c5d1SDavid du Colombier }
355*1936bb65SDavid du Colombier 
356*1936bb65SDavid du Colombier int
357*1936bb65SDavid du Colombier Readdir(int f, char *p, int onlydirs)
3583e12c5d1SDavid du Colombier {
359*1936bb65SDavid du Colombier 	struct dirent *dp = readdir(dirlist[f]);
360*1936bb65SDavid du Colombier 
361dc5a79c1SDavid du Colombier 	if(dp==0)
362dc5a79c1SDavid du Colombier 		return 0;
3633e12c5d1SDavid du Colombier 	strcpy(p, dp->d_name);
3643e12c5d1SDavid du Colombier 	return 1;
3653e12c5d1SDavid du Colombier }
366*1936bb65SDavid du Colombier 
367*1936bb65SDavid du Colombier void
368*1936bb65SDavid du Colombier Closedir(int f)
369*1936bb65SDavid du Colombier {
3703e12c5d1SDavid du Colombier 	closedir(dirlist[f]);
3713e12c5d1SDavid du Colombier 	dirlist[f] = 0;
3723e12c5d1SDavid du Colombier }
373*1936bb65SDavid du Colombier 
3743e12c5d1SDavid du Colombier char *Signame[] = {
3753e12c5d1SDavid du Colombier 	"sigexit",	"sighup",	"sigint",	"sigquit",
3763e12c5d1SDavid du Colombier 	"sigill",	"sigtrap",	"sigiot",	"sigemt",
3773e12c5d1SDavid du Colombier 	"sigfpe",	"sigkill",	"sigbus",	"sigsegv",
3783e12c5d1SDavid du Colombier 	"sigsys",	"sigpipe",	"sigalrm",	"sigterm",
3793e12c5d1SDavid du Colombier 	"sig16",	"sigstop",	"sigtstp",	"sigcont",
3803e12c5d1SDavid du Colombier 	"sigchld",	"sigttin",	"sigttou",	"sigtint",
3813e12c5d1SDavid du Colombier 	"sigxcpu",	"sigxfsz",	"sig26",	"sig27",
3823e12c5d1SDavid du Colombier 	"sig28",	"sig29",	"sig30",	"sig31",
3833e12c5d1SDavid du Colombier 	0,
3843e12c5d1SDavid du Colombier };
385dc5a79c1SDavid du Colombier 
386*1936bb65SDavid du Colombier void
387*1936bb65SDavid du Colombier gettrap(int sig)
388dc5a79c1SDavid du Colombier {
3893e12c5d1SDavid du Colombier 	signal(sig, gettrap);
3903e12c5d1SDavid du Colombier 	trap[sig]++;
3913e12c5d1SDavid du Colombier 	ntrap++;
3923e12c5d1SDavid du Colombier 	if(ntrap>=NSIG){
3933e12c5d1SDavid du Colombier 		pfmt(err, "rc: Too many traps (trap %d), dumping core\n", sig);
394*1936bb65SDavid du Colombier 		signal(SIGABRT, (void (*)())0);
395*1936bb65SDavid du Colombier 		kill(getpid(), SIGABRT);
3963e12c5d1SDavid du Colombier 	}
3973e12c5d1SDavid du Colombier }
398*1936bb65SDavid du Colombier 
399*1936bb65SDavid du Colombier void
400*1936bb65SDavid du Colombier Trapinit(void)
401*1936bb65SDavid du Colombier {
402dc5a79c1SDavid du Colombier 	int i;
403*1936bb65SDavid du Colombier 	void (*sig)();
404*1936bb65SDavid du Colombier 
4053e12c5d1SDavid du Colombier 	if(1 || flag['d']){	/* wrong!!! */
4063e12c5d1SDavid du Colombier 		sig = signal(SIGINT, gettrap);
407dc5a79c1SDavid du Colombier 		if(sig==SIG_IGN)
408dc5a79c1SDavid du Colombier 			signal(SIGINT, SIG_IGN);
4093e12c5d1SDavid du Colombier 	}
4103e12c5d1SDavid du Colombier 	else{
4113e12c5d1SDavid du Colombier 		for(i = 1;i<=NSIG;i++) if(i!=SIGCHLD){
4123e12c5d1SDavid du Colombier 			sig = signal(i, gettrap);
413dc5a79c1SDavid du Colombier 			if(sig==SIG_IGN)
414dc5a79c1SDavid du Colombier 				signal(i, SIG_IGN);
4153e12c5d1SDavid du Colombier 		}
4163e12c5d1SDavid du Colombier 	}
4173e12c5d1SDavid du Colombier }
418*1936bb65SDavid du Colombier 
4193e12c5d1SDavid du Colombier Unlink(name)
4203e12c5d1SDavid du Colombier char *name;
4213e12c5d1SDavid du Colombier {
4223e12c5d1SDavid du Colombier 	return unlink(name);
4233e12c5d1SDavid du Colombier }
4243e12c5d1SDavid du Colombier Write(fd, buf, cnt)
425*1936bb65SDavid du Colombier char *buf;
4263e12c5d1SDavid du Colombier {
4273e12c5d1SDavid du Colombier 	return write(fd, buf, cnt);
4283e12c5d1SDavid du Colombier }
4293e12c5d1SDavid du Colombier Read(fd, buf, cnt)
430*1936bb65SDavid du Colombier char *buf;
4313e12c5d1SDavid du Colombier {
4323e12c5d1SDavid du Colombier 	return read(fd, buf, cnt);
4333e12c5d1SDavid du Colombier }
4343e12c5d1SDavid du Colombier Seek(fd, cnt, whence)
4353e12c5d1SDavid du Colombier long cnt;
4363e12c5d1SDavid du Colombier {
4373e12c5d1SDavid du Colombier 	return lseek(fd, cnt, whence);
4383e12c5d1SDavid du Colombier }
4393e12c5d1SDavid du Colombier Executable(file)
4403e12c5d1SDavid du Colombier char *file;
4413e12c5d1SDavid du Colombier {
4423e12c5d1SDavid du Colombier 	return(access(file, 01)==0);
4433e12c5d1SDavid du Colombier }
4443e12c5d1SDavid du Colombier Creat(file)
4453e12c5d1SDavid du Colombier char *file;
4463e12c5d1SDavid du Colombier {
4473e12c5d1SDavid du Colombier 	return creat(file, 0666);
4483e12c5d1SDavid du Colombier }
4493e12c5d1SDavid du Colombier Dup(a, b){
4503e12c5d1SDavid du Colombier 	return dup2(a, b);
4513e12c5d1SDavid du Colombier }
4523e12c5d1SDavid du Colombier Dup1(a){
4533e12c5d1SDavid du Colombier 	return dup(a);
4543e12c5d1SDavid du Colombier }
4553e12c5d1SDavid du Colombier /*
4563e12c5d1SDavid du Colombier  * Wrong:  should go through components of a|b|c and return the maximum.
4573e12c5d1SDavid du Colombier  */
458*1936bb65SDavid du Colombier void
459*1936bb65SDavid du Colombier Exit(char *stat)
4603e12c5d1SDavid du Colombier {
461dc5a79c1SDavid du Colombier 	int n = 0;
462*1936bb65SDavid du Colombier 
4633e12c5d1SDavid du Colombier 	while(*stat){
4643e12c5d1SDavid du Colombier 		if(*stat!='|'){
465dc5a79c1SDavid du Colombier 			if(*stat<'0' || '9'<*stat)
466dc5a79c1SDavid du Colombier 				exit(1);
4673e12c5d1SDavid du Colombier 			else n = n*10+*stat-'0';
4683e12c5d1SDavid du Colombier 		}
4693e12c5d1SDavid du Colombier 		stat++;
4703e12c5d1SDavid du Colombier 	}
4713e12c5d1SDavid du Colombier 	exit(n);
4723e12c5d1SDavid du Colombier }
4733e12c5d1SDavid du Colombier Eintr(){
4743e12c5d1SDavid du Colombier 	return errno==EINTR;
4753e12c5d1SDavid du Colombier }
476*1936bb65SDavid du Colombier 
477*1936bb65SDavid du Colombier void
478*1936bb65SDavid du Colombier Noerror()
479*1936bb65SDavid du Colombier {
4803e12c5d1SDavid du Colombier 	errno = 0;
4813e12c5d1SDavid du Colombier }
4823e12c5d1SDavid du Colombier Isatty(fd){
4833e12c5d1SDavid du Colombier 	return isatty(fd);
4843e12c5d1SDavid du Colombier }
485*1936bb65SDavid du Colombier 
486*1936bb65SDavid du Colombier void
487*1936bb65SDavid du Colombier Abort()
488*1936bb65SDavid du Colombier {
4893e12c5d1SDavid du Colombier 	abort();
4903e12c5d1SDavid du Colombier }
491*1936bb65SDavid du Colombier 
492*1936bb65SDavid du Colombier void
493*1936bb65SDavid du Colombier execumask(void)		/* wrong -- should fork before writing */
494*1936bb65SDavid du Colombier {
495dc5a79c1SDavid du Colombier 	int m;
4963e12c5d1SDavid du Colombier 	struct io out[1];
4973e12c5d1SDavid du Colombier 	switch(count(runq->argv->words)){
4983e12c5d1SDavid du Colombier 	default:
4993e12c5d1SDavid du Colombier 		pfmt(err, "Usage: umask [umask]\n");
5003e12c5d1SDavid du Colombier 		setstatus("umask usage");
5013e12c5d1SDavid du Colombier 		poplist();
5023e12c5d1SDavid du Colombier 		return;
503dc5a79c1SDavid du Colombier 	case 2:
504dc5a79c1SDavid du Colombier 		umask(octal(runq->argv->words->next->word));
505dc5a79c1SDavid du Colombier 		break;
5063e12c5d1SDavid du Colombier 	case 1:
5073e12c5d1SDavid du Colombier 		umask(m = umask(0));
5083e12c5d1SDavid du Colombier 		out->fd = mapfd(1);
5093e12c5d1SDavid du Colombier 		out->bufp = out->buf;
5103e12c5d1SDavid du Colombier 		out->ebuf=&out->buf[NBUF];
5113e12c5d1SDavid du Colombier 		out->strp = 0;
5123e12c5d1SDavid du Colombier 		pfmt(out, "%o\n", m);
5133e12c5d1SDavid du Colombier 		break;
5143e12c5d1SDavid du Colombier 	}
5153e12c5d1SDavid du Colombier 	setstatus("");
5163e12c5d1SDavid du Colombier 	poplist();
5173e12c5d1SDavid du Colombier }
518*1936bb65SDavid du Colombier 
519*1936bb65SDavid du Colombier void
5203e12c5d1SDavid du Colombier Memcpy(a, b, n)
521*1936bb65SDavid du Colombier char *a, *b;
5223e12c5d1SDavid du Colombier {
5233e12c5d1SDavid du Colombier 	memmove(a, b, n);
5243e12c5d1SDavid du Colombier }
525dc5a79c1SDavid du Colombier 
526dc5a79c1SDavid du Colombier void*
527*1936bb65SDavid du Colombier Malloc(unsigned long n)
528dc5a79c1SDavid du Colombier {
5293e12c5d1SDavid du Colombier 	return (void *)malloc(n);
5303e12c5d1SDavid du Colombier }
531*1936bb65SDavid du Colombier 
532*1936bb65SDavid du Colombier void
533*1936bb65SDavid du Colombier errstr(char *buf, int len)
534*1936bb65SDavid du Colombier {
535*1936bb65SDavid du Colombier 	strncpy(buf, strerror(errno), len);
536*1936bb65SDavid du Colombier }
537*1936bb65SDavid du Colombier 
538*1936bb65SDavid du Colombier int
539*1936bb65SDavid du Colombier needsrcquote(int c)
540*1936bb65SDavid du Colombier {
541*1936bb65SDavid du Colombier 	if(c <= ' ')
542*1936bb65SDavid du Colombier 		return 1;
543*1936bb65SDavid du Colombier 	if(strchr("`^#*[]=|\\?${}()'<>&;", c))
544*1936bb65SDavid du Colombier 		return 1;
545*1936bb65SDavid du Colombier 	return 0;
546*1936bb65SDavid du Colombier }
547