xref: /plan9-contrib/sys/src/cmd/vi/syscall.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define Extern extern
6 #include "mips.h"
7 #undef CHDIR
8 
9 char 	errbuf[ERRLEN];
10 ulong	nofunc;
11 
12 #define	SYSR1		0
13 #define	ERRSTR		1
14 #define	BIND		2
15 #define	CHDIR		3
16 #define	CLOSE		4
17 #define	DUP		5
18 #define	ALARM		6
19 #define	EXEC		7
20 #define	EXITS		8
21 #define	FORK		9
22 #define	FORKPGRP	10
23 #define	FSTAT		11
24 #define	SEGBRK		12
25 #define	MOUNT		13
26 #define	OPEN		14
27 #define	READ		15
28 #define	SEEK		16
29 #define	SLEEP		17
30 #define	STAT		18
31 #define	WAIT		19
32 #define	WRITE		20
33 #define	PIPE		21
34 #define	CREATE		22
35 #define	RFORK		23
36 #define	BRK_		24
37 #define	REMOVE		25
38 #define	WSTAT		26
39 #define	FWSTAT		27
40 #define	NOTIFY		28
41 #define	NOTED		29
42 #define SEGATTACH 	30
43 #define SEGDETACH 	31
44 #define SEGFREE   	32
45 #define SEGFLUSH	33
46 #define RENDEZVOUS	34
47 #define UNMOUNT		35
48 
49 char *sysctab[]={
50 	[SYSR1]		"Running",
51 	[ERRSTR]	"Errstr",
52 	[BIND]		"Bind",
53 	[CHDIR]		"Chdir",
54 	[CLOSE]		"Close",
55 	[DUP]		"Dup",
56 	[ALARM]		"Alarm",
57 	[EXEC]		"Exec",
58 	[EXITS]		"Exits",
59 	[FORK]		"Fork",
60 	[FORKPGRP]	"Forkpgrp",
61 	[FSTAT]		"Fstat",
62 	[SEGBRK]	"Segbrk",
63 	[MOUNT]		"Mount",
64 	[OPEN]		"Open",
65 	[READ]		"Read",
66 	[SEEK]		"Seek",
67 	[SLEEP]		"Sleep",
68 	[STAT]		"Stat",
69 	[WAIT]		"Wait",
70 	[WRITE]		"Write",
71 	[PIPE]		"Pipe",
72 	[CREATE]	"Create",
73 	[RFORK]		"Rfork",
74 	[BRK_]		"Brk",
75 	[REMOVE]	"Remove",
76 	[WSTAT]		"Wstat",
77 	[FWSTAT]	"Fwstat",
78 	[NOTIFY]	"Notify",
79 	[NOTED]		"Noted",
80 	[SEGATTACH]	"Segattach",
81 	[SEGDETACH]	"Segdetach",
82 	[SEGFREE]	"Segfree",
83 	[SEGFLUSH]	"Segflush",
84 	[RENDEZVOUS]	"Rendez",
85 	[UNMOUNT]	"Unmount",
86 };
87 
88 void sys1(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0); }
89 
90 void
91 syserrstr(void)
92 {
93 	ulong str;
94 
95 	str = getmem_w(reg.r[29]+4);
96 	if(sysdbg)
97 		itrace("errstr(0x%lux)", str);
98 
99 	memio(errbuf, str, ERRLEN, MemWrite);
100 	strcpy(errbuf, "no error");
101 	reg.r[1] = 0;
102 
103 }
104 void
105 sysbind(void)
106 {
107 	ulong pname, pold, flags;
108 	char name[1024], old[1024];
109 	int n;
110 
111 	pname = getmem_w(reg.r[29]+4);
112 	pold = getmem_w(reg.r[29]+8);
113 	flags = getmem_w(reg.r[29]+12);
114 	memio(name, pname, sizeof(name), MemReadstring);
115 	memio(old, pold, sizeof(old), MemReadstring);
116 	if(sysdbg)
117 		itrace("bind(0x%lux='%s', 0x%lux='%s', 0x%lux)", name, old, flags);
118 
119 	n = bind(name, old, flags);
120 	if(n < 0)
121 		errstr(errbuf);
122 
123 	reg.r[1] = n;
124 }
125 
126 void
127 syschdir(void)
128 {
129 	char file[1024];
130 	int n;
131 	ulong name;
132 
133 	name = getmem_w(reg.r[29]+4);
134 	memio(file, name, sizeof(file), MemReadstring);
135 	if(sysdbg)
136 		itrace("chdir(0x%lux='%s', 0x%lux)", name, file);
137 
138 	n = chdir(file);
139 	if(n < 0)
140 		errstr(errbuf);
141 
142 	reg.r[1] = n;
143 }
144 
145 void
146 sysclose(void)
147 {
148 	int n;
149 	ulong fd;
150 
151 	fd = getmem_w(reg.r[29]+4);
152 	if(sysdbg)
153 		itrace("close(%d)", fd);
154 
155 	n = close(fd);
156 	if(n < 0)
157 		errstr(errbuf);
158 	reg.r[1] = n;
159 }
160 
161 void
162 sysdup(void)
163 {
164 	int oldfd, newfd;
165 	int n;
166 
167 	oldfd = getmem_w(reg.r[29]+4);
168 	newfd = getmem_w(reg.r[29]+8);
169 	if(sysdbg)
170 		itrace("dup(%d, %d)", oldfd, newfd);
171 
172 	n = dup(oldfd, newfd);
173 	if(n < 0)
174 		errstr(errbuf);
175 	reg.r[1] = n;
176 }
177 
178 void
179 sysexits(void)
180 {
181 	char buf[ERRLEN];
182 	ulong str;
183 
184 	str = getmem_w(reg.r[29]+4);
185 	if(sysdbg)
186 		itrace("exits(0x%lux)", str);
187 
188 	count = 1;
189 	if(str != 0) {
190 		memio(buf, str, ERRLEN, MemRead);
191 		Bprint(bioout, "exits(%s)\n", buf);
192 	}
193 	else
194 		Bprint(bioout, "exits(0)\n");
195 }
196 
197 void
198 sysopen(void)
199 {
200 	char file[1024];
201 	int n;
202 	ulong mode, name;
203 
204 	name = getmem_w(reg.r[29]+4);
205 	mode = getmem_w(reg.r[29]+8);
206 	memio(file, name, sizeof(file), MemReadstring);
207 	if(sysdbg)
208 		itrace("open(0x%lux='%s', 0x%lux)", name, file, mode);
209 
210 	n = open(file, mode);
211 	if(n < 0)
212 		errstr(errbuf);
213 
214 	reg.r[1] = n;
215 };
216 
217 void
218 sysread(void)
219 {
220 	int fd;
221 	ulong size, a;
222 	char *buf, *p;
223 	int n, cnt, c;
224 
225 	fd = getmem_w(reg.r[29]+4);
226 	a = getmem_w(reg.r[29]+8);
227 	size = getmem_w(reg.r[29]+12);
228 
229 	buf = emalloc(size);
230 	if(fd == 0) {
231 		print("\nstdin>>");
232 		p = buf;
233 		n = 0;
234 		cnt = size;
235 		while(cnt) {
236 			c = Bgetc(bin);
237 			if(c <= 0)
238 				break;
239 			*p++ = c;
240 			n++;
241 			cnt--;
242 			if(c == '\n')
243 				break;
244 		}
245 	}
246 	else
247 		n = read(fd, buf, size);
248 
249 	if(n < 0)
250 		errstr(errbuf);
251 	else
252 		memio(buf, a, n, MemWrite);
253 
254 	if(sysdbg)
255 		itrace("read(%d, 0x%lux, %d) = %d", fd, a, size, n);
256 
257 	free(buf);
258 	reg.r[1] = n;
259 }
260 
261 void
262 sysseek(void)
263 {
264 	int fd, n;
265 	ulong off, mode;
266 
267 	fd = getmem_w(reg.r[29]+4);
268 	off = getmem_w(reg.r[29]+8);
269 	mode = getmem_w(reg.r[29]+12);
270 	if(sysdbg)
271 		itrace("seek(%d, %lud, %d)", fd, off, mode);
272 
273 	n = seek(fd, off, mode);
274 	if(n < 0)
275 		errstr(errbuf);
276 
277 	reg.r[1] = n;
278 }
279 
280 void
281 syssleep(void)
282 {
283 	ulong len;
284 	int n;
285 
286 	len = getmem_w(reg.r[29]+4);
287 	if(sysdbg)
288 		itrace("sleep(%d)", len);
289 
290 	n = sleep(len);
291 	if(n < 0)
292 		errstr(errbuf);
293 
294 	reg.r[1] = n;
295 }
296 
297 void
298 sysstat(void)
299 {
300 	char nambuf[1024];
301 	char buf[DIRLEN];
302 	ulong edir, name;
303 	int n;
304 
305 	name = getmem_w(reg.r[29]+4);
306 	edir = getmem_w(reg.r[29]+8);
307 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
308 	if(sysdbg)
309 		itrace("stat(0x%lux='%s', 0x%lux)", name, nambuf, edir);
310 
311 	n = stat(nambuf, buf);
312 	if(n < 0)
313 		errstr(errbuf);
314 	else
315 		memio(buf, edir, DIRLEN, MemWrite);
316 
317 	reg.r[1] = n;
318 }
319 
320 void
321 sysfstat(void)
322 {
323 	char buf[DIRLEN];
324 	ulong edir;
325 	int n, fd;
326 
327 	fd = getmem_w(reg.r[29]+4);
328 	edir = getmem_w(reg.r[29]+8);
329 	if(sysdbg)
330 		itrace("fstat(%d, 0x%lux)", fd, edir);
331 
332 	n = fstat(fd, buf);
333 	if(n < 0)
334 		errstr(errbuf);
335 	else
336 		memio(buf, edir, DIRLEN, MemWrite);
337 
338 	reg.r[1] = n;
339 }
340 
341 void
342 syswrite(void)
343 {
344 	int fd;
345 	ulong size, a;
346 	char *buf;
347 	int n;
348 
349 	fd = getmem_w(reg.r[29]+4);
350 	a = getmem_w(reg.r[29]+8);
351 	size = getmem_w(reg.r[29]+12);
352 	if(sysdbg)
353 		itrace("write(%d, %lux, %d)", fd, a, size);
354 
355 	buf = memio(0, a, size, MemRead);
356 	n = write(fd, buf, size);
357 	if(n < 0)
358 		errstr(errbuf);
359 	free(buf);
360 
361 	reg.r[1] = n;
362 }
363 
364 void
365 syspipe(void)
366 {
367 	int n, p[2];
368 	ulong fd;
369 
370 	fd = getmem_w(reg.r[29]+4);
371 	if(sysdbg)
372 		itrace("pipe(%lux)", fd);
373 
374 	n = pipe(p);
375 	if(n < 0)
376 		errstr(errbuf);
377 	else {
378 		putmem_w(fd, p[0]);
379 		putmem_w(fd+4, p[1]);
380 	}
381 	reg.r[1] = n;
382 }
383 
384 void
385 syscreate(void)
386 {
387 	char file[1024];
388 	int n;
389 	ulong mode, name, perm;
390 
391 	name = getmem_w(reg.r[29]+4);
392 	mode = getmem_w(reg.r[29]+8);
393 	perm = getmem_w(reg.r[29]+12);
394 	memio(file, name, sizeof(file), MemReadstring);
395 	if(sysdbg)
396 		itrace("create(0x%lux='%s', 0x%lux, 0x%lux)", name, file, mode, perm);
397 
398 	n = create(file, mode, perm);
399 	if(n < 0)
400 		errstr(errbuf);
401 
402 	reg.r[1] = n;
403 }
404 
405 void
406 sysbrk_(void)
407 {
408 	ulong addr, osize, nsize;
409 	Segment *s;
410 
411 	addr = getmem_w(reg.r[29]+4);
412 	if(sysdbg)
413 		itrace("brk_(0x%lux)", addr);
414 
415 	reg.r[1] = -1;
416 	if(addr < memory.seg[Data].base+datasize) {
417 		strcpy(errbuf, "address below segment");
418 		return;
419 	}
420 	if(addr > memory.seg[Stack].base) {
421 		strcpy(errbuf, "segment too big");
422 		return;
423 	}
424 	s = &memory.seg[Bss];
425 	if(addr > s->end) {
426 		osize = ((s->end-s->base)/BY2PG)*BY2WD;
427 		addr = ((addr)+(BY2PG-1))&~(BY2PG-1);
428 		s->end = addr;
429 		nsize = ((s->end-s->base)/BY2PG)*BY2WD;
430 		s->table = erealloc(s->table, osize, nsize);
431 	}
432 
433 	reg.r[1] = 0;
434 }
435 
436 void
437 sysremove(void)
438 {
439 	char nambuf[1024];
440 	ulong name;
441 	int n;
442 
443 	name = getmem_w(reg.r[29]+4);
444 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
445 	if(sysdbg)
446 		itrace("remove(0x%lux='%s')", name, nambuf);
447 
448 	n = remove(nambuf);
449 	if(n < 0)
450 		errstr(errbuf);
451 	reg.r[1] = n;
452 }
453 
454 void
455 sysnotify(void)
456 {
457 	nofunc = getmem_w(reg.r[29]+4);
458 	if(sysdbg)
459 		itrace("notify(0x%lux)\n", nofunc);
460 
461 	reg.r[1] = 0;
462 }
463 
464 void syswait(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0); }
465 void sysrfork(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
466 void syswstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
467 void sysfwstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
468 void sysnoted(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
469 void syssegattach(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
470 void syssegdetach(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
471 void syssegfree(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
472 void syssegflush(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
473 void sysrendezvous(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
474 void sysunmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
475 void sysfork(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
476 void sysforkpgrp(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
477 void syssegbrk(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
478 void sysmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
479 void sysalarm(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
480 void sysexec(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);}
481 
482 void (*systab[])(void)	={
483 	[SYSR1]		sys1,
484 	[ERRSTR]	syserrstr,
485 	[BIND]		sysbind,
486 	[CHDIR]		syschdir,
487 	[CLOSE]		sysclose,
488 	[DUP]		sysdup,
489 	[ALARM]		sysalarm,
490 	[EXEC]		sysexec,
491 	[EXITS]		sysexits,
492 	[FORK]		sysfork,
493 	[FORKPGRP]	sysforkpgrp,
494 	[FSTAT]		sysfstat,
495 	[SEGBRK]	syssegbrk,
496 	[MOUNT]		sysmount,
497 	[OPEN]		sysopen,
498 	[READ]		sysread,
499 	[SEEK]		sysseek,
500 	[SLEEP]		syssleep,
501 	[STAT]		sysstat,
502 	[WAIT]		syswait,
503 	[WRITE]		syswrite,
504 	[PIPE]		syspipe,
505 	[CREATE]	syscreate,
506 	[RFORK]		sysrfork,
507 	[BRK_]		sysbrk_,
508 	[REMOVE]	sysremove,
509 	[WSTAT]		syswstat,
510 	[FWSTAT]	sysfwstat,
511 	[NOTIFY]	sysnotify,
512 	[NOTED]		sysnoted,
513 	[SEGATTACH]	syssegattach,
514 	[SEGDETACH]	syssegdetach,
515 	[SEGFREE]	syssegfree,
516 	[SEGFLUSH]	syssegflush,
517 	[RENDEZVOUS]	sysrendezvous,
518 	[UNMOUNT]	sysunmount,
519 };
520 
521 void
522 Ssyscall(ulong inst)
523 {
524 	int call;
525 
526 	USED(inst);
527 	call = reg.r[1];
528 	if(call < 0 || call > UNMOUNT) {
529 		Bprint(bioout, "Bad system call\n");
530 		dumpreg();
531 	}
532 	if(trace)
533 		itrace("sysc\t%s", sysctab[call]);
534 
535 	(*systab[call])();
536 	Bflush(bioout);
537 }
538