xref: /plan9/sys/src/cmd/rc/plan9.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier  * Plan 9 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 "io.h"
93e12c5d1SDavid du Colombier #include "fns.h"
103e12c5d1SDavid du Colombier #include "getflags.h"
113e12c5d1SDavid du Colombier char *Signame[]={
123e12c5d1SDavid du Colombier 	"sigexit",	"sighup",	"sigint",	"sigquit",
13*219b2ee8SDavid du Colombier 	"sigalrm",	"sigkill",	"sigfpe",	"sigterm",
14*219b2ee8SDavid du Colombier 	0
153e12c5d1SDavid du Colombier };
163e12c5d1SDavid du Colombier char *syssigname[]={
173e12c5d1SDavid du Colombier 	"exit",		/* can't happen */
183e12c5d1SDavid du Colombier 	"hangup",
193e12c5d1SDavid du Colombier 	"interrupt",
203e12c5d1SDavid du Colombier 	"quit",		/* can't happen */
213e12c5d1SDavid du Colombier 	"alarm",
22*219b2ee8SDavid du Colombier 	"kill",
233e12c5d1SDavid du Colombier 	"sys: fp: ",
24*219b2ee8SDavid du Colombier 	"term",
253e12c5d1SDavid du Colombier 	0
263e12c5d1SDavid du Colombier };
273e12c5d1SDavid du Colombier char Rcmain[]="/rc/lib/rcmain";
283e12c5d1SDavid du Colombier char Fdprefix[]="/fd/";
293e12c5d1SDavid du Colombier void execfinit(void);
303e12c5d1SDavid du Colombier void execbind(void);
313e12c5d1SDavid du Colombier void execmount(void);
323e12c5d1SDavid du Colombier void execnewpgrp(void);
333e12c5d1SDavid du Colombier builtin Builtin[]={
343e12c5d1SDavid du Colombier 	"cd",		execcd,
353e12c5d1SDavid du Colombier 	"whatis",	execwhatis,
363e12c5d1SDavid du Colombier 	"eval",		execeval,
373e12c5d1SDavid du Colombier 	"exec",		execexec,	/* but with popword first */
383e12c5d1SDavid du Colombier 	"exit",		execexit,
393e12c5d1SDavid du Colombier 	"shift",	execshift,
403e12c5d1SDavid du Colombier 	"wait",		execwait,
413e12c5d1SDavid du Colombier 	".",		execdot,
423e12c5d1SDavid du Colombier 	"finit",	execfinit,
433e12c5d1SDavid du Colombier 	"flag",		execflag,
443e12c5d1SDavid du Colombier 	"rfork",	execnewpgrp,
453e12c5d1SDavid du Colombier 	0
463e12c5d1SDavid du Colombier };
473e12c5d1SDavid du Colombier void execnewpgrp(void){
483e12c5d1SDavid du Colombier 	int arg;
493e12c5d1SDavid du Colombier 	char *s;
503e12c5d1SDavid du Colombier 	switch(count(runq->argv->words)){
513e12c5d1SDavid du Colombier 	case 1: arg=RFENVG|RFNAMEG|RFNOTEG; break;
523e12c5d1SDavid du Colombier 	case 2:
533e12c5d1SDavid du Colombier 		arg=0;
543e12c5d1SDavid du Colombier 		for(s=runq->argv->words->next->word;*s;s++) switch(*s){
553e12c5d1SDavid du Colombier 		default:
563e12c5d1SDavid du Colombier 			goto Usage;
573e12c5d1SDavid du Colombier 		case 'n': arg|=RFNAMEG;  break;
583e12c5d1SDavid du Colombier 		case 'N': arg|=RFCNAMEG; break;
593e12c5d1SDavid du Colombier 		case 'e': arg|=RFENVG;   break;
603e12c5d1SDavid du Colombier 		case 'E': arg|=RFCENVG;  break;
613e12c5d1SDavid du Colombier 		case 's': arg|=RFNOTEG;  break;
623e12c5d1SDavid du Colombier 		case 'f': arg|=RFFDG;    break;
633e12c5d1SDavid du Colombier 		case 'F': arg|=RFCFDG;   break;
643e12c5d1SDavid du Colombier 		}
653e12c5d1SDavid du Colombier 		break;
663e12c5d1SDavid du Colombier 	default:
673e12c5d1SDavid du Colombier 	Usage:
683e12c5d1SDavid du Colombier 		pfmt(err, "Usage: %s [fnesFNE]\n", runq->argv->words->word);
693e12c5d1SDavid du Colombier 		setstatus("rfork usage");
703e12c5d1SDavid du Colombier 		poplist();
713e12c5d1SDavid du Colombier 		return;
723e12c5d1SDavid du Colombier 	}
733e12c5d1SDavid du Colombier 	if(rfork(arg)==-1){
743e12c5d1SDavid du Colombier 		pfmt(err, "rc: %s failed\n", runq->argv->words->word);
753e12c5d1SDavid du Colombier 		setstatus("rfork failed");
763e12c5d1SDavid du Colombier 	}
773e12c5d1SDavid du Colombier 	else
783e12c5d1SDavid du Colombier 		setstatus("");
793e12c5d1SDavid du Colombier 	poplist();
803e12c5d1SDavid du Colombier }
813e12c5d1SDavid du Colombier void Vinit(void){
823e12c5d1SDavid du Colombier 	int dir=open("#e", 0), f, len;
833e12c5d1SDavid du Colombier 	word *val;
843e12c5d1SDavid du Colombier 	char *buf, *s;
853e12c5d1SDavid du Colombier 	Dir ent;
863e12c5d1SDavid du Colombier 	char envname[NAMELEN+6];
873e12c5d1SDavid du Colombier 	if(dir<0){
883e12c5d1SDavid du Colombier 		pfmt(err, "rc: can't open #e\n");
893e12c5d1SDavid du Colombier 		return;
903e12c5d1SDavid du Colombier 	}
913e12c5d1SDavid du Colombier 	while(dirread(dir, &ent, sizeof ent)==sizeof ent){
923e12c5d1SDavid du Colombier 		len=ent.length;
933e12c5d1SDavid du Colombier 		if(len && strncmp(ent.name, "fn#", 3)!=0){
943e12c5d1SDavid du Colombier 			strcpy(envname, "#e/");
953e12c5d1SDavid du Colombier 			strcat(envname, ent.name);
963e12c5d1SDavid du Colombier 			if((f=open(envname, 0))>=0){
973e12c5d1SDavid du Colombier 				buf=emalloc((int)len+1);
983e12c5d1SDavid du Colombier 				read(f, buf, (long)len);
993e12c5d1SDavid du Colombier 				val=0;
1003e12c5d1SDavid du Colombier 				/* Charitably add a 0 at the end if need be */
1013e12c5d1SDavid du Colombier 				if(buf[len-1]) buf[len++]='\0';
1023e12c5d1SDavid du Colombier 				s=buf+len-1;
1033e12c5d1SDavid du Colombier 				for(;;){
1043e12c5d1SDavid du Colombier 					while(s!=buf && s[-1]!='\0') --s;
1053e12c5d1SDavid du Colombier 					val=newword(s, val);
1063e12c5d1SDavid du Colombier 					if(s==buf) break;
1073e12c5d1SDavid du Colombier 					--s;
1083e12c5d1SDavid du Colombier 				}
1093e12c5d1SDavid du Colombier 				setvar(ent.name, val);
1103e12c5d1SDavid du Colombier 				vlook(ent.name)->changed=0;
1113e12c5d1SDavid du Colombier 				close(f);
1123e12c5d1SDavid du Colombier 				efree(buf);
1133e12c5d1SDavid du Colombier 			}
1143e12c5d1SDavid du Colombier 		}
1153e12c5d1SDavid du Colombier 	}
1163e12c5d1SDavid du Colombier 	close(dir);
1173e12c5d1SDavid du Colombier }
1183e12c5d1SDavid du Colombier #ifdef old_execfinit
1193e12c5d1SDavid du Colombier void Xrdfn(void){}
1203e12c5d1SDavid du Colombier void execfinit(void){
1213e12c5d1SDavid du Colombier 	Xpopm();
1223e12c5d1SDavid du Colombier }
1233e12c5d1SDavid du Colombier #else
1243e12c5d1SDavid du Colombier int envdir;
1253e12c5d1SDavid du Colombier void Xrdfn(void){
1263e12c5d1SDavid du Colombier 	int f, len;
1273e12c5d1SDavid du Colombier 	Dir ent;
1283e12c5d1SDavid du Colombier 	char envname[NAMELEN+6];
1293e12c5d1SDavid du Colombier 	while(dirread(envdir, &ent, sizeof ent)==sizeof ent){
1303e12c5d1SDavid du Colombier 		len=ent.length;
1313e12c5d1SDavid du Colombier 		if(len && strncmp(ent.name, "fn#", 3)==0){
1323e12c5d1SDavid du Colombier 			strcpy(envname, "#e/");
1333e12c5d1SDavid du Colombier 			strcat(envname, ent.name);
1343e12c5d1SDavid du Colombier 			if((f=open(envname, 0))>=0){
1353e12c5d1SDavid du Colombier 				execcmds(openfd(f));
1363e12c5d1SDavid du Colombier 				return;
1373e12c5d1SDavid du Colombier 			}
1383e12c5d1SDavid du Colombier 		}
1393e12c5d1SDavid du Colombier 	}
1403e12c5d1SDavid du Colombier 	close(envdir);
1413e12c5d1SDavid du Colombier 	Xreturn();
1423e12c5d1SDavid du Colombier }
1433e12c5d1SDavid du Colombier union code rdfns[4];
1443e12c5d1SDavid du Colombier void execfinit(void){
1453e12c5d1SDavid du Colombier 	static int first=1;
1463e12c5d1SDavid du Colombier 	if(first){
1473e12c5d1SDavid du Colombier 		rdfns[0].i=1;
1483e12c5d1SDavid du Colombier 		rdfns[1].f=Xrdfn;
1493e12c5d1SDavid du Colombier 		rdfns[2].f=Xjump;
1503e12c5d1SDavid du Colombier 		rdfns[3].i=1;
1513e12c5d1SDavid du Colombier 		first=0;
1523e12c5d1SDavid du Colombier 	}
1533e12c5d1SDavid du Colombier 	Xpopm();
1543e12c5d1SDavid du Colombier 	envdir=open("#e", 0);
1553e12c5d1SDavid du Colombier 	if(envdir<0){
1563e12c5d1SDavid du Colombier 		pfmt(err, "rc: can't open #e\n");
1573e12c5d1SDavid du Colombier 		return;
1583e12c5d1SDavid du Colombier 	}
1593e12c5d1SDavid du Colombier 	start(rdfns, 1, runq->local);
1603e12c5d1SDavid du Colombier }
1613e12c5d1SDavid du Colombier #endif
1623e12c5d1SDavid du Colombier int Waitfor(int pid, int persist){
1633e12c5d1SDavid du Colombier 	thread *p;
1643e12c5d1SDavid du Colombier 	Waitmsg w;
1653e12c5d1SDavid du Colombier 	int cpid;
166*219b2ee8SDavid du Colombier 	char errbuf[ERRLEN];
167*219b2ee8SDavid du Colombier 	while((cpid=wait(&w))>=0){
1683e12c5d1SDavid du Colombier 		if(pid==cpid){
1693e12c5d1SDavid du Colombier 			setstatus(w.msg);
170*219b2ee8SDavid du Colombier 			return 0;
1713e12c5d1SDavid du Colombier 		}
1723e12c5d1SDavid du Colombier 		for(p=runq->ret;p;p=p->ret)
1733e12c5d1SDavid du Colombier 			if(p->pid==cpid){
1743e12c5d1SDavid du Colombier 				p->pid=-1;
1753e12c5d1SDavid du Colombier 				strcpy(p->status, w.msg);
1763e12c5d1SDavid du Colombier 			}
1773e12c5d1SDavid du Colombier 	}
178*219b2ee8SDavid du Colombier 	errstr(errbuf);
179*219b2ee8SDavid du Colombier 	if(strcmp(errbuf, "interrupted")==0) return -1;
1803e12c5d1SDavid du Colombier 	return 0;
1813e12c5d1SDavid du Colombier }
1823e12c5d1SDavid du Colombier char **mkargv(word *a)
1833e12c5d1SDavid du Colombier {
1843e12c5d1SDavid du Colombier 	char **argv=(char **)emalloc((count(a)+2)*sizeof(char *));
1853e12c5d1SDavid du Colombier 	char **argp=argv+1;	/* leave one at front for runcoms */
1863e12c5d1SDavid du Colombier 	for(;a;a=a->next) *argp++=a->word;
1873e12c5d1SDavid du Colombier 	*argp=0;
1883e12c5d1SDavid du Colombier 	return argv;
1893e12c5d1SDavid du Colombier }
1903e12c5d1SDavid du Colombier void addenv(var *v)
1913e12c5d1SDavid du Colombier {
1923e12c5d1SDavid du Colombier 	char envname[NAMELEN+9];
1933e12c5d1SDavid du Colombier 	word *w;
1943e12c5d1SDavid du Colombier 	int f;
1953e12c5d1SDavid du Colombier 	io *fd;
1963e12c5d1SDavid du Colombier 	if(v->changed){
1973e12c5d1SDavid du Colombier 		v->changed=0;
1983e12c5d1SDavid du Colombier 		strcpy(envname, "#e/");
1993e12c5d1SDavid du Colombier 		strcat(envname, v->name);
2003e12c5d1SDavid du Colombier 		if((f=Creat(envname))<0)
2013e12c5d1SDavid du Colombier 			pfmt(err, "rc: can't open %s\n", envname);
2023e12c5d1SDavid du Colombier 		else{
2033e12c5d1SDavid du Colombier 			for(w=v->val;w;w=w->next)
2043e12c5d1SDavid du Colombier 				write(f, w->word, strlen(w->word)+1L);
2053e12c5d1SDavid du Colombier 			close(f);
2063e12c5d1SDavid du Colombier 		}
2073e12c5d1SDavid du Colombier 	}
2083e12c5d1SDavid du Colombier 	if(v->fnchanged){
2093e12c5d1SDavid du Colombier 		v->fnchanged=0;
2103e12c5d1SDavid du Colombier 		strcpy(envname, "#e/fn#");
2113e12c5d1SDavid du Colombier 		strcat(envname, v->name);
2123e12c5d1SDavid du Colombier 		if((f=Creat(envname))<0)
2133e12c5d1SDavid du Colombier 			pfmt(err, "rc: can't open %s\n", envname);
2143e12c5d1SDavid du Colombier 		else{
2153e12c5d1SDavid du Colombier 			if(v->fn){
2163e12c5d1SDavid du Colombier 				fd=openfd(f);
2173e12c5d1SDavid du Colombier 				pfmt(fd, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
2183e12c5d1SDavid du Colombier 				closeio(fd);
2193e12c5d1SDavid du Colombier 			}
2203e12c5d1SDavid du Colombier 			close(f);
2213e12c5d1SDavid du Colombier 		}
2223e12c5d1SDavid du Colombier 	}
2233e12c5d1SDavid du Colombier }
2243e12c5d1SDavid du Colombier void updenvlocal(var *v)
2253e12c5d1SDavid du Colombier {
2263e12c5d1SDavid du Colombier 	if(v){
2273e12c5d1SDavid du Colombier 		updenvlocal(v->next);
2283e12c5d1SDavid du Colombier 		addenv(v);
2293e12c5d1SDavid du Colombier 	}
2303e12c5d1SDavid du Colombier }
2313e12c5d1SDavid du Colombier void Updenv(void){
2323e12c5d1SDavid du Colombier 	var *v, **h;
2333e12c5d1SDavid du Colombier 	for(h=gvar;h!=&gvar[NVAR];h++)
2343e12c5d1SDavid du Colombier 		for(v=*h;v;v=v->next)
2353e12c5d1SDavid du Colombier 			addenv(v);
2363e12c5d1SDavid du Colombier 	if(runq) updenvlocal(runq->local);
2373e12c5d1SDavid du Colombier }
2383e12c5d1SDavid du Colombier void Execute(word *args, word *path)
2393e12c5d1SDavid du Colombier {
2403e12c5d1SDavid du Colombier 	char **argv=mkargv(args);
241*219b2ee8SDavid du Colombier 	char file[1024];
242*219b2ee8SDavid du Colombier 	int nc;
2433e12c5d1SDavid du Colombier 	Updenv();
2443e12c5d1SDavid du Colombier 	for(;path;path=path->next){
245*219b2ee8SDavid du Colombier 		nc=strlen(path->word);
246*219b2ee8SDavid du Colombier 		if(nc<1024){
2473e12c5d1SDavid du Colombier 			strcpy(file, path->word);
248*219b2ee8SDavid du Colombier 			if(file[0]){
249*219b2ee8SDavid du Colombier 				strcat(file, "/");
250*219b2ee8SDavid du Colombier 				nc++;
251*219b2ee8SDavid du Colombier 			}
252*219b2ee8SDavid du Colombier 			if(nc+strlen(argv[1])<1024){
2533e12c5d1SDavid du Colombier 				strcat(file, argv[1]);
2543e12c5d1SDavid du Colombier 				exec(file, argv+1);
2553e12c5d1SDavid du Colombier 			}
256*219b2ee8SDavid du Colombier 			else werrstr("command name too long");
257*219b2ee8SDavid du Colombier 		}
258*219b2ee8SDavid du Colombier 	}
2593e12c5d1SDavid du Colombier 	errstr(file);
2603e12c5d1SDavid du Colombier 	pfmt(err, "%s: %s\n", argv[1], file);
2613e12c5d1SDavid du Colombier 	efree((char *)argv);
2623e12c5d1SDavid du Colombier }
2633e12c5d1SDavid du Colombier int Globsize(char *p)
2643e12c5d1SDavid du Colombier {
2653e12c5d1SDavid du Colombier 	ulong isglob=0, globlen=NAMELEN+1;
2663e12c5d1SDavid du Colombier 	for(;*p;p++){
2673e12c5d1SDavid du Colombier 		if(*p==GLOB){
2683e12c5d1SDavid du Colombier 			p++;
2693e12c5d1SDavid du Colombier 			if(*p!=GLOB) isglob++;
2703e12c5d1SDavid du Colombier 			globlen+=*p=='*'?NAMELEN:1;
2713e12c5d1SDavid du Colombier 		}
2723e12c5d1SDavid du Colombier 		else
2733e12c5d1SDavid du Colombier 			globlen++;
2743e12c5d1SDavid du Colombier 	}
2753e12c5d1SDavid du Colombier 	return isglob?globlen:0;
2763e12c5d1SDavid du Colombier }
2773e12c5d1SDavid du Colombier #define NFD	50
2783e12c5d1SDavid du Colombier #define	NDBUF	32
2793e12c5d1SDavid du Colombier struct{
2803e12c5d1SDavid du Colombier 	char	*buf;
2813e12c5d1SDavid du Colombier 	int	n;
2823e12c5d1SDavid du Colombier }dir[NFD];
2833e12c5d1SDavid du Colombier int Opendir(char *name)
2843e12c5d1SDavid du Colombier {
2853e12c5d1SDavid du Colombier 	Dir db;
2863e12c5d1SDavid du Colombier 	int f;
2873e12c5d1SDavid du Colombier 	f=open(name, 0);
2883e12c5d1SDavid du Colombier 	if(f==-1)
2893e12c5d1SDavid du Colombier 		return f;
2903e12c5d1SDavid du Colombier 	if(dirfstat(f, &db)!=-1 && (db.mode&0x80000000)){
2913e12c5d1SDavid du Colombier 		if(f<NFD && dir[f].buf){
2923e12c5d1SDavid du Colombier 			free(dir[f].buf);
2933e12c5d1SDavid du Colombier 			dir[f].buf=0;
2943e12c5d1SDavid du Colombier 		}
2953e12c5d1SDavid du Colombier 		return f;
2963e12c5d1SDavid du Colombier 	}
2973e12c5d1SDavid du Colombier 	close(f);
2983e12c5d1SDavid du Colombier 	return -1;
2993e12c5d1SDavid du Colombier }
3003e12c5d1SDavid du Colombier int Readdir(int f, char *p)
3013e12c5d1SDavid du Colombier {
3023e12c5d1SDavid du Colombier 	char dirent[DIRLEN];
3033e12c5d1SDavid du Colombier 	int n;
3043e12c5d1SDavid du Colombier 	if(f<0 || f>=NFD){
3053e12c5d1SDavid du Colombier    slow:
3063e12c5d1SDavid du Colombier 		while(read(f, dirent, sizeof dirent)==sizeof dirent){
3073e12c5d1SDavid du Colombier 			strcpy(p, dirent);
3083e12c5d1SDavid du Colombier 			return 1;
3093e12c5d1SDavid du Colombier 		}
3103e12c5d1SDavid du Colombier 		return 0;
3113e12c5d1SDavid du Colombier 	}
3123e12c5d1SDavid du Colombier 	if(dir[f].buf==0){	/* allocate */
3133e12c5d1SDavid du Colombier 		dir[f].buf=malloc(NDBUF*DIRLEN);
3143e12c5d1SDavid du Colombier 		if(dir[f].buf==0)
3153e12c5d1SDavid du Colombier 			goto slow;
3163e12c5d1SDavid du Colombier 		dir[f].n=0;
3173e12c5d1SDavid du Colombier 	}
3183e12c5d1SDavid du Colombier 	if(dir[f].n==0){	/* read */
3193e12c5d1SDavid du Colombier 		memset(dir[f].buf, 0, NDBUF*DIRLEN);
3203e12c5d1SDavid du Colombier 		n = read(f, dir[f].buf, NDBUF*DIRLEN);
3213e12c5d1SDavid du Colombier 		if(n>0 && n<NDBUF*DIRLEN){
3223e12c5d1SDavid du Colombier 			memmove(dir[f].buf+NDBUF*DIRLEN-n, dir[f].buf, n);
3233e12c5d1SDavid du Colombier 			dir[f].n=NDBUF-n/DIRLEN;
3243e12c5d1SDavid du Colombier 		}else
3253e12c5d1SDavid du Colombier 			dir[f].n=0;
3263e12c5d1SDavid du Colombier 	}
3273e12c5d1SDavid du Colombier 	if(dir[f].buf[dir[f].n*DIRLEN]==0)
3283e12c5d1SDavid du Colombier 		return 0;
3293e12c5d1SDavid du Colombier 	strcpy(p, &dir[f].buf[dir[f].n*DIRLEN]);
3303e12c5d1SDavid du Colombier 	dir[f].n++;
3313e12c5d1SDavid du Colombier 	if(dir[f].n==NDBUF)
3323e12c5d1SDavid du Colombier 		dir[f].n=0;
3333e12c5d1SDavid du Colombier 	return 1;
3343e12c5d1SDavid du Colombier }
3353e12c5d1SDavid du Colombier void Closedir(int f){
3363e12c5d1SDavid du Colombier 	if(f>=0 && f<NFD && dir[f].buf){
3373e12c5d1SDavid du Colombier 		free(dir[f].buf);
3383e12c5d1SDavid du Colombier 		dir[f].buf=0;
3393e12c5d1SDavid du Colombier 	}
3403e12c5d1SDavid du Colombier 	close(f);
3413e12c5d1SDavid du Colombier }
3423e12c5d1SDavid du Colombier int interrupted = 0;
3433e12c5d1SDavid du Colombier void
3443e12c5d1SDavid du Colombier notifyf(void *a, char *s)
3453e12c5d1SDavid du Colombier {
3463e12c5d1SDavid du Colombier 	int i;
3473e12c5d1SDavid du Colombier 	for(i=0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
3483e12c5d1SDavid du Colombier 		if(strncmp(s, "sys: ", 5)!=0) interrupted=1;
3493e12c5d1SDavid du Colombier 		goto Out;
3503e12c5d1SDavid du Colombier 	}
3513e12c5d1SDavid du Colombier 	pfmt(err, "rc: note: %s\n", s);
3523e12c5d1SDavid du Colombier 	noted(NDFLT);
3533e12c5d1SDavid du Colombier 	return;
3543e12c5d1SDavid du Colombier Out:
355*219b2ee8SDavid du Colombier 	if(strcmp(s, "interrupt")!=0 || trap[i]==0){
3563e12c5d1SDavid du Colombier 		trap[i]++;
3573e12c5d1SDavid du Colombier 		ntrap++;
358*219b2ee8SDavid du Colombier 	}
3593e12c5d1SDavid du Colombier 	if(ntrap>=32){	/* rc is probably in a trap loop */
3603e12c5d1SDavid du Colombier 		pfmt(err, "rc: Too many traps (trap %s), aborting\n", s);
3613e12c5d1SDavid du Colombier 		abort();
3623e12c5d1SDavid du Colombier 	}
3633e12c5d1SDavid du Colombier 	noted(NCONT);
3643e12c5d1SDavid du Colombier }
3653e12c5d1SDavid du Colombier void Trapinit(void){
3663e12c5d1SDavid du Colombier 	notify(notifyf);
3673e12c5d1SDavid du Colombier }
3683e12c5d1SDavid du Colombier void Unlink(char *name)
3693e12c5d1SDavid du Colombier {
3703e12c5d1SDavid du Colombier 	remove(name);
3713e12c5d1SDavid du Colombier }
3723e12c5d1SDavid du Colombier long Write(int fd, char *buf, long cnt)
3733e12c5d1SDavid du Colombier {
3743e12c5d1SDavid du Colombier 	return write(fd, buf, (long)cnt);
3753e12c5d1SDavid du Colombier }
3763e12c5d1SDavid du Colombier long Read(int fd, char *buf, long cnt)
3773e12c5d1SDavid du Colombier {
3783e12c5d1SDavid du Colombier 	int n;
3793e12c5d1SDavid du Colombier 
3803e12c5d1SDavid du Colombier 	return read(fd, buf, cnt);
3813e12c5d1SDavid du Colombier }
3823e12c5d1SDavid du Colombier long Seek(int fd, long cnt, int whence)
3833e12c5d1SDavid du Colombier {
3843e12c5d1SDavid du Colombier 	return seek(fd, cnt, whence);
3853e12c5d1SDavid du Colombier }
3863e12c5d1SDavid du Colombier int Executable(char *file)
3873e12c5d1SDavid du Colombier {
3883e12c5d1SDavid du Colombier 	Dir statbuf;
3893e12c5d1SDavid du Colombier 
3903e12c5d1SDavid du Colombier 	return dirstat(file, &statbuf)!=-1 && (statbuf.mode&0111)!=0 && (statbuf.mode&CHDIR)==0;
3913e12c5d1SDavid du Colombier }
3923e12c5d1SDavid du Colombier int Creat(char *file)
3933e12c5d1SDavid du Colombier {
3943e12c5d1SDavid du Colombier 	return create(file, 1, 0666L);
3953e12c5d1SDavid du Colombier }
3963e12c5d1SDavid du Colombier int Dup(int a, int b){
3973e12c5d1SDavid du Colombier 	return dup(a, b);
3983e12c5d1SDavid du Colombier }
3993e12c5d1SDavid du Colombier int Dup1(int a){
4003e12c5d1SDavid du Colombier 	return -1;
4013e12c5d1SDavid du Colombier }
4023e12c5d1SDavid du Colombier void Exit(char *stat)
4033e12c5d1SDavid du Colombier {
4043e12c5d1SDavid du Colombier 	Updenv();
4053e12c5d1SDavid du Colombier 	setstatus(stat);
4063e12c5d1SDavid du Colombier 	exits(truestatus()?"":getstatus());
4073e12c5d1SDavid du Colombier }
4083e12c5d1SDavid du Colombier int Eintr(void){
4093e12c5d1SDavid du Colombier 	return interrupted;
4103e12c5d1SDavid du Colombier }
4113e12c5d1SDavid du Colombier void Noerror(void){
4123e12c5d1SDavid du Colombier 	interrupted=0;
4133e12c5d1SDavid du Colombier }
4143e12c5d1SDavid du Colombier int Isatty(int fd){
4153e12c5d1SDavid du Colombier 	Dir d1, d2;
4163e12c5d1SDavid du Colombier 
4173e12c5d1SDavid du Colombier 	if(dirfstat(0, &d1)==-1) return 0;
418*219b2ee8SDavid du Colombier 	if(strncmp(d1.name, "ptty", 4)==0) return 1;	/* fwd complaints to philw */
4193e12c5d1SDavid du Colombier 	if(dirstat("/dev/cons", &d2)==-1) return 0;
4203e12c5d1SDavid du Colombier 	return d1.type==d2.type&&d1.dev==d2.dev&&d1.qid.path==d2.qid.path;
4213e12c5d1SDavid du Colombier }
4223e12c5d1SDavid du Colombier void Abort(void){
4233e12c5d1SDavid du Colombier 	pfmt(err, "aborting\n");
4243e12c5d1SDavid du Colombier 	flush(err);
4253e12c5d1SDavid du Colombier 	Exit("aborting");
4263e12c5d1SDavid du Colombier }
4273e12c5d1SDavid du Colombier void Memcpy(char *a, char *b, long n)
4283e12c5d1SDavid du Colombier {
4293e12c5d1SDavid du Colombier 	memmove(a, b, (long)n);
4303e12c5d1SDavid du Colombier }
4313e12c5d1SDavid du Colombier void *Malloc(ulong n){
4323e12c5d1SDavid du Colombier 	return malloc(n);
4333e12c5d1SDavid du Colombier }
434*219b2ee8SDavid du Colombier char *Geterrstr(void){
435*219b2ee8SDavid du Colombier 	static char error[ERRLEN];
436*219b2ee8SDavid du Colombier 	error[0]='\0';
437*219b2ee8SDavid du Colombier 	errstr(error);
438*219b2ee8SDavid du Colombier 	return error;
439*219b2ee8SDavid du Colombier }
440