xref: /plan9/sys/src/cmd/rc/unix.c (revision bad30d5d5a5510556b3d04cddb2a7590f26fb546)
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"
71936bb65SDavid du Colombier #include "io.h"
83e12c5d1SDavid du Colombier #include "exec.h"
91936bb65SDavid du Colombier #include "getflags.h"
103e12c5d1SDavid du Colombier #include <errno.h>
111936bb65SDavid du Colombier 
12*bad30d5dSDavid du Colombier char *Rcmain = "/usr/lib/rcmain";
13*bad30d5dSDavid du Colombier char *Fdprefix = "/dev/fd/";
141936bb65SDavid du Colombier 
151936bb65SDavid du Colombier void execfinit(void);
161936bb65SDavid 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*
enval(s)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 }
471936bb65SDavid du Colombier 
481936bb65SDavid du Colombier void
Vinit(void)491936bb65SDavid du Colombier Vinit(void)
501936bb65SDavid 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 }
711936bb65SDavid du Colombier 
723e12c5d1SDavid du Colombier char **envp;
731936bb65SDavid du Colombier 
741936bb65SDavid du Colombier void
Xrdfn(void)751936bb65SDavid du Colombier Xrdfn(void)
761936bb65SDavid 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 }
991936bb65SDavid du Colombier 
1003e12c5d1SDavid du Colombier union code rdfns[4];
1011936bb65SDavid du Colombier 
1021936bb65SDavid du Colombier void
execfinit(void)1031936bb65SDavid du Colombier execfinit(void)
1041936bb65SDavid 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 }
1171936bb65SDavid du Colombier 
1181936bb65SDavid du Colombier int
cmpenv(const void * aa,const void * ab)1191936bb65SDavid du Colombier cmpenv(const void *aa, const void *ab)
1203e12c5d1SDavid du Colombier {
1211936bb65SDavid du Colombier 	char **a = aa, **b = ab;
1221936bb65SDavid du Colombier 
1233e12c5d1SDavid du Colombier 	return strcmp(*a, *b);
1243e12c5d1SDavid du Colombier }
125dc5a79c1SDavid du Colombier 
1261936bb65SDavid du Colombier char **
mkenv(void)1271936bb65SDavid 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;
1331936bb65SDavid du Colombier 
1343e12c5d1SDavid du Colombier 	/*
1351936bb65SDavid du Colombier 	 * Slightly kludgy loops look at locals then globals.
1361936bb65SDavid du Colombier 	 * locals no longer exist - geoff
1373e12c5d1SDavid du Colombier 	 */
1381936bb65SDavid du Colombier 	for(h = gvar-1; h != &gvar[NVAR]; h++)
1391936bb65SDavid 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];
1541936bb65SDavid du Colombier 	for(h = gvar-1; h != &gvar[NVAR]; h++)
1551936bb65SDavid 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;
1821936bb65SDavid 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 };
2081936bb65SDavid du Colombier 
2091936bb65SDavid du Colombier void
Waitfor(int pid,int persist)2101936bb65SDavid du Colombier Waitfor(int pid, int persist)
2111936bb65SDavid 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];
2161936bb65SDavid 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 
2561936bb65SDavid du Colombier char **
mkargv(a)2571936bb65SDavid 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 */
2621936bb65SDavid du Colombier 
2631936bb65SDavid du Colombier 	for(;a;a = a->next)
2641936bb65SDavid du Colombier 		*argp++=a->word;
2653e12c5d1SDavid du Colombier 	*argp = 0;
2663e12c5d1SDavid du Colombier 	return argv;
2673e12c5d1SDavid du Colombier }
2681936bb65SDavid du Colombier 
2691936bb65SDavid du Colombier void
Updenv(void)2701936bb65SDavid du Colombier Updenv(void)
2711936bb65SDavid du Colombier {
2721936bb65SDavid du Colombier }
2731936bb65SDavid du Colombier 
2741936bb65SDavid du Colombier void
Execute(struct word * args,struct word * path)2751936bb65SDavid 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];
2821936bb65SDavid 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 }
3171936bb65SDavid du Colombier 
3183e12c5d1SDavid du Colombier #define	NDIR	14		/* should get this from param.h */
3191936bb65SDavid du Colombier 
Globsize(p)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 }
3361936bb65SDavid du Colombier 
3373e12c5d1SDavid du Colombier #include <sys/types.h>
3381936bb65SDavid du Colombier #include <dirent.h>
3391936bb65SDavid du Colombier 
3403e12c5d1SDavid du Colombier #define	NDIRLIST	50
3411936bb65SDavid du Colombier 
3423e12c5d1SDavid du Colombier DIR *dirlist[NDIRLIST];
3431936bb65SDavid du Colombier 
Opendir(name)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 }
3551936bb65SDavid du Colombier 
3561936bb65SDavid du Colombier int
Readdir(int f,char * p,int onlydirs)3571936bb65SDavid du Colombier Readdir(int f, char *p, int onlydirs)
3583e12c5d1SDavid du Colombier {
3591936bb65SDavid du Colombier 	struct dirent *dp = readdir(dirlist[f]);
3601936bb65SDavid 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 }
3661936bb65SDavid du Colombier 
3671936bb65SDavid du Colombier void
Closedir(int f)3681936bb65SDavid du Colombier Closedir(int f)
3691936bb65SDavid du Colombier {
3703e12c5d1SDavid du Colombier 	closedir(dirlist[f]);
3713e12c5d1SDavid du Colombier 	dirlist[f] = 0;
3723e12c5d1SDavid du Colombier }
3731936bb65SDavid 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 
3861936bb65SDavid du Colombier void
gettrap(int sig)3871936bb65SDavid 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);
3941936bb65SDavid du Colombier 		signal(SIGABRT, (void (*)())0);
3951936bb65SDavid du Colombier 		kill(getpid(), SIGABRT);
3963e12c5d1SDavid du Colombier 	}
3973e12c5d1SDavid du Colombier }
3981936bb65SDavid du Colombier 
3991936bb65SDavid du Colombier void
Trapinit(void)4001936bb65SDavid du Colombier Trapinit(void)
4011936bb65SDavid du Colombier {
402dc5a79c1SDavid du Colombier 	int i;
4031936bb65SDavid du Colombier 	void (*sig)();
4041936bb65SDavid 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 }
4181936bb65SDavid du Colombier 
Unlink(name)4193e12c5d1SDavid du Colombier Unlink(name)
4203e12c5d1SDavid du Colombier char *name;
4213e12c5d1SDavid du Colombier {
4223e12c5d1SDavid du Colombier 	return unlink(name);
4233e12c5d1SDavid du Colombier }
Write(fd,buf,cnt)4243e12c5d1SDavid du Colombier Write(fd, buf, cnt)
4251936bb65SDavid du Colombier char *buf;
4263e12c5d1SDavid du Colombier {
4273e12c5d1SDavid du Colombier 	return write(fd, buf, cnt);
4283e12c5d1SDavid du Colombier }
Read(fd,buf,cnt)4293e12c5d1SDavid du Colombier Read(fd, buf, cnt)
4301936bb65SDavid du Colombier char *buf;
4313e12c5d1SDavid du Colombier {
4323e12c5d1SDavid du Colombier 	return read(fd, buf, cnt);
4333e12c5d1SDavid du Colombier }
Seek(fd,cnt,whence)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 }
Executable(file)4393e12c5d1SDavid du Colombier Executable(file)
4403e12c5d1SDavid du Colombier char *file;
4413e12c5d1SDavid du Colombier {
4423e12c5d1SDavid du Colombier 	return(access(file, 01)==0);
4433e12c5d1SDavid du Colombier }
Creat(file)4443e12c5d1SDavid du Colombier Creat(file)
4453e12c5d1SDavid du Colombier char *file;
4463e12c5d1SDavid du Colombier {
4473e12c5d1SDavid du Colombier 	return creat(file, 0666);
4483e12c5d1SDavid du Colombier }
Dup(a,b)4493e12c5d1SDavid du Colombier Dup(a, b){
4503e12c5d1SDavid du Colombier 	return dup2(a, b);
4513e12c5d1SDavid du Colombier }
Dup1(a)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  */
4581936bb65SDavid du Colombier void
Exit(char * stat)4591936bb65SDavid du Colombier Exit(char *stat)
4603e12c5d1SDavid du Colombier {
461dc5a79c1SDavid du Colombier 	int n = 0;
4621936bb65SDavid 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 }
Eintr()4733e12c5d1SDavid du Colombier Eintr(){
4743e12c5d1SDavid du Colombier 	return errno==EINTR;
4753e12c5d1SDavid du Colombier }
4761936bb65SDavid du Colombier 
4771936bb65SDavid du Colombier void
Noerror()4781936bb65SDavid du Colombier Noerror()
4791936bb65SDavid du Colombier {
4803e12c5d1SDavid du Colombier 	errno = 0;
4813e12c5d1SDavid du Colombier }
Isatty(fd)4823e12c5d1SDavid du Colombier Isatty(fd){
4833e12c5d1SDavid du Colombier 	return isatty(fd);
4843e12c5d1SDavid du Colombier }
4851936bb65SDavid du Colombier 
4861936bb65SDavid du Colombier void
Abort()4871936bb65SDavid du Colombier Abort()
4881936bb65SDavid du Colombier {
4893e12c5d1SDavid du Colombier 	abort();
4903e12c5d1SDavid du Colombier }
4911936bb65SDavid du Colombier 
4921936bb65SDavid du Colombier void
execumask(void)4931936bb65SDavid du Colombier execumask(void)		/* wrong -- should fork before writing */
4941936bb65SDavid 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 }
5181936bb65SDavid du Colombier 
5191936bb65SDavid du Colombier void
Memcpy(a,b,n)5203e12c5d1SDavid du Colombier Memcpy(a, b, n)
5211936bb65SDavid 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*
Malloc(unsigned long n)5271936bb65SDavid du Colombier Malloc(unsigned long n)
528dc5a79c1SDavid du Colombier {
5293e12c5d1SDavid du Colombier 	return (void *)malloc(n);
5303e12c5d1SDavid du Colombier }
5311936bb65SDavid du Colombier 
5321936bb65SDavid du Colombier void
errstr(char * buf,int len)5331936bb65SDavid du Colombier errstr(char *buf, int len)
5341936bb65SDavid du Colombier {
5351936bb65SDavid du Colombier 	strncpy(buf, strerror(errno), len);
5361936bb65SDavid du Colombier }
5371936bb65SDavid du Colombier 
5381936bb65SDavid du Colombier int
needsrcquote(int c)5391936bb65SDavid du Colombier needsrcquote(int c)
5401936bb65SDavid du Colombier {
5411936bb65SDavid du Colombier 	if(c <= ' ')
5421936bb65SDavid du Colombier 		return 1;
5431936bb65SDavid du Colombier 	if(strchr("`^#*[]=|\\?${}()'<>&;", c))
5441936bb65SDavid du Colombier 		return 1;
5451936bb65SDavid du Colombier 	return 0;
5461936bb65SDavid du Colombier }
547*bad30d5dSDavid du Colombier 
548*bad30d5dSDavid du Colombier int
rfork(int bits)549*bad30d5dSDavid du Colombier rfork(int bits)
550*bad30d5dSDavid du Colombier {
551*bad30d5dSDavid du Colombier 	return fork();
552*bad30d5dSDavid du Colombier }
553*bad30d5dSDavid du Colombier 
554*bad30d5dSDavid du Colombier int *waitpids;
555*bad30d5dSDavid du Colombier int nwaitpids;
556*bad30d5dSDavid du Colombier 
557*bad30d5dSDavid du Colombier void
addwaitpid(int pid)558*bad30d5dSDavid du Colombier addwaitpid(int pid)
559*bad30d5dSDavid du Colombier {
560*bad30d5dSDavid du Colombier 	waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]);
561*bad30d5dSDavid du Colombier 	if(waitpids == 0)
562*bad30d5dSDavid du Colombier 		panic("Can't realloc %d waitpids", nwaitpids+1);
563*bad30d5dSDavid du Colombier 	waitpids[nwaitpids++] = pid;
564*bad30d5dSDavid du Colombier }
565*bad30d5dSDavid du Colombier 
566*bad30d5dSDavid du Colombier void
delwaitpid(int pid)567*bad30d5dSDavid du Colombier delwaitpid(int pid)
568*bad30d5dSDavid du Colombier {
569*bad30d5dSDavid du Colombier 	int r, w;
570*bad30d5dSDavid du Colombier 
571*bad30d5dSDavid du Colombier 	for(r=w=0; r<nwaitpids; r++)
572*bad30d5dSDavid du Colombier 		if(waitpids[r] != pid)
573*bad30d5dSDavid du Colombier 			waitpids[w++] = waitpids[r];
574*bad30d5dSDavid du Colombier 	nwaitpids = w;
575*bad30d5dSDavid du Colombier }
576*bad30d5dSDavid du Colombier 
577*bad30d5dSDavid du Colombier void
clearwaitpids(void)578*bad30d5dSDavid du Colombier clearwaitpids(void)
579*bad30d5dSDavid du Colombier {
580*bad30d5dSDavid du Colombier 	nwaitpids = 0;
581*bad30d5dSDavid du Colombier }
582*bad30d5dSDavid du Colombier 
583*bad30d5dSDavid du Colombier int
havewaitpid(int pid)584*bad30d5dSDavid du Colombier havewaitpid(int pid)
585*bad30d5dSDavid du Colombier {
586*bad30d5dSDavid du Colombier 	int i;
587*bad30d5dSDavid du Colombier 
588*bad30d5dSDavid du Colombier 	for(i=0; i<nwaitpids; i++)
589*bad30d5dSDavid du Colombier 		if(waitpids[i] == pid)
590*bad30d5dSDavid du Colombier 			return 1;
591*bad30d5dSDavid du Colombier 	return 0;
592*bad30d5dSDavid du Colombier }
593