summaryrefslogtreecommitdiff
path: root/kernel/syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/syscalls.c')
-rw-r--r--kernel/syscalls.c139
1 files changed, 117 insertions, 22 deletions
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
index 1c1d2c7..e73f89c 100644
--- a/kernel/syscalls.c
+++ b/kernel/syscalls.c
@@ -31,6 +31,8 @@
//TODO move to process.c and implement per process //
static fd fds[MAX_PID][MAX_FD];
+//static uint32_t opendir_pos[MAX_PID][MAX_FD];
+//static char opendir_name[MAX_PID][MAX_FD][256];
static int tty[MAX_PID]; // keep track of /dev/tty fd for each process :P
static bool open_fd[MAX_PID][MAX_FD];
@@ -55,6 +57,19 @@ void fd_init_std_streams(uint32_t pid)
}
//
+/** helper */
+int nextfd(int pid)
+{
+ for(int i=0;i<MAX_FD;i++)
+ {
+ if(!open_fd[pid][i])
+ {
+ open_fd[pid][i]=true;
+ return i;
+ }
+ }
+ return -1;
+}
/** errno helper */
void set_errno(int no)
{
@@ -107,6 +122,8 @@ char* syscall_get_name(uint32_t num)
return "SYSCALL_GETTIMEOFDAY";
case SYSCALL_READDIR:
return "SYSCALL_READDIR";
+ case SYSCALL_OPENDIR:
+ return "SYSCALL_OPENDIR";
case SYSCALL_KILL:
return "SYSCALL_KILL";
case SYSCALL_CLONE:
@@ -121,8 +138,12 @@ char* syscall_get_name(uint32_t num)
return "SYSCALL_GUI_WIN";
case SYSCALL_SELECT:
return "SYSCALL_SELECT";
+ case SYSCALL_TCGETATTR:
+ return "SYSCALL_TCGETATTR";
+ case SYSCALL_TCSETATTR:
+ return "SYSCALL_TCSETATTR";
case SYSCALL_UNIMPLEMENTED:
- return "SYSCALL_UNKNOWN";
+ return "SYSCALL_UNIMPLEMENTED";
}
kpanic("UNKNOWN SYSCALL NUM: %d",num);
}
@@ -154,8 +175,21 @@ int syscall_lseek(int file,int ptr,int dir,uint32_t pid)
dat[1]+=ptr;
return dat[1];
}
+ else if(dir==SEEK_SET)
+ {
+ uint32_t *dat=fds[pid][file].data;
+ dat[1]=ptr;
+ return dat[1];
+ }
+ else if(dir==SEEK_END)
+ {
+ kpanic("SEEK_END dir for lseek!");
+ }
+ else
+ {
+ kpanic("wrong dir for lseek!");
+ }
- kpanic("not fully handled lseek! dir=%d",dir);
return 0;
}
@@ -177,12 +211,40 @@ int syscall_write(int file, char *buf, int len,uint32_t pid)
*/
int syscall_read(int file, char *buf, int len,uint32_t pid)
{
+ int ret=0;
+
if(!open_fd[pid][file])kpanic("reading from closed file descriptor");
if(fd_eof(&fds[pid][file]))return 0;
- *buf=fd_read(&fds[pid][file]);
- return 1;
+
+ while((fd_has(&fds[pid][file])||fd_eof(&fds[pid][file]))&&len-->0)
+ {
+ if(fd_eof(&fds[pid][file]))return ret;
+ *buf++=fd_read(&fds[pid][file]);
+ ret++;
+ }
+ return ret;
}
+ /**
+ * Monitor multiple descriptors
+ * ============================
+ *
+ * nfds is the MAX file descriptor number +1.
+ *
+ * It is possible to provide 3 different sets of filedescriptors
+ * (they can be NULL as well)
+ *
+ * - readfds - reading
+ * - writefds - writing
+ * - exceptfds - exceptions (all cleared unless exception occurs)
+ *
+ * The call returns the total number of descriptors contained in all
+ * sets after returning.
+ *
+ * This call will block until time (timeout) runs out
+ * OR a file descriptor becomes ready.
+ */
+
int syscall_select(int maxxfd,struct timeval *tv, fd_set **fd_sets, uint32_t pid, bool test)
{
int ret=0;
@@ -251,15 +313,47 @@ int syscall_select(int maxxfd,struct timeval *tv, fd_set **fd_sets, uint32_t pid
}
-//TODO: replace with dirent!
-int syscall_readdir(const char *name,fs_dirent *dirs,int *pos,uint32_t pid)
+//TODO: use fd and inode (instead of path)... now this is a crazy trick how it works..
+//is it that bad??? yes it was bad and vim crashed so we changed to even more hacky approach now.. :( :(
+//ok it was other reason but we should not use it ...
+//since userspace might zero or reuse dirent* and corrupt our DIR* ! TODO TODO TODO danger!
+struct dirent *syscall_opendir(const char *name,struct dirent *dirs,int none,uint32_t pid)
{
- int ret=mount_read_dir(name, dirs, pos);
+ strcpy(dirs->dirname,name);
+ if(dirs->dirname[strlen(dirs->dirname)-1]=='/')dirs->dirname[strlen(dirs->dirname)-1]=0;
+ klog("syscall to opendir(%s)",dirs->dirname);
+
+ // test if exists....
+ struct dirent testdirent;
+ uint32_t testpos;
+ int ret=mount_read_dir(dirs->dirname, &testdirent, &testpos);
if(ret==-1)
{
+ // no it does not!
set_errno(ENOENT);
+ return NULL;
}
- return ret;
+
+ dirs->pos=0;
+
+ /*
+ uint32_t fdn=nextfd(pid);
+ strcpy(opendir_name[pid][fdn],dirs->dirname);
+ opendir_pos[pid][fdn]=0;
+ */
+
+ return dirs;
+}
+
+struct dirent *syscall_readdir(struct dirent *dirs,int none1, int none2,uint32_t pid)
+{
+ // this dirent will get filled with next entry...
+ int ret=mount_read_dir(dirs->dirname, dirs, &dirs->pos);
+
+ // no more entries
+ if(ret==0)return NULL;
+
+ return dirs;
}
/** execve helper */
@@ -327,22 +421,10 @@ int syscall_execve(const char *name, char *const argv[], char *const env[], int
return 0;
}
-/** helper */
-int nextfd(int pid)
-{
- for(int i=0;i<MAX_FD;i++)
- {
- if(!open_fd[pid][i])
- {
- open_fd[pid][i]=true;
- return i;
- }
- }
- return -1;
-}
int syscall_open(char *name, int flags, int mode,uint32_t pid)
{
+ klog("open %s",name);
if(!strcmp("/dev/tty",name))return tty[pid];
uint32_t fdn=nextfd(pid);
@@ -434,6 +516,10 @@ uint32_t syscall_sbrk(uint32_t incr, int none1, int none2, uint32_t pid)
uint32_t oldalloc=alloc;
alloc+=incr;
task_set_brk(pid,alloc);
+
+ uint32_t max_addy=VMEM_USER_PROG+VMEM_USER_PROG_PAGES*4096;
+
+ if(alloc>max_addy)kpanic("can not set sbrk . TODO: dynamic allocation!");
fixme("fake syscall_sbrk(0x%08X) return %08X",incr,oldalloc);
return oldalloc;
}
@@ -568,7 +654,9 @@ uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3,
uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
{
-// klog("processing syscall [%s] for pid:%d",syscall_get_name(nr),pid);
+#ifdef LOG_SYSCALLS
+ klog("processing syscall [%s] for pid:%d",syscall_get_name(nr),pid);
+#endif
switch(nr){
case SYSCALL_EXIT :
@@ -617,6 +705,8 @@ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint
return syscall_gettimeofday(p1,p2,p3,pid);
case SYSCALL_READDIR :
return syscall_readdir(p1,p2,p3,pid);
+ case SYSCALL_OPENDIR :
+ return syscall_opendir(p1,p2,p3,pid);
case SYSCALL_KILL :
// return task_kill(p1,p2,p3);
return -1;
@@ -634,6 +724,11 @@ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint
return syscall_tcgetattr(p1,p2,p3,pid);
case SYSCALL_TCSETATTR:
return syscall_tcsetattr(p1,p2,p3,pid);
+ case SYSCALL_UNIMPLEMENTED:
+ if(!strcmp(p1,"fcntl")){
+ klog("todo: quickfix hack for fcntl");
+ }
+
}
klog("unknown syscall %s / %d we just return 0",p1,nr);
return 0;