From: John Hodge Date: Tue, 1 Mar 2011 06:42:05 +0000 (+0800) Subject: Usermode implementation of select() X-Git-Tag: rel0.10~177 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=2c1df972d9b8d2ccbffbc672d985bf8bda72f7ab;hp=22621d0f86a4b3ca5038e470f105d941fbbd7c62;p=tpg%2Facess2.git Usermode implementation of select() --- diff --git a/Kernel/include/syscalls.h b/Kernel/include/syscalls.h index 4cd733d6..bb80ffb1 100644 --- a/Kernel/include/syscalls.h +++ b/Kernel/include/syscalls.h @@ -63,6 +63,7 @@ enum eSyscalls { SYS_CHDIR, // Change current directory SYS_GETCWD, // Get current directory SYS_MOUNT, // Mount a filesystem + SYS_SELECT, // Wait for file handles NUM_SYSCALLS, SYS_DEBUG = 0x100 @@ -153,6 +154,7 @@ static const char *cSYSCALL_NAMES[] = { "SYS_CHDIR", "SYS_GETCWD", "SYS_MOUNT", + "SYS_SELECT", "" }; diff --git a/Kernel/include/syscalls.inc.asm b/Kernel/include/syscalls.inc.asm index d4fa7249..307e5829 100644 --- a/Kernel/include/syscalls.inc.asm +++ b/Kernel/include/syscalls.inc.asm @@ -54,3 +54,4 @@ %define SYS_CHDIR 81 ;Change current directory %define SYS_GETCWD 82 ;Get current directory %define SYS_MOUNT 83 ;Mount a filesystem +%define SYS_SELECT 84 ;Wait for file handles diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c index f930cdd4..6c62a927 100644 --- a/Kernel/syscalls.c +++ b/Kernel/syscalls.c @@ -301,6 +301,29 @@ void SyscallHandler(tSyscallRegs *Regs) (char*)Regs->Arg4 // Options ); break; + + // Wait on a set of handles + case SYS_SELECT: + // Sanity checks + if( (Regs->Arg2 && !Syscall_Valid(sizeof(fd_set), Regs->Arg2)) + || (Regs->Arg3 && !Syscall_Valid(sizeof(fd_set), Regs->Arg3)) + || (Regs->Arg4 && !Syscall_Valid(sizeof(fd_set), Regs->Arg4)) + || (Regs->Arg5 && !Syscall_Valid(sizeof(tTime), Regs->Arg5)) ) + { + err = -EINVAL; + ret = -1; + break; + } + // Perform the call + ret = VFS_Select( + Regs->Arg1, // Max handle + (fd_set *)Regs->Arg2, // Read + (fd_set *)Regs->Arg3, // Write + (fd_set *)Regs->Arg4, // Errors + (tTime *)Regs->Arg5, // Timeout + 0 // User handles + ); + break; // -- Debug //#if DEBUG_BUILD diff --git a/Kernel/syscalls.lst b/Kernel/syscalls.lst index cf299eaa..826249dc 100644 --- a/Kernel/syscalls.lst +++ b/Kernel/syscalls.lst @@ -61,3 +61,4 @@ SYS_TELL Return the current file position SYS_CHDIR Change current directory SYS_GETCWD Get current directory SYS_MOUNT Mount a filesystem +SYS_SELECT Wait for file handles diff --git a/Usermode/Libraries/ld-acess.so_src/vfs.asm b/Usermode/Libraries/ld-acess.so_src/vfs.asm index 44bce6b2..6afd7c7f 100644 --- a/Usermode/Libraries/ld-acess.so_src/vfs.asm +++ b/Usermode/Libraries/ld-acess.so_src/vfs.asm @@ -20,5 +20,6 @@ SYSCALL2 _SysGetACL, SYS_GETACL ; int, void* SYSCALL1 chdir, SYS_CHDIR ; char* SYSCALL3 ioctl, SYS_IOCTL ; int, int, void* SYSCALL4 _SysMount, SYS_MOUNT ; char*, char*, char*, char* +SYSCALL5 select, SYS_SELECT ; int, fd_set*, fd_set*, fd_set*, tTime* SYSCALL3 _SysOpenChild, SYS_OPENCHILD diff --git a/Usermode/include/acess/sys.h b/Usermode/include/acess/sys.h index ba58ffe5..35f582d8 100644 --- a/Usermode/include/acess/sys.h +++ b/Usermode/include/acess/sys.h @@ -98,6 +98,7 @@ extern int readdir(int fd, char *dest); extern int _SysOpenChild(int fd, char *name, int flags); extern int _SysGetACL(int fd, t_sysACL *dest); extern int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options); +extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errfds, time_t *timeout); // --- IPC --- extern int SysSendMessage(pid_t dest, uint length, void *Data); diff --git a/Usermode/include/sys/sys.h b/Usermode/include/sys/sys.h index d9e7ada3..d932eb33 100644 --- a/Usermode/include/sys/sys.h +++ b/Usermode/include/sys/sys.h @@ -31,6 +31,9 @@ extern void seek(int fp, int64_t dist, int flag); extern int fstat(int fp, t_fstat *st); extern int ioctl(int fp, int call, void *arg); extern int readdir(int fp, char *file); + +extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errfds, time_t *timeout); + extern int kdebug(char *fmt, ...); extern int waitpid(int pid, int action); extern int gettid(); // Get Thread ID diff --git a/Usermode/include/sys/types.h b/Usermode/include/sys/types.h index 2fad39fc..92e27917 100644 --- a/Usermode/include/sys/types.h +++ b/Usermode/include/sys/types.h @@ -27,6 +27,20 @@ typedef struct { #define S_IFSOCK 0140000 /* socket */ #define S_IFIFO 0010000 /* fifo */ +#define FD_SETSIZE 128 + +/** + * \brief fd_set for select() + */ +typedef struct +{ + uint16_t flags[FD_SETSIZE/16]; +} fd_set; + +static inline void FD_ZERO(fd_set *fdsetp) {int i=FD_SETSIZE/16;while(i--)fdsetp->flags[i]=0; } +static inline void FD_CLR(int fd, fd_set *fdsetp) { fdsetp->flags[fd/16]&=~(1<<(fd%16)); } +static inline void FD_SET(int fd, fd_set *fdsetp) { fdsetp->flags[fd/16]|=1<<(fd%16); } +static inline int FD_ISSET(int fd, fd_set *fdsetp) { return fdsetp->flags[fd/16]&(1<<(fd%16)); } typedef uint32_t pid_t; typedef uint32_t tid_t;