diff options
Diffstat (limited to 'kernel/syscalls.c')
| -rw-r--r-- | kernel/syscalls.c | 161 |
1 files changed, 125 insertions, 36 deletions
diff --git a/kernel/syscalls.c b/kernel/syscalls.c index 507be13..228b70a 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -24,6 +24,7 @@ #include "errno.h" #include "compositor.h" #include "stdstreams.h" +#include "sys/unistd.h" #define MAX_PID 200 @@ -65,58 +66,60 @@ char* syscall_get_name(uint32_t num) { switch(num) { - case 60: + case SYSCALL_EXIT: return "SYSCALL_EXIT"; - case 66: + case SYSCALL_CLOSE: return "SYSCALL_CLOSE"; - case 64: + case SYSCALL_EXECVE: return "SYSCALL_EXECVE"; - case 72: + case SYSCALL_FORK: return "SYSCALL_FORK"; - case 78: + case SYSCALL_GETPID: return "SYSCALL_GETPID"; - case 68: + case SYSCALL_ISATTY: return "SYSCALL_ISATTY"; - case 82: + case SYSCALL_LINK: return "SYSCALL_LINK"; - case 69: + case SYSCALL_LSEEK: return "SYSCALL_LSEEK"; - case 65: + case SYSCALL_OPEN: return "SYSCALL_OPEN"; - case 62: + case SYSCALL_READ: return "SYSCALL_READ"; - case 70: + case SYSCALL_SBRK: return "SYSCALL_SBRK"; - case 74: + case SYSCALL_STAT: return "SYSCALL_STAT"; - case 67: + case SYSCALL_FSTAT: return "SYSCALL_FSTAT"; - case 79: + case SYSCALL_LSTAT: return "SYSCALL_LSTAT"; - case 75: + case SYSCALL_TIMES: return "SYSCALL_TIMES"; - case 76: + case SYSCALL_UNLINK: return "SYSCALL_UNLINK"; - case 77: + case SYSCALL_WAIT: return "SYSCALL_WAIT"; - case 61: + case SYSCALL_WRITE: return "SYSCALL_WRITE"; - case 71: + case SYSCALL_GETTIMEOFDAY: return "SYSCALL_GETTIMEOFDAY"; - case 63: + case SYSCALL_READDIR: return "SYSCALL_READDIR"; - case 73: + case SYSCALL_KILL: return "SYSCALL_KILL"; - case 80: + case SYSCALL_CLONE: return "SYSCALL_CLONE"; - case 84: + case SYSCALL_PIPE: return "SYSCALL_PIPE"; - case 86: + case SYSCALL_DUP2: return "SYSCALL_DUP2"; - case 87: + case SYSCALL_GUI_RECT: return "SYSCALL_GUI_RECT"; - case 88: + case SYSCALL_GUI_WIN: return "SYSCALL_GUI_WIN"; + case SYSCALL_SELECT: + return "SYSCALL_SELECT"; } kpanic("UNKNOWN SYSCALL NUM"); } @@ -142,16 +145,6 @@ int syscall_gettimeofday(struct timeval *tv, struct timezone *tz,uint32_t none1, int syscall_lseek(int file,int ptr,int dir,uint32_t pid) { -#ifndef SEEK_SET -#define SEEK_SET 0 /* set file offset to offset */ -#endif -#ifndef SEEK_CUR -#define SEEK_CUR 1 /* set file offset to current plus offset */ -#endif -#ifndef SEEK_END -#define SEEK_END 2 /* set file offset to EOF plus offset */ -#endif - if(dir==SEEK_CUR) { uint32_t *dat=fds[pid][file].data; @@ -187,6 +180,71 @@ int syscall_read(int file, char *buf, int len,uint32_t pid) return 1; } +int syscall_select(int maxxfd,struct timeval *tv, fd_set **fd_sets, uint32_t pid, bool test) +{ + int ret=0; + + // TODO: wake when timeout runs out! + + if(!test) + { + if(tv==NULL)klog("select with infinite timeout"); + else klog ("select with timeout: sec=%d, usec=%d",tv->tv_sec,tv->tv_usec); + } + + for(int i=0;i<maxxfd;i++) + { + if(FD_ISSET(i,fd_sets[0])) + { + // klog("%d in readfds",i); + if(fd_has(&fds[pid][i])||fd_eof(&fds[pid][i])) + { + ret++; + } + else + { + if(!test)FD_CLR(i,fd_sets[0]); + } + } + if(FD_ISSET(i,fd_sets[1])) + { +// klog("%d in writefds",i); + + if(fd_can_write(&fds[pid][i])) + { + ret++; + } + else + { + if(!test)FD_CLR(i,fd_sets[1]); + } + } + + if(FD_ISSET(i,fd_sets[2])) + { + // klog("%d in exceptfds",i); // TODO! + } + } + + if(!test)FD_ZERO(fd_sets[2]); // we dont give a shit about exceptions! :P TODO!!! + + if(test&&ret==0&&tv!=NULL) // check if time did not run out already + { + uint64_t t=timer_get_ms(); // current time in milliseconds (10^-3) + + uint64_t t0=0; + t0+=tv->tv_sec*1000; // seconds * 10^3 + t0+=tv->tv_usec/1000; // microseconds * 10^-3 + + if(t>t0)return 1; // ready to fire! + } + + return ret; + + + +} + //TODO: replace with dirent! int syscall_readdir(const char *name,fs_dirent *dirs,int *pos,uint32_t pid) { @@ -404,6 +462,8 @@ uint32_t syscall_pipe(uint32_t *addr,int none1, int none2, uint32_t pid) uint32_t syscall_dup2(uint32_t oldfd,int newfd, int none2, uint32_t pid) { + if(newfd==0xffffffff)klog("dup mode not supported yet !!!"); + fds[pid][newfd]=fd_dupl(&fds[pid][oldfd]); return newfd; } @@ -424,6 +484,31 @@ uint32_t syscall_gui_win(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) } /** Generics */ +uint32_t syscall_generic_prep(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) +{ + struct timeval *tv=p2; + + switch(nr){ + case SYSCALL_SELECT : + + // change to absolute time for easier timout + if(tv!=NULL) + { + uint64_t t=timer_get_ms(); // current time in milliseconds (10^-3) + t+=tv->tv_sec*1000; // seconds * 10^3 + t+=tv->tv_usec/1000; // microseconds * 10^-3 + + tv->tv_sec=t/1000; + tv->tv_usec=(t%1000)*1000; + + } + + break; + } + return 1; +} + +/** Generics */ uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) { switch(nr){ @@ -433,6 +518,8 @@ uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, return fd_has(&fds[pid][p1])||fd_eof(&fds[pid][p1]); case SYSCALL_WRITE : return fd_can_write(&fds[pid][p1]); + case SYSCALL_SELECT : + return syscall_select(p1,p2,p3,pid,true); } return 1;//other syscalls never block for now. @@ -495,6 +582,8 @@ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint return syscall_pipe(p1,p2,p3,pid); case SYSCALL_DUP2 : return syscall_dup2(p1,p2,p3,pid); + case SYSCALL_SELECT : + return syscall_select(p1,p2,p3,pid,false); case SYSCALL_GUI_RECT : return syscall_gui_rect(p1,p2,p3,pid); case SYSCALL_GUI_WIN : |
