diff options
Diffstat (limited to 'kernel/syscalls.c')
| -rw-r--r-- | kernel/syscalls.c | 273 |
1 files changed, 109 insertions, 164 deletions
diff --git a/kernel/syscalls.c b/kernel/syscalls.c index b5dd6df..dfcdaae 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -1,3 +1,5 @@ +// remember to sync this with interface/syscalls.c + #include "lib/string/string.h" #include "lib/printf/printf.h" #include "fs/ext2.h" @@ -20,6 +22,30 @@ #include "mem.h" #include "reent.h" #include "errno.h" +#include "stdstreams.h" + +#define MAX_PID 200 + +//TODO move to process.c and implement per process // +static fd fds[MAX_PID][MAX_FD]; +static uint32_t next_fd[MAX_PID]; + +void fd_init_std_streams(uint32_t pid) +{ + if(pid==0) + { + //stdin / stdout /stderr + fds[0][next_fd[0]++]=fd_from_ringbuffer(); + fds[0][next_fd[0]++]=fd_from_fb_term(); + fds[0][next_fd[0]++]=fd_from_fb_term(); + } + else + { + fds[pid][0]=fds[0][0]; + fds[pid][1]=fds[0][1]; + fds[pid][2]=fds[0][2]; + } +} /** errno helper */ void set_errno(int no) @@ -28,17 +54,7 @@ void set_errno(int no) impure_ptr->_errno=no; } -static fd fds[MAX_FD]; -static uint32_t next_fd=0; - -// fifos for backing up some file descrpitors -static fifo fifos[MAX_FIFOS]; -static uint32_t next_fifo=0; - -// screen / terminal -term_out screen; -terminal_tty tty1; - +/** get string represnation of syscall */ char* syscall_get_name(uint32_t num) { switch(num) @@ -89,18 +105,13 @@ char* syscall_get_name(uint32_t num) return "SYSCALL_CLONE"; case 84: return "SYSCALL_PIPE"; + case 86: + return "SYSCALL_DUP2"; } - return "UNKNOWN SYSCALL NUM"; -} - -int syscall_unhandled(int nr) -{ - char msg[256]; - tfp_sprintf(msg, "unhandled syscall : %d",nr); - kpanic("%s",msg); + kpanic("UNKNOWN SYSCALL NUM"); } -int syscall_gettimeofday(struct timeval *tv, struct timezone *tz) +int syscall_gettimeofday(struct timeval *tv, struct timezone *tz,uint32_t none1, uint32_t pid) { if(tv!=NULL) { @@ -118,7 +129,7 @@ int syscall_gettimeofday(struct timeval *tv, struct timezone *tz) return 0; } -int syscall_lseek(int file,int ptr,int dir) +int syscall_lseek(int file,int ptr,int dir,uint32_t pid) { #ifndef SEEK_SET @@ -133,7 +144,7 @@ int syscall_lseek(int file,int ptr,int dir) if(dir==SEEK_CUR) { - uint32_t *dat=fds[file].data; + uint32_t *dat=fds[pid][file].data; dat[1]+=ptr; return dat[1]; } @@ -143,11 +154,11 @@ int syscall_lseek(int file,int ptr,int dir) } // TODO: /dev/console or /dev/tty1 - /dev/ttyN -int syscall_write(int file, char *buf, int len) +int syscall_write(int file, char *buf, int len,uint32_t pid) { for(int i=0;i<len;i++) { - fd_write(&fds[file],buf[i]); + fd_write(&fds[pid][file],buf[i]); } return len; } @@ -156,15 +167,15 @@ int syscall_write(int file, char *buf, int len) * __read()__ attemts to read up to _len_ bytes from file descriptor _file_ * into the buffer starting at _buf_. */ -int syscall_read(int file, char *buf, int len) +int syscall_read(int file, char *buf, int len,uint32_t pid) { - if(fd_eof(&fds[file]))return 0; - *buf=fd_read(&fds[file]); + if(fd_eof(&fds[pid][file]))return 0; + *buf=fd_read(&fds[pid][file]); return 1; } //TODO: replace with dirent! -int syscall_readdir(const char *name,fs_dirent *dirs,int *pos) +int syscall_readdir(const char *name,fs_dirent *dirs,int *pos,uint32_t pid) { int ret=mount_read_dir(name, dirs, pos); if(ret==-1) @@ -174,35 +185,7 @@ int syscall_readdir(const char *name,fs_dirent *dirs,int *pos) return ret; } -// for non blocking io? -int syscall_poll(int file) -{ - file=2; //workaround - - return fd_has(&fds[file]); -} - -// TODO: DELETE THIS SHIT! -int syscall_tune(int v1,int v2, int v3) -{ - - // osbolete - /* - if(v1==0) // regular tty mode - { - get_fool()->tty->set_buff=true; - get_fool()->tty->set_echo=true; - } - if(v1==1) // gaming tty mode - { - get_fool()->tty->set_buff=false; - get_fool()->tty->set_echo=false; - } - */ - - return 0; -} - +/** execve helper */ int copy_args(char **in, char **out) { //klog("copy_args(0x%08x, 0x%08X)",in,out); @@ -233,6 +216,7 @@ int copy_args(char **in, char **out) } /** does not return on success otherwise -1 and errrno set */ +// int execve(const char *filename, char *const argv[], char *const envp[]); int syscall_execve(const char *name, char *const argv[], char *const env[], int pid) { @@ -264,98 +248,54 @@ int syscall_execve(const char *name, char *const argv[], char *const env[], int return 0; } -// minihack -int get_max_fd() +int syscall_open(char *name, int flags, int mode,uint32_t pid) { - return next_fd-1; + fds[pid][next_fd[pid]]=mount_file_open(name); + if(*(uint32_t *)fds[pid][next_fd[pid]].data==0)return -1; + + next_fd[pid]++; + return next_fd[pid]-1; } -// TODO: support other files too (not only fifo pipes) -// TODO: allow opening existing files/named pipes -int syscall_open(char *name, int flags, int mode) +// pid_t fork(void); +uint32_t syscall_fork(int none1, int none2, int none3, int pid) { - if( next_fifo>=MAX_FIFOS || next_fd>=MAX_FD)kpanic("we ran out of fd's or fifo's"); - - bool create_fifo=true; - if(name[0]!='~')create_fifo=false; - - if(create_fifo) - { - - if(!strcmp(name,"~term")) - { - screen.put_char=console_put_char; - screen.update_cursor=update_cursor; - - tty1=terminal_init(&screen,NULL); - - fifos[next_fifo].data=&tty1; - fifos[next_fifo].put=terminal_put; - - fds[next_fd]=fd_from_fifo(&fifos[next_fifo]); - } - else if(!strcmp(name,"~xterm")) - { - screen.put_char=vesa_console_put_char; - screen.update_cursor=vesa_update_cursor; - - tty1=terminal_init(&screen,NULL); - - fifos[next_fifo].data=&tty1; - fifos[next_fifo].put=terminal_put; - - fds[next_fd]=fd_from_fifo(&fifos[next_fifo]); - } - else - { - fifos[next_fifo]=fifo_create_buffered(1); - fds[next_fd]=fd_from_fifo(&fifos[next_fifo]); - } - - next_fifo++; - } - else - { - fds[next_fd]=mount_file_open(name); - if(*(uint32_t *)fds[next_fd].data==0)return -1; - } - - next_fd++; - return next_fd-1; + uint32_t newpid=task_fork(pid); + fds[newpid][0]=fds[pid][0]; + fds[newpid][1]=fds[pid][1]; + fds[newpid][2]=fds[pid][2]; + return newpid; } -uint32_t syscall_fork(int pid) -{ - return task_fork(pid); -} -uint32_t syscall_clone(int pid) +uint32_t syscall_clone(int none1, int none2, int none3, int pid) { return task_clone(pid); } -uint32_t syscall_wait(int pid) +uint32_t syscall_wait(int none1, int none2, int none3, int pid) { return 0; } -uint32_t syscall_exit(int pid) +// void _exit(int status) +uint32_t syscall_exit(int status, uint32_t none1, uint32_t none2,int pid) { fixme("free allll mem"); + klog("pid %d exited with %d",pid,status); task_exit(pid); return 0; } -//newcomers -// -int syscall_close(int file,int none1,int none2) +// int close (int fd) (TODO; close or not to close open filedescirptors?) +int syscall_close(int file,int none1,int none2,int pid) { if(file<3)return 0; - fd_close(&fds[file]); + fd_close(&fds[pid][file]); return 0; } -// TODO: check if file is termminal! -int syscall_isatty(int file,int none1,int none2) +// TODO: check if file is a termminal! +int syscall_isatty(int file,int none1,int none2,int pid) { return 1; } @@ -372,83 +312,86 @@ uint32_t syscall_sbrk(uint32_t incr, int none1, int none2, uint32_t pid) } // stat, fstat, lstat -int syscall_stat(const char *path, struct stat *st,int none) +int syscall_stat(const char *path, struct stat *st,int none,uint32_t pid) { st->st_mode = S_IFCHR; return 0; } -/// there also is task_fork, task_wait, task_exit.. which is in scheduler.c -//////////////////////////////////////// -uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) -{ - switch(nr){ - case SYSCALL_WAIT : - return !task_runs(p1); - case SYSCALL_READ : - return fd_has(&fds[p1]); - case SYSCALL_EXIT : - return 1; - } - return 1; -} -uint32_t syscall_pipe(uint32_t *addr) +uint32_t syscall_pipe(uint32_t *addr,int none1, int none2, uint32_t pid) { - if( next_fifo>=MAX_FIFOS || next_fd>=MAX_FD)kpanic("we ran out of fd's or fifo's"); fd pipfds[2]; int ret=fds_from_pipe(pipfds); - fds[next_fd]=pipfds[0] ; - *addr=next_fd; + fds[pid][next_fd[pid]]=pipfds[0] ; + *addr=next_fd[pid]; addr++; - next_fd++; - if( next_fifo>=MAX_FIFOS || next_fd>=MAX_FD)kpanic("we ran out of fd's or fifo's"); + next_fd[pid]++; - fds[next_fd]=pipfds[1] ; - *addr=next_fd; - next_fd++; + fds[pid][next_fd[pid]]=pipfds[1] ; + *addr=next_fd[pid]; + next_fd[pid]++; return ret; +} + +uint32_t syscall_dup2(uint32_t oldfd,int newfd, int none2, uint32_t pid) +{ + fds[pid][newfd]=fds[pid][oldfd]; + return newfd; +} + +/** Generics */ +uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) +{ + switch(nr){ + case SYSCALL_WAIT : + return !task_runs(p1); + case SYSCALL_READ : + return fd_has(&fds[pid][p1]); + } + return 1;//other syscalls never block for now. } +/** Generics */ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) { switch(nr){ case SYSCALL_EXIT : - return syscall_exit(pid); + return syscall_exit(p1,p2,p3,pid); case SYSCALL_CLOSE : - return syscall_close(p1,p2,p3); + return syscall_close(p1,p2,p3,pid); case SYSCALL_EXECVE : return syscall_execve(p1,p2,p3,pid); case SYSCALL_FORK : - return syscall_fork(pid); + return syscall_fork(p1,p2,p3,pid); case SYSCALL_CLONE : - return syscall_clone(pid); + return syscall_clone(p1,p2,p3,pid); case SYSCALL_GETPID : // return syscall_getpid(p1,p2,p3); return -1; case SYSCALL_ISATTY : - return syscall_isatty(p1,p2,p3); + return syscall_isatty(p1,p2,p3,pid); case SYSCALL_LINK : // return syscall_link(p1,p2,p3); return -1; case SYSCALL_LSEEK : - return syscall_lseek(p1,p2,p3); + return syscall_lseek(p1,p2,p3,pid); case SYSCALL_OPEN : - return syscall_open(p1,p2,p3); + return syscall_open(p1,p2,p3,pid); case SYSCALL_READ : - return syscall_read(p1,p2,p3); + return syscall_read(p1,p2,p3,pid); case SYSCALL_SBRK : return syscall_sbrk(p1,p2,p3,pid); case SYSCALL_STAT : - return syscall_stat(p1,p2,p3); + return syscall_stat(p1,p2,p3,pid); case SYSCALL_FSTAT : - return syscall_stat(p1,p2,p3); + return syscall_stat(p1,p2,p3,pid); case SYSCALL_LSTAT : - return syscall_stat(p1,p2,p3); + return syscall_stat(p1,p2,p3,pid); case SYSCALL_TIMES : // return syscall_times(p1,p2,p3); return -1; @@ -456,18 +399,20 @@ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint // return syscall_unlink(p1,p2,p3); return -1; case SYSCALL_WAIT : - return syscall_wait(pid); + return syscall_wait(p1,p2,p3,pid); case SYSCALL_WRITE : - return syscall_write(p1,p2,p3); + return syscall_write(p1,p2,p3,pid); case SYSCALL_GETTIMEOFDAY: - return syscall_gettimeofday(p1,p2); + return syscall_gettimeofday(p1,p2,p3,pid); case SYSCALL_READDIR : - return syscall_readdir(p1,p2,p3); + return syscall_readdir(p1,p2,p3,pid); case SYSCALL_KILL : // return task_kill(p1,p2,p3); return -1; case SYSCALL_PIPE : - return syscall_pipe(p1); + return syscall_pipe(p1,p2,p3,pid); + case SYSCALL_DUP2 : + return syscall_dup2(p1,p2,p3,pid); } kpanic("unknown syscall"); } |
