#define FOOLOS_MODULE_NAME "syscalls" #include "lib/buffer/ringbuffer.h" #include "lib/logger/log.h" #include "lib/bool/bool.h" #include "fs/fs.h" #include "fs/ext2.h" #include "kernel/console.h" #include "kernel/config.h" #include int syscall_unhandled(int nr) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"syscall: %d", nr); panic(FOOLOS_MODULE_NAME,"unhandled syscall"); } 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"); return 0; } // TODO: /dev/console or /dev/tty1 - /dev/ttyN int syscall_write(int file, char *buf, int len) { //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"); //stderr and stdout go to console for(int i=0;i0) { console_del_char(); buf--; l--; } } else{ *buf=c; buf++; l++; if(c!=0x04)console_put_char_white(c); if(c=='\n')return l; if(c==0x04) { l--; buf--; eof=true; 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); } int syscall_execve(char *name, char **argv1, char **env1) { int temp=0x1; uint32_t *entry=temp; temp+=4; char *force_argv[]={"",NULL}; char *force_env[]={"PS1=$","PWD=/home/miguel","PATH=/bin",NULL}; if(argv1==NULL)argv1=force_argv; if(env1==NULL)env1=force_env; int env_count=0; do{env_count++;}while(env1[env_count]!=NULL); int arg_count=0; do{arg_count++;}while(argv1[arg_count]!=NULL); char **env=temp; temp+=sizeof(char **)*(env_count+1); char **argv=temp; temp+=sizeof(char **)*(arg_count+1); int i=0; do{ int l=strlen(env1[i]); char *env_var=temp; temp+=sizeof(char *)*(l+1); memcpy(env_var,env1[i],l+1); env[i]=env_var; i++; }while(env1[i]!=NULL); env[i]=NULL; i=0; do{ int l=strlen(argv1[i]); char *arg_var=temp; temp+=sizeof(char *)*(l+1); memcpy(arg_var,argv1[i],l+1); argv[i]=arg_var; i++; }while(argv1[i]!=NULL); argv[i]=NULL; #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"execve (name=0x%08X(%s), argvs=0x%08X, env=0x%08X)", name,name,argv1,env1); #endif if(!entry) { #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 ."); asm volatile("mov $0x8fff000,%esp"); // set stack at high end of process image uint32_t alloc; *entry=load_elf(name,&alloc); // TODO: avoid code duplication for argv and env!! char **env_new=alloc; alloc+=sizeof(char **)*(env_count+1); i=0; do{ int l=strlen(env[i]); char *env_var=alloc; alloc+=sizeof(char)*l+1; memcpy(env_var,env[i],l+1); env_new[i]=env_var; #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"envr %d : 0x%08X : %s" ,i,env_new[i],env_new[i]); #endif i++; }while(env[i]!=NULL); env_new[i]=NULL; char **argv_new=alloc; alloc+=sizeof(char **)*(arg_count+1); i=0; do{ int l=strlen(argv[i]); char *arg_var=alloc; alloc+=sizeof(char)*l+1; memcpy(arg_var,argv[i],l+1); argv_new[i]=arg_var; #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"arg %d : 0x%08X : %s" ,i,argv_new[i],argv_new[i]); #endif i++; }while(argv[i]!=NULL); #ifdef LOG_SYSCALLS log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"argc: %d" ,arg_count); #endif task_set_brk(alloc); asm volatile ("push %0" :: "r" (argv_new)); asm volatile ("push %0" :: "r" (arg_count)); asm volatile ("push %0" :: "r" (env_new)); // push addr and return to it asm volatile ("push %0"::"r"(*entry)); 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"); } //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"); 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; } // TODO: per process basis! uint32_t syscall_sbrk(int incr, int none1, int none2) { uint32_t alloc=task_get_brk(); uint32_t oldalloc=alloc; alloc+=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; }