// remember to sync this with interface/syscalls.c #include "lib/string/string.h" #include "lib/printf/printf.h" #include "fs/ext2.h" #include "kernel.h" #include "driver/vesa.h" #include "fifo.h" #include "fd.h" #include "fs/elf.h" #include "driver/terminal.h" #include "driver/screen.h" #include #include #include #include #include "syscalls.h" #include "scheduler.h" #include "log.h" #include "timer.h" #include "mount.h" #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 bool open_fd[MAX_PID][MAX_FD]; void fd_init_std_streams(uint32_t pid,bool fb) { static bool first=true; if(pid==0&&first) { first=false; //stdin / stdout /stderr fds[0][0]=fd_from_ringbuffer(); if(!fb) // ega text mode { fds[0][1]=fd_from_term(); fds[0][2]=fd_from_term(); } else { fds[0][1]=fd_from_fb_term(); fds[0][2]=fd_from_fb_term(); } open_fd[0][0]=true; open_fd[0][1]=true; open_fd[0][2]=true; } else { fds[pid][0]=fds[0][0]; fds[pid][1]=fds[0][1]; fds[pid][2]=fds[0][2]; open_fd[pid][0]=true; open_fd[pid][1]=true; open_fd[pid][2]=true; } } // /** errno helper */ void set_errno(int no) { struct _reent *impure_ptr=VMEM_USER_NEWLIB; impure_ptr->_errno=no; } /** get string represnation of syscall */ char* syscall_get_name(uint32_t num) { switch(num) { case 60: return "SYSCALL_EXIT"; case 66: return "SYSCALL_CLOSE"; case 64: return "SYSCALL_EXECVE"; case 72: return "SYSCALL_FORK"; case 78: return "SYSCALL_GETPID"; case 68: return "SYSCALL_ISATTY"; case 82: return "SYSCALL_LINK"; case 69: return "SYSCALL_LSEEK"; case 65: return "SYSCALL_OPEN"; case 62: return "SYSCALL_READ"; case 70: return "SYSCALL_SBRK"; case 74: return "SYSCALL_STAT"; case 67: return "SYSCALL_FSTAT"; case 79: return "SYSCALL_LSTAT"; case 75: return "SYSCALL_TIMES"; case 76: return "SYSCALL_UNLINK"; case 77: return "SYSCALL_WAIT"; case 61: return "SYSCALL_WRITE"; case 71: return "SYSCALL_GETTIMEOFDAY"; case 63: return "SYSCALL_READDIR"; case 73: return "SYSCALL_KILL"; case 80: return "SYSCALL_CLONE"; case 84: return "SYSCALL_PIPE"; case 86: return "SYSCALL_DUP2"; } kpanic("UNKNOWN SYSCALL NUM"); } int syscall_gettimeofday(struct timeval *tv, struct timezone *tz,uint32_t none1, uint32_t pid) { if(tv!=NULL) { uint64_t t=timer_get_ms(); tv->tv_sec=t/1000+2*3600; // add gmt+2 tv->tv_usec=0;//t-tv->tv_sec*1000; } // tz struct is obsolote if(tz!=NULL) { tz->tz_minuteswest=0;// -21*60; // warsaw tz->tz_dsttime=DST_NONE; } return 0; } 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; dat[1]+=ptr; return dat[1]; } kpanic("not fully handled lseek! dir=%d",dir); return 0; } // TODO: /dev/console or /dev/tty1 - /dev/ttyN int syscall_write(int file, char *buf, int len,uint32_t pid) { for(int i=0;ist_mode = S_IFCHR; return 0; } uint32_t syscall_pipe(uint32_t *addr,int none1, int none2, uint32_t pid) { fd pipfds[2]; int ret=fds_from_pipe(pipfds); int fd1=nextfd(pid); int fd2=nextfd(pid); fds[pid][fd1]=pipfds[0] ; *addr=fd1; addr++; fds[pid][fd2]=pipfds[1] ; *addr=fd2; return ret; } uint32_t syscall_dup2(uint32_t oldfd,int newfd, int none2, uint32_t pid) { fds[pid][newfd]=fd_dupl(&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])||fd_eof(&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(p1,p2,p3,pid); case SYSCALL_CLOSE : return syscall_close(p1,p2,p3,pid); case SYSCALL_EXECVE : return syscall_execve(p1,p2,p3,pid); case SYSCALL_FORK : return syscall_fork(p1,p2,p3,pid); case SYSCALL_CLONE : 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,pid); case SYSCALL_LINK : // return syscall_link(p1,p2,p3); return -1; case SYSCALL_LSEEK : return syscall_lseek(p1,p2,p3,pid); case SYSCALL_OPEN : return syscall_open(p1,p2,p3,pid); case SYSCALL_READ : 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,pid); case SYSCALL_FSTAT : return syscall_stat(p1,p2,p3,pid); case SYSCALL_LSTAT : return syscall_stat(p1,p2,p3,pid); case SYSCALL_TIMES : // return syscall_times(p1,p2,p3); return -1; case SYSCALL_UNLINK : // return syscall_unlink(p1,p2,p3); return -1; case SYSCALL_WAIT : return syscall_wait(p1,p2,p3,pid); case SYSCALL_WRITE : return syscall_write(p1,p2,p3,pid); case SYSCALL_GETTIMEOFDAY: return syscall_gettimeofday(p1,p2,p3,pid); case SYSCALL_READDIR : 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,p2,p3,pid); case SYSCALL_DUP2 : return syscall_dup2(p1,p2,p3,pid); } kpanic("unknown syscall"); }