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 };