#define FOOLOS_MODULE_NAME "syscalls" #include "lib/logger/log.h" #include "fs/fs.h" #include "fs/ext2.h" #include "kernel/kernel.h" #include "kernel/config.h" #include #include #include #include int syscall_unhandled(int nr) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"syscall: %d", nr); panic(FOOLOS_MODULE_NAME,"unhandled syscall (generic handler)"); } int syscall_gettimeofday(struct timeval *tv, struct timezone *tz) { if(tv!=NULL) { uint32_t t=timer_get_ms(); tv->tv_sec=t/1000; tv->tv_usec=0;//t-tv->tv_sec*1000; } if(tz!=NULL) { tz->tz_minuteswest=0; tz->tz_dsttime=DST_NONE; } return 0; } int syscall_lseek(int file,int ptr,int dir) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"lseek (file=%d, ptr=%d, dir=%d)", file,ptr,dir); #endif panic(FOOLOS_MODULE_NAME,"unhandled syscall: lseek"); return 0; } // TODO: /dev/console or /dev/tty1 - /dev/ttyN int syscall_write(int file, char *buf, int len) { lock_spin(2); //x86_int_disable(); #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] write(file=%d, buf=0x%08X, len=%d)", task_get_current_pid(),file,buf,len); #endif if(file!=1&&file!=2) panic(FOOLOS_MODULE_NAME,"unhandled syscall: write (only stdout and stderr)"); //stderr and stdout go to console for(int i=0;istd_out,buf[i]); } lock_release(2); //x86_int_enable(); return len; } int syscall_read(int file, char *buf, int len) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"read(file=%d, buf=0x%08X, len=%d)", file,buf,len); #endif // stdin TODO: other descroptiors! if(file!=0) panic(FOOLOS_MODULE_NAME,"unhandled syscall: read (only stdin)"); char c; int l=0; while(1) { while(!fifo_has(&get_fool()->std_in)); c=fifo_get(&get_fool()->std_in); *buf=c; buf++; l++; if(l==len)return l; if(c=='\n')return l; } } //TODO: replace with dirent! int syscall_readdir(const char *name,fs_dirent *dirs,int max) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"readdir(name=0x%08X, dirs=0x%08X, %d)", name,dirs,max); #endif return fs_readdir(name,dirs,max); } // for non blocking io? int syscall_has_data_waiting(int file) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"has data waiting?"); #endif return fifo_has(&get_fool()->std_in); } int syscall_tune(int v1,int v2, int v3) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"tuning request"); #endif 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; } int copy_args(char **in, char **out) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"copy_args(0x%08x, 0x%08X)",in,out); int count=0; while(in[count]!=NULL) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"args(0x%08x: %s)",in[count],out); count++; }; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"copy_args : count: %d",count); char **pos=out; pos+=sizeof(char **)*(count+1); int i=0; do{ int l=strlen(in[i]); char *var=pos; memcpy(var,in[i],l+1); pos+=sizeof(char *)*(l+1); out[i]=var; i++; }while(in[i]!=NULL); out[i]=NULL; return count; } int syscall_execve(char *name, char **argv, char **env) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"execve (name=0x%08X(%s), argvs=0x%08X, env=0x%08X)", name,name,argv,env); #endif int arg_count=0; while(argv[arg_count]!=NULL)arg_count++; char **argv1=kballoc(1); char **env1=kballoc(1); copy_args(argv,argv1); copy_args(env,env1); uint32_t alloc; uint32_t entry_global=load_elf(name,&alloc); task_set_brk(alloc); if(!entry_global) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"execve: bailing out!"); #endif return -1; // errror loading } /* try to move this to asm */ // asm volatile("jmp ."); // loop forever log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"returning to jump addy (0x%08X)", entry_global); asm volatile("mov $0x8fff000,%esp"); // set stack at high end of process image asm volatile ("push %0" :: "r" (argv1)); asm volatile ("push %0" :: "r" (arg_count)); asm volatile ("push %0" :: "r" (kballoc(1))); asm volatile ("push %0" :: "r" (env1)); // push addr and return to it asm volatile ("pushl %0"::"r"(entry_global)); asm volatile ("sti"); asm volatile ("ret"); // this is never reached! } int syscall_open(char *name, int flags, int mode) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"open (name=0x%08X(\"%s\"), flags=%d, mode=%d)",name, name,flags,mode); #endif panic(FOOLOS_MODULE_NAME,"unhandled syscall: open"); } //newcomers // int syscall_close(int file,int none1,int none2) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"close (file=%d)", file); #endif if(file!=0&&file!=1&&file!=2) panic(FOOLOS_MODULE_NAME,"unhandled syscall: close"); return -1; } // TODO: check if file is termminal! int syscall_isatty(int file,int none1,int none2) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"isatty (file=%d)", file); #endif return 1; } uint32_t fuckalloc=0x8500000; // TODO: per process basis! uint32_t syscall_sbrk(int incr, int none1, int none2) { uint32_t alloc=task_get_brk(); uint32_t oldalloc=fuckalloc; fuckalloc+=incr; task_set_brk(alloc); #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"sbrk (incr=%d) = 0x%08X", incr,oldalloc); #endif return oldalloc; } // stat, fstat, lstat int syscall_stat(const char *path, struct stat *st,int none) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"stat (path=0x%08X,stat=0x%08X)", path,st); #endif st->st_mode = S_IFCHR; return 0; } int syscall_fstat(int file, struct stat *st,int none) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"fstat (file=%d,stat=0x%08X)", file,st); #endif st->st_mode = S_IFCHR; return 0; } int syscall_lstat(const char *path, struct stat *st,int none) { #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"lstat (path=0x%08X,stat=0x%08X)", path,st); #endif st->st_mode = S_IFCHR; return 0; }