9os

Experimental kernel using plan9 ideas for embedded device
git clone git://git.simple-cc.org/9os
Log | Files | Refs | README | LICENSE

syscall.c (1294B)


      1 #include <os9/os9.h>
      2 
      3 #include <stdarg.h>
      4 #include <errno.h>
      5 
      6 static int
      7 validmode(int mode)
      8 {
      9 	if ((mode & O_READ) &&  (mode & (O_WRITE | O_RDWR)))
     10 		goto err;
     11 	if ((mode & O_WRITE) && (mode & (O_READ | O_RDWR)))
     12 		goto err;
     13 	if ((mode & O_RDWR) && (mode & (O_READ | O_WRITE)))
     14 		goto err;
     15 	if (mode  == 0)
     16 		goto err;
     17 	return 1;
     18 
     19 err:
     20 	seterror(EINVAL);
     21 	return 0;
     22 }
     23 
     24 static int
     25 newfd(Chan *c, int mode)
     26 {
     27 	int fd;
     28 	Chan **bp;
     29 	Fdset *fds = proc->fds;
     30 
     31 	lock(&fds->m);
     32 	for (bp = fds->fdset; bp < &fds->fdset[NR_CHANS]; ++bp) {
     33 		if (*bp == c)
     34 			break;
     35 	}
     36 	if (bp == &fds->fdset[NR_CHANS]) {
     37 		seterror(EMFILE);
     38 		unlock(&fds->m);
     39 		return -1;
     40 	}
     41 
     42 	fd = bp - fds->fdset;
     43 	fds->fdset[fd] = c;
     44 	unlock(&fds->m);
     45 
     46 	return fd;
     47 }
     48 
     49 static int
     50 validaddr(void *addr, int len, int write)
     51 {
     52 	/* TODO */
     53 	return 1;
     54 }
     55 
     56 static int
     57 sysopen(int nargs, ...)
     58 {
     59 	char *fname;
     60 	int mode, flags, fd;
     61 	va_list va;
     62 	Chan *c;
     63 
     64 	va_start(va, nargs);
     65 	fname = (char *) va_arg(va, uintptr_t);
     66 	mode = va_arg(va, uintptr_t);
     67 	flags = va_arg(va, uintptr_t);
     68 	va_end(va);
     69 
     70 	if (!validmode(mode))
     71 		return -1;
     72 	if (!validaddr(fname, 1, 0))
     73 		return -1;
     74 	if ((c = namec(fname, mode)) == NULL)
     75 		return -1;
     76 	if ((fd = newfd(c, mode)) < 0)
     77 		return -1;
     78 	return fd;
     79 }
     80 
     81 struct syscall systab[] = {
     82 	[SYSOPEN] = 3, sysopen,
     83 };