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