summaryrefslogtreecommitdiff
path: root/kernel/syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/syscalls.c')
-rw-r--r--kernel/syscalls.c161
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 :