xref: /plan9/sys/src/cmd/rc/win32.c (revision bad30d5d5a5510556b3d04cddb2a7590f26fb546)
1dc5a79c1SDavid du Colombier /*
2dc5a79c1SDavid du Colombier  * Plan 9 versions of system-specific functions
3dc5a79c1SDavid du Colombier  *	By convention, exported routines herein have names beginning with an
4dc5a79c1SDavid du Colombier  *	upper case letter.
5dc5a79c1SDavid du Colombier  */
6dc5a79c1SDavid du Colombier #include "rc.h"
7dc5a79c1SDavid du Colombier #include "exec.h"
8dc5a79c1SDavid du Colombier #include "io.h"
9dc5a79c1SDavid du Colombier #include "fns.h"
10dc5a79c1SDavid du Colombier #include "getflags.h"
11dc5a79c1SDavid du Colombier char *Signame[] = {
12dc5a79c1SDavid du Colombier 	"sigexit",	"sighup",	"sigint",	"sigquit",
13dc5a79c1SDavid du Colombier 	"sigalrm",	"sigkill",	"sigfpe",	"sigterm",
14dc5a79c1SDavid du Colombier 	0
15dc5a79c1SDavid du Colombier };
16dc5a79c1SDavid du Colombier char *syssigname[] = {
17dc5a79c1SDavid du Colombier 	"exit",		/* can't happen */
18dc5a79c1SDavid du Colombier 	"hangup",
19dc5a79c1SDavid du Colombier 	"interrupt",
20dc5a79c1SDavid du Colombier 	"quit",		/* can't happen */
21dc5a79c1SDavid du Colombier 	"alarm",
22dc5a79c1SDavid du Colombier 	"kill",
23dc5a79c1SDavid du Colombier 	"sys: fp: ",
24dc5a79c1SDavid du Colombier 	"term",
25dc5a79c1SDavid du Colombier 	0
26dc5a79c1SDavid du Colombier };
27*bad30d5dSDavid du Colombier char *Rcmain = "/rc/lib/rcmain";
28*bad30d5dSDavid du Colombier char *Fdprefix = "/fd/";
29*bad30d5dSDavid du Colombier 
30dc5a79c1SDavid du Colombier void execfinit(void);
31dc5a79c1SDavid du Colombier void execbind(void);
32dc5a79c1SDavid du Colombier 
33dc5a79c1SDavid du Colombier builtin Builtin[] = {
34dc5a79c1SDavid du Colombier 	"cd",		execcd,
35dc5a79c1SDavid du Colombier 	"whatis",	execwhatis,
36dc5a79c1SDavid du Colombier 	"eval",		execeval,
37dc5a79c1SDavid du Colombier 	"exec",		execexec,	/* but with popword first */
38dc5a79c1SDavid du Colombier 	"exit",		execexit,
39dc5a79c1SDavid du Colombier 	"shift",	execshift,
40dc5a79c1SDavid du Colombier 	"wait",		execwait,
41dc5a79c1SDavid du Colombier 	".",		execdot,
42dc5a79c1SDavid du Colombier 	"finit",	execfinit,
43dc5a79c1SDavid du Colombier 	"flag",		execflag,
44dc5a79c1SDavid du Colombier 	0
45dc5a79c1SDavid du Colombier };
46dc5a79c1SDavid du Colombier 
47dc5a79c1SDavid du Colombier void
Vinit(void)48dc5a79c1SDavid du Colombier Vinit(void)
49dc5a79c1SDavid du Colombier {
50dc5a79c1SDavid du Colombier 	int dir, f, len;
51dc5a79c1SDavid du Colombier 	word *val;
52dc5a79c1SDavid du Colombier 	char *buf, *s;
53dc5a79c1SDavid du Colombier 	Dir *ent;
54dc5a79c1SDavid du Colombier 	int i, nent;
55dc5a79c1SDavid du Colombier 	char envname[256];
56dc5a79c1SDavid du Colombier 	dir = open("/env", OREAD);
57dc5a79c1SDavid du Colombier 	if(dir<0){
58dc5a79c1SDavid du Colombier 		pfmt(err, "rc: can't open /env: %r\n");
59dc5a79c1SDavid du Colombier 		return;
60dc5a79c1SDavid du Colombier 	}
61dc5a79c1SDavid du Colombier 	ent = nil;
62dc5a79c1SDavid du Colombier 	for(;;){
63dc5a79c1SDavid du Colombier 		nent = dirread(dir, &ent);
64dc5a79c1SDavid du Colombier 		if(nent <= 0)
65dc5a79c1SDavid du Colombier 			break;
66dc5a79c1SDavid du Colombier 		for(i = 0; i<nent; i++){
67dc5a79c1SDavid du Colombier 			len = ent[i].length;
68dc5a79c1SDavid du Colombier 			if(len && strncmp(ent[i].name, "fn#", 3)!=0){
69dc5a79c1SDavid du Colombier 				snprint(envname, sizeof envname, "/env/%s", ent[i].name);
70dc5a79c1SDavid du Colombier 				if((f = open(envname, 0))>=0){
71dc5a79c1SDavid du Colombier 					buf = emalloc((int)len+1);
72dc5a79c1SDavid du Colombier 					read(f, buf, (long)len);
73dc5a79c1SDavid du Colombier 					val = 0;
74dc5a79c1SDavid du Colombier 					/* Charitably add a 0 at the end if need be */
75dc5a79c1SDavid du Colombier 					if(buf[len-1])
76dc5a79c1SDavid du Colombier 						buf[len++]='\0';
77dc5a79c1SDavid du Colombier 					s = buf+len-1;
78dc5a79c1SDavid du Colombier 					for(;;){
79dc5a79c1SDavid du Colombier 						while(s!=buf && s[-1]!='\0') --s;
80dc5a79c1SDavid du Colombier 						val = newword(s, val);
81dc5a79c1SDavid du Colombier 						if(s==buf)
82dc5a79c1SDavid du Colombier 							break;
83dc5a79c1SDavid du Colombier 						--s;
84dc5a79c1SDavid du Colombier 					}
85dc5a79c1SDavid du Colombier 					setvar(ent[i].name, val);
86dc5a79c1SDavid du Colombier 					vlook(ent[i].name)->changed = 0;
87dc5a79c1SDavid du Colombier 					close(f);
88dc5a79c1SDavid du Colombier 					efree(buf);
89dc5a79c1SDavid du Colombier 				}
90dc5a79c1SDavid du Colombier 			}
91dc5a79c1SDavid du Colombier 		}
92dc5a79c1SDavid du Colombier 		free(ent);
93dc5a79c1SDavid du Colombier 	}
94dc5a79c1SDavid du Colombier 	close(dir);
95dc5a79c1SDavid du Colombier }
96dc5a79c1SDavid du Colombier int envdir;
97dc5a79c1SDavid du Colombier 
98dc5a79c1SDavid du Colombier void
Xrdfn(void)99dc5a79c1SDavid du Colombier Xrdfn(void)
100dc5a79c1SDavid du Colombier {
101dc5a79c1SDavid du Colombier 	int f, len;
102dc5a79c1SDavid du Colombier 	static Dir *ent, *allocent;
103dc5a79c1SDavid du Colombier 	static int nent;
104dc5a79c1SDavid du Colombier 	Dir *e;
105dc5a79c1SDavid du Colombier 	char envname[256];
106dc5a79c1SDavid du Colombier 
107dc5a79c1SDavid du Colombier 	for(;;){
108dc5a79c1SDavid du Colombier 		if(nent == 0){
109dc5a79c1SDavid du Colombier 			free(allocent);
110dc5a79c1SDavid du Colombier 			nent = dirread(envdir, &allocent);
111dc5a79c1SDavid du Colombier 			ent = allocent;
112dc5a79c1SDavid du Colombier 		}
113dc5a79c1SDavid du Colombier 		if(nent <= 0)
114dc5a79c1SDavid du Colombier 			break;
115dc5a79c1SDavid du Colombier 		while(nent){
116dc5a79c1SDavid du Colombier 			e = ent++;
117dc5a79c1SDavid du Colombier 			nent--;
118dc5a79c1SDavid du Colombier 			len = e->length;
119dc5a79c1SDavid du Colombier 			if(len && strncmp(e->name, "fn#", 3)==0){
120dc5a79c1SDavid du Colombier 				snprint(envname, sizeof envname, "/env/%s", e->name);
121dc5a79c1SDavid du Colombier 				if((f = open(envname, 0))>=0){
122dc5a79c1SDavid du Colombier 					execcmds(openfd(f));
123dc5a79c1SDavid du Colombier 					return;
124dc5a79c1SDavid du Colombier 				}
125dc5a79c1SDavid du Colombier 			}
126dc5a79c1SDavid du Colombier 		}
127dc5a79c1SDavid du Colombier 	}
128dc5a79c1SDavid du Colombier 	close(envdir);
129dc5a79c1SDavid du Colombier 	Xreturn();
130dc5a79c1SDavid du Colombier }
131dc5a79c1SDavid du Colombier union code rdfns[4];
132dc5a79c1SDavid du Colombier 
133dc5a79c1SDavid du Colombier void
execfinit(void)134dc5a79c1SDavid du Colombier execfinit(void)
135dc5a79c1SDavid du Colombier {
136dc5a79c1SDavid du Colombier 	static int first = 1;
137dc5a79c1SDavid du Colombier 	if(first){
138dc5a79c1SDavid du Colombier 		rdfns[0].i = 1;
139dc5a79c1SDavid du Colombier 		rdfns[1].f = Xrdfn;
140dc5a79c1SDavid du Colombier 		rdfns[2].f = Xjump;
141dc5a79c1SDavid du Colombier 		rdfns[3].i = 1;
142dc5a79c1SDavid du Colombier 		first = 0;
143dc5a79c1SDavid du Colombier 	}
144dc5a79c1SDavid du Colombier 	Xpopm();
145dc5a79c1SDavid du Colombier 	envdir = open("/env", 0);
146dc5a79c1SDavid du Colombier 	if(envdir<0){
147dc5a79c1SDavid du Colombier 		pfmt(err, "rc: can't open /env: %r\n");
148dc5a79c1SDavid du Colombier 		return;
149dc5a79c1SDavid du Colombier 	}
150dc5a79c1SDavid du Colombier 	start(rdfns, 1, runq->local);
151dc5a79c1SDavid du Colombier }
152dc5a79c1SDavid du Colombier 
153dc5a79c1SDavid du Colombier int
Waitfor(int pid,int persist)154dc5a79c1SDavid du Colombier Waitfor(int pid, int persist)
155dc5a79c1SDavid du Colombier {
156dc5a79c1SDavid du Colombier 	thread *p;
157dc5a79c1SDavid du Colombier 	Waitmsg *w;
158dc5a79c1SDavid du Colombier 	char errbuf[ERRMAX];
159dc5a79c1SDavid du Colombier 
160dc5a79c1SDavid du Colombier 	while((w = wait()) != nil){
161dc5a79c1SDavid du Colombier 		if(w->pid==pid){
162dc5a79c1SDavid du Colombier 			setstatus(w->msg);
163dc5a79c1SDavid du Colombier 			free(w);
164dc5a79c1SDavid du Colombier 			return 0;
165dc5a79c1SDavid du Colombier 		}
166dc5a79c1SDavid du Colombier 		for(p = runq->ret;p;p = p->ret)
167dc5a79c1SDavid du Colombier 			if(p->pid==w->pid){
168dc5a79c1SDavid du Colombier 				p->pid=-1;
169dc5a79c1SDavid du Colombier 				strcpy(p->status, w->msg);
170dc5a79c1SDavid du Colombier 			}
171dc5a79c1SDavid du Colombier 		free(w);
172dc5a79c1SDavid du Colombier 	}
173dc5a79c1SDavid du Colombier 
174dc5a79c1SDavid du Colombier 	errstr(errbuf, sizeof errbuf);
175dc5a79c1SDavid du Colombier 	if(strcmp(errbuf, "interrupted")==0) return -1;
176dc5a79c1SDavid du Colombier 	return 0;
177dc5a79c1SDavid du Colombier }
178dc5a79c1SDavid du Colombier 
179dc5a79c1SDavid du Colombier char*
mkargv(word * a)180dc5a79c1SDavid du Colombier *mkargv(word *a)
181dc5a79c1SDavid du Colombier {
182dc5a79c1SDavid du Colombier 	char **argv = (char **)emalloc((count(a)+2)*sizeof(char *));
183dc5a79c1SDavid du Colombier 	char **argp = argv+1;	/* leave one at front for runcoms */
184dc5a79c1SDavid du Colombier 	for(;a;a = a->next) *argp++=a->word;
185dc5a79c1SDavid du Colombier 	*argp = 0;
186dc5a79c1SDavid du Colombier 	return argv;
187dc5a79c1SDavid du Colombier }
188dc5a79c1SDavid du Colombier 
189dc5a79c1SDavid du Colombier void
addenv(var * v)190dc5a79c1SDavid du Colombier addenv(var *v)
191dc5a79c1SDavid du Colombier {
192dc5a79c1SDavid du Colombier 	char envname[256];
193dc5a79c1SDavid du Colombier 	word *w;
194dc5a79c1SDavid du Colombier 	int f;
195dc5a79c1SDavid du Colombier 	io *fd;
196dc5a79c1SDavid du Colombier 	if(v->changed){
197dc5a79c1SDavid du Colombier 		v->changed = 0;
198dc5a79c1SDavid du Colombier 		snprint(envname, sizeof envname, "/env/%s", v->name);
199dc5a79c1SDavid du Colombier 		if((f = Creat(envname))<0)
200dc5a79c1SDavid du Colombier 			pfmt(err, "rc: can't open %s: %r\n", envname);
201dc5a79c1SDavid du Colombier 		else{
202dc5a79c1SDavid du Colombier 			for(w = v->val;w;w = w->next)
203dc5a79c1SDavid du Colombier 				write(f, w->word, strlen(w->word)+1L);
204dc5a79c1SDavid du Colombier 			close(f);
205dc5a79c1SDavid du Colombier 		}
206dc5a79c1SDavid du Colombier 	}
207dc5a79c1SDavid du Colombier 	if(v->fnchanged){
208dc5a79c1SDavid du Colombier 		v->fnchanged = 0;
209dc5a79c1SDavid du Colombier 		snprint(envname, sizeof envname, "/env/fn#%s", v->name);
210dc5a79c1SDavid du Colombier 		if((f = Creat(envname))<0)
211dc5a79c1SDavid du Colombier 			pfmt(err, "rc: can't open %s: %r\n", envname);
212dc5a79c1SDavid du Colombier 		else{
213dc5a79c1SDavid du Colombier 			if(v->fn){
214dc5a79c1SDavid du Colombier 				fd = openfd(f);
215fed0fa9eSDavid du Colombier 				pfmt(fd, "fn %q %s\n", v->name, v->fn[v->pc-1].s);
216dc5a79c1SDavid du Colombier 				closeio(fd);
217dc5a79c1SDavid du Colombier 			}
218dc5a79c1SDavid du Colombier 			close(f);
219dc5a79c1SDavid du Colombier 		}
220dc5a79c1SDavid du Colombier 	}
221dc5a79c1SDavid du Colombier }
222dc5a79c1SDavid du Colombier 
223dc5a79c1SDavid du Colombier void
updenvlocal(var * v)224dc5a79c1SDavid du Colombier updenvlocal(var *v)
225dc5a79c1SDavid du Colombier {
226dc5a79c1SDavid du Colombier 	if(v){
227dc5a79c1SDavid du Colombier 		updenvlocal(v->next);
228dc5a79c1SDavid du Colombier 		addenv(v);
229dc5a79c1SDavid du Colombier 	}
230dc5a79c1SDavid du Colombier }
231dc5a79c1SDavid du Colombier 
232dc5a79c1SDavid du Colombier void
Updenv(void)233dc5a79c1SDavid du Colombier Updenv(void)
234dc5a79c1SDavid du Colombier {
235dc5a79c1SDavid du Colombier 	var *v, **h;
236dc5a79c1SDavid du Colombier 	for(h = gvar;h!=&gvar[NVAR];h++)
237dc5a79c1SDavid du Colombier 		for(v=*h;v;v = v->next)
238dc5a79c1SDavid du Colombier 			addenv(v);
239dc5a79c1SDavid du Colombier 	if(runq)
240dc5a79c1SDavid du Colombier 		updenvlocal(runq->local);
241dc5a79c1SDavid du Colombier }
242dc5a79c1SDavid du Colombier 
243dc5a79c1SDavid du Colombier int
ForkExecute(char * file,char ** argv,int sin,int sout,int serr)244dc5a79c1SDavid du Colombier ForkExecute(char *file, char **argv, int sin, int sout, int serr)
245dc5a79c1SDavid du Colombier {
246dc5a79c1SDavid du Colombier 	int pid;
247dc5a79c1SDavid du Colombier 
248dc5a79c1SDavid du Colombier {int i;
249dc5a79c1SDavid du Colombier fprint(2, "forkexec %s", file);
250dc5a79c1SDavid du Colombier for(i = 0; argv[i]; i++)fprint(2, " %s", argv[i]);
251dc5a79c1SDavid du Colombier fprint(2, " %d %d %d\n", sin, sout, serr);
252dc5a79c1SDavid du Colombier }
253dc5a79c1SDavid du Colombier 	if(access(file, 1) != 0)
254dc5a79c1SDavid du Colombier 		return -1;
255dc5a79c1SDavid du Colombier fprint(2, "forking\n");
256dc5a79c1SDavid du Colombier 	switch(pid = fork()){
257dc5a79c1SDavid du Colombier 	case -1:
258dc5a79c1SDavid du Colombier 		return -1;
259dc5a79c1SDavid du Colombier 	case 0:
260dc5a79c1SDavid du Colombier 		if(sin >= 0)
261dc5a79c1SDavid du Colombier 			dup(sin, 0);
262dc5a79c1SDavid du Colombier 		else
263dc5a79c1SDavid du Colombier 			close(0);
264dc5a79c1SDavid du Colombier 		if(sout >= 0)
265dc5a79c1SDavid du Colombier 			dup(sout, 1);
266dc5a79c1SDavid du Colombier 		else
267dc5a79c1SDavid du Colombier 			close(1);
268dc5a79c1SDavid du Colombier 		if(serr >= 0)
269dc5a79c1SDavid du Colombier 			dup(serr, 2);
270dc5a79c1SDavid du Colombier 		else
271dc5a79c1SDavid du Colombier 			close(2);
272dc5a79c1SDavid du Colombier fprint(2, "execing\n");
273dc5a79c1SDavid du Colombier 		exec(file, argv);
274dc5a79c1SDavid du Colombier fprint(2, "exec: %r\n");
275dc5a79c1SDavid du Colombier 		exits(file);
276dc5a79c1SDavid du Colombier 	}
277dc5a79c1SDavid du Colombier 	return pid;
278dc5a79c1SDavid du Colombier }
279dc5a79c1SDavid du Colombier 
280dc5a79c1SDavid du Colombier void
Execute(word * args,word * path)281dc5a79c1SDavid du Colombier Execute(word *args, word *path)
282dc5a79c1SDavid du Colombier {
283dc5a79c1SDavid du Colombier 	char **argv = mkargv(args);
284dc5a79c1SDavid du Colombier 	char file[1024];
285dc5a79c1SDavid du Colombier 	int nc;
286dc5a79c1SDavid du Colombier 	Updenv();
287dc5a79c1SDavid du Colombier 	for(;path;path = path->next){
288dc5a79c1SDavid du Colombier 		nc = strlen(path->word);
289dc5a79c1SDavid du Colombier 		if(nc<1024){
290dc5a79c1SDavid du Colombier 			strcpy(file, path->word);
291dc5a79c1SDavid du Colombier 			if(file[0]){
292dc5a79c1SDavid du Colombier 				strcat(file, "/");
293dc5a79c1SDavid du Colombier 				nc++;
294dc5a79c1SDavid du Colombier 			}
295dc5a79c1SDavid du Colombier 			if(nc+strlen(argv[1])<1024){
296dc5a79c1SDavid du Colombier 				strcat(file, argv[1]);
297dc5a79c1SDavid du Colombier 				exec(file, argv+1);
298dc5a79c1SDavid du Colombier 			}
299dc5a79c1SDavid du Colombier 			else werrstr("command name too long");
300dc5a79c1SDavid du Colombier 		}
301dc5a79c1SDavid du Colombier 	}
302dc5a79c1SDavid du Colombier 	rerrstr(file, sizeof file);
303dc5a79c1SDavid du Colombier 	pfmt(err, "%s: %s\n", argv[1], file);
304dc5a79c1SDavid du Colombier 	efree((char *)argv);
305dc5a79c1SDavid du Colombier }
306dc5a79c1SDavid du Colombier #define	NDIR	256		/* shoud be a better way */
307dc5a79c1SDavid du Colombier 
308dc5a79c1SDavid du Colombier int
Globsize(char * p)309dc5a79c1SDavid du Colombier Globsize(char *p)
310dc5a79c1SDavid du Colombier {
31173e742d7SDavid du Colombier 	int isglob = 0, globlen = NDIR+1;
312dc5a79c1SDavid du Colombier 	for(;*p;p++){
313dc5a79c1SDavid du Colombier 		if(*p==GLOB){
314dc5a79c1SDavid du Colombier 			p++;
315dc5a79c1SDavid du Colombier 			if(*p!=GLOB)
316dc5a79c1SDavid du Colombier 				isglob++;
317dc5a79c1SDavid du Colombier 			globlen+=*p=='*'?NDIR:1;
318dc5a79c1SDavid du Colombier 		}
319dc5a79c1SDavid du Colombier 		else
320dc5a79c1SDavid du Colombier 			globlen++;
321dc5a79c1SDavid du Colombier 	}
322dc5a79c1SDavid du Colombier 	return isglob?globlen:0;
323dc5a79c1SDavid du Colombier }
324dc5a79c1SDavid du Colombier #define	NFD	50
325dc5a79c1SDavid du Colombier #define	NDBUF	32
326dc5a79c1SDavid du Colombier struct{
327dc5a79c1SDavid du Colombier 	Dir	*dbuf;
328dc5a79c1SDavid du Colombier 	int	i;
329dc5a79c1SDavid du Colombier 	int	n;
330dc5a79c1SDavid du Colombier }dir[NFD];
331dc5a79c1SDavid du Colombier 
332dc5a79c1SDavid du Colombier int
Opendir(char * name)333dc5a79c1SDavid du Colombier Opendir(char *name)
334dc5a79c1SDavid du Colombier {
335dc5a79c1SDavid du Colombier 	Dir *db;
336dc5a79c1SDavid du Colombier 	int f;
337dc5a79c1SDavid du Colombier 	f = open(name, 0);
338dc5a79c1SDavid du Colombier 	if(f==-1)
339dc5a79c1SDavid du Colombier 		return f;
340dc5a79c1SDavid du Colombier 	db = dirfstat(f);
341dc5a79c1SDavid du Colombier 	if(db!=nil && (db->mode&DMDIR)){
342dc5a79c1SDavid du Colombier 		if(f<NFD){
343dc5a79c1SDavid du Colombier 			dir[f].i = 0;
344dc5a79c1SDavid du Colombier 			dir[f].n = 0;
345dc5a79c1SDavid du Colombier 		}
346dc5a79c1SDavid du Colombier 		free(db);
347dc5a79c1SDavid du Colombier 		return f;
348dc5a79c1SDavid du Colombier 	}
349dc5a79c1SDavid du Colombier 	free(db);
350dc5a79c1SDavid du Colombier 	close(f);
351dc5a79c1SDavid du Colombier 	return -1;
352dc5a79c1SDavid du Colombier }
353dc5a79c1SDavid du Colombier 
354dc5a79c1SDavid du Colombier static int
trimdirs(Dir * d,int nd)355dc5a79c1SDavid du Colombier trimdirs(Dir *d, int nd)
356dc5a79c1SDavid du Colombier {
357dc5a79c1SDavid du Colombier 	int r, w;
358dc5a79c1SDavid du Colombier 
359dc5a79c1SDavid du Colombier 	for(r=w=0; r<nd; r++)
360dc5a79c1SDavid du Colombier 		if(d[r].mode&DMDIR)
361dc5a79c1SDavid du Colombier 			d[w++] = d[r];
362dc5a79c1SDavid du Colombier 	return w;
363dc5a79c1SDavid du Colombier }
364dc5a79c1SDavid du Colombier 
365dc5a79c1SDavid du Colombier /*
366dc5a79c1SDavid du Colombier  * onlydirs is advisory -- it means you only
367dc5a79c1SDavid du Colombier  * need to return the directories.  it's okay to
368dc5a79c1SDavid du Colombier  * return files too (e.g., on unix where you can't
369dc5a79c1SDavid du Colombier  * tell during the readdir), but that just makes
370dc5a79c1SDavid du Colombier  * the globber work harder.
371dc5a79c1SDavid du Colombier  */
372dc5a79c1SDavid du Colombier int
Readdir(int f,void * p,int onlydirs)373276e7d6dSDavid du Colombier Readdir(int f, void *p, int onlydirs)
374dc5a79c1SDavid du Colombier {
375dc5a79c1SDavid du Colombier 	int n;
376dc5a79c1SDavid du Colombier 
377dc5a79c1SDavid du Colombier 	if(f<0 || f>=NFD)
378dc5a79c1SDavid du Colombier 		return 0;
379dc5a79c1SDavid du Colombier Again:
380dc5a79c1SDavid du Colombier 	if(dir[f].i==dir[f].n){	/* read */
381dc5a79c1SDavid du Colombier 		free(dir[f].dbuf);
382dc5a79c1SDavid du Colombier 		dir[f].dbuf = 0;
383dc5a79c1SDavid du Colombier 		n = dirread(f, &dir[f].dbuf);
384dc5a79c1SDavid du Colombier 		if(n>0){
385dc5a79c1SDavid du Colombier 			if(onlydirs){
386dc5a79c1SDavid du Colombier 				n = trimdirs(dir[f].dbuf, n);
387dc5a79c1SDavid du Colombier 				if(n == 0)
388dc5a79c1SDavid du Colombier 					goto Again;
389dc5a79c1SDavid du Colombier 			}
390dc5a79c1SDavid du Colombier 			dir[f].n = n;
391dc5a79c1SDavid du Colombier 		}else
392dc5a79c1SDavid du Colombier 			dir[f].n = 0;
393dc5a79c1SDavid du Colombier 		dir[f].i = 0;
394dc5a79c1SDavid du Colombier 	}
395dc5a79c1SDavid du Colombier 	if(dir[f].i == dir[f].n)
396dc5a79c1SDavid du Colombier 		return 0;
397dc5a79c1SDavid du Colombier 	strcpy(p, dir[f].dbuf[dir[f].i].name);
398dc5a79c1SDavid du Colombier 	dir[f].i++;
399dc5a79c1SDavid du Colombier 	return 1;
400dc5a79c1SDavid du Colombier }
401dc5a79c1SDavid du Colombier 
402dc5a79c1SDavid du Colombier void
Closedir(int f)403dc5a79c1SDavid du Colombier Closedir(int f)
404dc5a79c1SDavid du Colombier {
405dc5a79c1SDavid du Colombier 	if(f>=0 && f<NFD){
406dc5a79c1SDavid du Colombier 		free(dir[f].dbuf);
407dc5a79c1SDavid du Colombier 		dir[f].i = 0;
408dc5a79c1SDavid du Colombier 		dir[f].n = 0;
409dc5a79c1SDavid du Colombier 		dir[f].dbuf = 0;
410dc5a79c1SDavid du Colombier 	}
411dc5a79c1SDavid du Colombier 	close(f);
412dc5a79c1SDavid du Colombier }
413dc5a79c1SDavid du Colombier int interrupted = 0;
414dc5a79c1SDavid du Colombier void
notifyf(void *,char * s)415dc5a79c1SDavid du Colombier notifyf(void*, char *s)
416dc5a79c1SDavid du Colombier {
417dc5a79c1SDavid du Colombier 	int i;
418dc5a79c1SDavid du Colombier 	for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
419dc5a79c1SDavid du Colombier 		if(strncmp(s, "sys: ", 5)!=0) interrupted = 1;
420dc5a79c1SDavid du Colombier 		goto Out;
421dc5a79c1SDavid du Colombier 	}
422dc5a79c1SDavid du Colombier 	pfmt(err, "rc: note: %s\n", s);
423dc5a79c1SDavid du Colombier 	noted(NDFLT);
424dc5a79c1SDavid du Colombier 	return;
425dc5a79c1SDavid du Colombier Out:
426dc5a79c1SDavid du Colombier 	if(strcmp(s, "interrupt")!=0 || trap[i]==0){
427dc5a79c1SDavid du Colombier 		trap[i]++;
428dc5a79c1SDavid du Colombier 		ntrap++;
429dc5a79c1SDavid du Colombier 	}
430dc5a79c1SDavid du Colombier 	if(ntrap>=32){	/* rc is probably in a trap loop */
431dc5a79c1SDavid du Colombier 		pfmt(err, "rc: Too many traps (trap %s), aborting\n", s);
432dc5a79c1SDavid du Colombier 		abort();
433dc5a79c1SDavid du Colombier 	}
434dc5a79c1SDavid du Colombier 	noted(NCONT);
435dc5a79c1SDavid du Colombier }
436dc5a79c1SDavid du Colombier 
437dc5a79c1SDavid du Colombier void
Trapinit(void)438dc5a79c1SDavid du Colombier Trapinit(void)
439dc5a79c1SDavid du Colombier {
440dc5a79c1SDavid du Colombier 	notify(notifyf);
441dc5a79c1SDavid du Colombier }
442dc5a79c1SDavid du Colombier 
443dc5a79c1SDavid du Colombier void
Unlink(char * name)444dc5a79c1SDavid du Colombier Unlink(char *name)
445dc5a79c1SDavid du Colombier {
446dc5a79c1SDavid du Colombier 	remove(name);
447dc5a79c1SDavid du Colombier }
448dc5a79c1SDavid du Colombier 
449dc5a79c1SDavid du Colombier long
Write(int fd,void * buf,long cnt)450276e7d6dSDavid du Colombier Write(int fd, void *buf, long cnt)
451dc5a79c1SDavid du Colombier {
452dc5a79c1SDavid du Colombier 	return write(fd, buf, (long)cnt);
453dc5a79c1SDavid du Colombier }
454dc5a79c1SDavid du Colombier 
455dc5a79c1SDavid du Colombier long
Read(int fd,void * buf,long cnt)456276e7d6dSDavid du Colombier Read(int fd, void *buf, long cnt)
457dc5a79c1SDavid du Colombier {
458dc5a79c1SDavid du Colombier 	return read(fd, buf, cnt);
459dc5a79c1SDavid du Colombier }
460dc5a79c1SDavid du Colombier 
461dc5a79c1SDavid du Colombier long
Seek(int fd,long cnt,long whence)462dc5a79c1SDavid du Colombier Seek(int fd, long cnt, long whence)
463dc5a79c1SDavid du Colombier {
464dc5a79c1SDavid du Colombier 	return seek(fd, cnt, whence);
465dc5a79c1SDavid du Colombier }
466dc5a79c1SDavid du Colombier 
467dc5a79c1SDavid du Colombier int
Executable(char * file)468dc5a79c1SDavid du Colombier Executable(char *file)
469dc5a79c1SDavid du Colombier {
470dc5a79c1SDavid du Colombier 	Dir *statbuf;
471dc5a79c1SDavid du Colombier 	int ret;
472dc5a79c1SDavid du Colombier 
473dc5a79c1SDavid du Colombier 	statbuf = dirstat(file);
474dc5a79c1SDavid du Colombier 	if(statbuf == nil)
475dc5a79c1SDavid du Colombier 		return 0;
476dc5a79c1SDavid du Colombier 	ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0);
477dc5a79c1SDavid du Colombier 	free(statbuf);
478dc5a79c1SDavid du Colombier 	return ret;
479dc5a79c1SDavid du Colombier }
480dc5a79c1SDavid du Colombier 
481dc5a79c1SDavid du Colombier int
Creat(char * file)482dc5a79c1SDavid du Colombier Creat(char *file)
483dc5a79c1SDavid du Colombier {
484dc5a79c1SDavid du Colombier 	return create(file, 1, 0666L);
485dc5a79c1SDavid du Colombier }
486dc5a79c1SDavid du Colombier 
487dc5a79c1SDavid du Colombier int
Dup(int a,int b)488dc5a79c1SDavid du Colombier Dup(int a, int b)
489dc5a79c1SDavid du Colombier {
490dc5a79c1SDavid du Colombier 	return dup(a, b);
491dc5a79c1SDavid du Colombier }
492dc5a79c1SDavid du Colombier 
493dc5a79c1SDavid du Colombier int
Dup1(int)494dc5a79c1SDavid du Colombier Dup1(int)
495dc5a79c1SDavid du Colombier {
496dc5a79c1SDavid du Colombier 	return -1;
497dc5a79c1SDavid du Colombier }
498dc5a79c1SDavid du Colombier 
499dc5a79c1SDavid du Colombier void
Exit(char * stat)500dc5a79c1SDavid du Colombier Exit(char *stat)
501dc5a79c1SDavid du Colombier {
502dc5a79c1SDavid du Colombier 	Updenv();
503dc5a79c1SDavid du Colombier 	setstatus(stat);
504dc5a79c1SDavid du Colombier 	exits(truestatus()?"":getstatus());
505dc5a79c1SDavid du Colombier }
506dc5a79c1SDavid du Colombier 
507dc5a79c1SDavid du Colombier int
Eintr(void)508dc5a79c1SDavid du Colombier Eintr(void)
509dc5a79c1SDavid du Colombier {
510dc5a79c1SDavid du Colombier 	return interrupted;
511dc5a79c1SDavid du Colombier }
512dc5a79c1SDavid du Colombier 
513dc5a79c1SDavid du Colombier void
Noerror(void)514dc5a79c1SDavid du Colombier Noerror(void)
515dc5a79c1SDavid du Colombier {
516dc5a79c1SDavid du Colombier 	interrupted = 0;
517dc5a79c1SDavid du Colombier }
518dc5a79c1SDavid du Colombier 
519dc5a79c1SDavid du Colombier int
Isatty(int fd)520dc5a79c1SDavid du Colombier Isatty(int fd)
521dc5a79c1SDavid du Colombier {
522dc5a79c1SDavid du Colombier 	Dir *d1, *d2;
523dc5a79c1SDavid du Colombier 	int ret;
524dc5a79c1SDavid du Colombier 
525dc5a79c1SDavid du Colombier 	d1 = dirfstat(fd);
526dc5a79c1SDavid du Colombier 	if(d1 == nil)
527dc5a79c1SDavid du Colombier 		return 0;
528dc5a79c1SDavid du Colombier 	if(strncmp(d1->name, "ptty", 4)==0){	/* fwd complaints to philw */
529dc5a79c1SDavid du Colombier 		free(d1);
530dc5a79c1SDavid du Colombier 		return 1;
531dc5a79c1SDavid du Colombier 	}
532dc5a79c1SDavid du Colombier 	d2 = dirstat("/dev/cons");
533dc5a79c1SDavid du Colombier 	if(d2 == nil){
534dc5a79c1SDavid du Colombier 		free(d1);
535dc5a79c1SDavid du Colombier 		return 0;
536dc5a79c1SDavid du Colombier 	}
537dc5a79c1SDavid du Colombier 	ret = (d1->type==d2->type&&d1->dev==d2->dev&&d1->qid.path==d2->qid.path);
538dc5a79c1SDavid du Colombier 	free(d1);
539dc5a79c1SDavid du Colombier 	free(d2);
540dc5a79c1SDavid du Colombier 	return ret;
541dc5a79c1SDavid du Colombier }
542dc5a79c1SDavid du Colombier 
543dc5a79c1SDavid du Colombier void
Abort(void)544dc5a79c1SDavid du Colombier Abort(void)
545dc5a79c1SDavid du Colombier {
546dc5a79c1SDavid du Colombier 	pfmt(err, "aborting\n");
547dc5a79c1SDavid du Colombier 	flush(err);
548dc5a79c1SDavid du Colombier 	Exit("aborting");
549dc5a79c1SDavid du Colombier }
550dc5a79c1SDavid du Colombier 
551dc5a79c1SDavid du Colombier void
Memcpy(void * a,void * b,long n)552276e7d6dSDavid du Colombier Memcpy(void *a, void *b, long n)
553dc5a79c1SDavid du Colombier {
554276e7d6dSDavid du Colombier 	memmove(a, b, n);
555dc5a79c1SDavid du Colombier }
556dc5a79c1SDavid du Colombier 
557dc5a79c1SDavid du Colombier void*
Malloc(ulong n)558dc5a79c1SDavid du Colombier Malloc(ulong n)
559dc5a79c1SDavid du Colombier {
560dc5a79c1SDavid du Colombier 	return malloc(n);
561dc5a79c1SDavid du Colombier }
562