Usermode implementation of select()
authorJohn Hodge <[email protected]>
Tue, 1 Mar 2011 06:42:05 +0000 (14:42 +0800)
committerJohn Hodge <[email protected]>
Tue, 1 Mar 2011 06:42:05 +0000 (14:42 +0800)
Kernel/include/syscalls.h
Kernel/include/syscalls.inc.asm
Kernel/syscalls.c
Kernel/syscalls.lst
Usermode/Libraries/ld-acess.so_src/vfs.asm
Usermode/include/acess/sys.h
Usermode/include/sys/sys.h
Usermode/include/sys/types.h

index 4cd733d..bb80ffb 100644 (file)
@@ -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",
 
        ""
 };
index d4fa724..307e582 100644 (file)
@@ -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
index f930cdd..6c62a92 100644 (file)
@@ -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
index cf299ea..826249d 100644 (file)
@@ -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
index 44bce6b..6afd7c7 100644 (file)
@@ -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
index ba58ffe..35f582d 100644 (file)
@@ -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);
index d9e7ada..d932eb3 100644 (file)
@@ -31,6 +31,9 @@ extern void seek(int fp, int64_t dist, int flag);
 extern int     fstat(int fp, t_fstat *st);\r
 extern int     ioctl(int fp, int call, void *arg);\r
 extern int     readdir(int fp, char *file);\r
+\r
+extern int     select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errfds, time_t *timeout);\r
+\r
 extern int     kdebug(char *fmt, ...);\r
 extern int     waitpid(int pid, int action);\r
 extern int     gettid();       // Get Thread ID\r
index 2fad39f..92e2791 100644 (file)
@@ -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;

UCC git Repository :: git.ucc.asn.au