Added SYS_OPENCHILD system call
authorJohn Hodge <[email protected]>
Thu, 15 Apr 2010 02:11:01 +0000 (10:11 +0800)
committerJohn Hodge <[email protected]>
Thu, 15 Apr 2010 02:11:01 +0000 (10:11 +0800)
- SYS_OPENCHILD opens a file that is a direct child of the passed FD
  (using the FD's Node)
- Used for IPStack servers to open a client connection

14 files changed:
Kernel/Makefile
Kernel/Makefile.BuildNum
Kernel/include/acess.h
Kernel/include/errno.h
Kernel/include/syscalls.h
Kernel/include/syscalls.inc.asm
Kernel/include/vfs_ext.h
Kernel/syscalls.c
Kernel/syscalls.lst
Kernel/vfs/open.c
Usermode/Libraries/Makefile.tpl
Usermode/Libraries/libacess.so_src/Makefile
Usermode/Libraries/libacess.so_src/vfs.asm
Usermode/include/acess/sys.h

index 5e6fafb..fa8ff2a 100644 (file)
@@ -25,8 +25,9 @@ ifeq ($(DEBUG_BUILD),yes)
        CFLAGS += -g
 endif
 
-OBJ = $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
-OBJ += heap.o messages.o debug.o modules.o lib.o syscalls.o system.o threads.o drvutil.o logging.o
+OBJ := $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
+OBJ += heap.o drvutil.o logging.o debug.o lib.o adt.o
+OBJ += messages.o modules.o syscalls.o system.o threads.o
 OBJ += $(addprefix vfs/fs/, $(addsuffix .o,$(FILESYSTEMS)))
 OBJ += drv/vterm.o drv/proc.o drv/fifo.o drv/iocache.o drv/dma.o drv/pci.o drv/kb.o drv/vga.o
 OBJ += binary.o bin/elf.o bin/pe.o
index 789b571..9a0157e 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 1837
+BUILD_NUM = 1866
index 963cb9c..db2dd96 100644 (file)
@@ -399,5 +399,6 @@ extern int  DivUp(int num, int dem);
 
 #include <binary_ext.h>
 #include <vfs_ext.h>
+#include <adt.h>
 
 #endif
index 0b796c0..f5b2360 100644 (file)
@@ -14,7 +14,12 @@ enum eErrorNums
        EACCES,
        ENOTFOUND,
        EREADONLY,
-       ENOTIMPL
+       ENOTIMPL,
+       ENOENT,
+       ENFILE,
+       ENOTDIR,
+       
+       NUM_ERRS
 };
 
 #endif
index 2c44d2c..fb9a2ff 100644 (file)
@@ -47,16 +47,17 @@ enum eSyscalls {
        SYS_WRITE,      // 68 - Write to an open file
        SYS_IOCTL,      // 69 - Perform an IOCtl Call
        SYS_READDIR,    // 70 - Read from an open directory
-       SYS_MKDIR,      // 71 - Create a new directory
-       SYS_SYMLINK,    // 72 - Create a symbolic link
-       SYS_GETACL,     // 73 - Get an ACL Value
-       SYS_SETACL,     // 74 - Set an ACL Value
-       SYS_FINFO,      // 75 - Get file information
-       SYS_SEEK,       // 76 - Seek to a new position in the file
-       SYS_TELL,       // 77 - Return the current file position
-       SYS_CHDIR,      // 78 - Change current directory
-       SYS_GETCWD,     // 79 - Get current directory
-       SYS_MOUNT,      // 80 - Mount a filesystem
+       SYS_OPENCHILD,  // 71 - Open a child entry in a directory
+       SYS_MKDIR,      // 72 - Create a new directory
+       SYS_SYMLINK,    // 73 - Create a symbolic link
+       SYS_GETACL,     // 74 - Get an ACL Value
+       SYS_SETACL,     // 75 - Set an ACL Value
+       SYS_FINFO,      // 76 - Get file information
+       SYS_SEEK,       // 77 - Seek to a new position in the file
+       SYS_TELL,       // 78 - Return the current file position
+       SYS_CHDIR,      // 79 - Change current directory
+       SYS_GETCWD,     // 80 - Get current directory
+       SYS_MOUNT,      // 81 - Mount a filesystem
        NUM_SYSCALLS,
        SYS_DEBUG = 0x100       // 0x100 - Print a debug string
 };
@@ -73,8 +74,8 @@ static const char *cSYSCALL_NAMES[] = {
        "","","","","","",
        "","","","","","",
        "","","","","SYS_OPEN","SYS_REOPEN",
-       "SYS_CLOSE","SYS_READ","SYS_WRITE","SYS_IOCTL","SYS_READDIR","SYS_MKDIR",
-       "SYS_SYMLINK","SYS_GETACL","SYS_SETACL","SYS_FINFO","SYS_SEEK","SYS_TELL",
-       "SYS_CHDIR","SYS_GETCWD","SYS_MOUNT",""
+       "SYS_CLOSE","SYS_READ","SYS_WRITE","SYS_IOCTL","SYS_READDIR","SYS_OPENCHILD",
+       "SYS_MKDIR","SYS_SYMLINK","SYS_GETACL","SYS_SETACL","SYS_FINFO","SYS_SEEK",
+       "SYS_TELL","SYS_CHDIR","SYS_GETCWD","SYS_MOUNT",""
 };
 #endif
index 178ecbd..a379deb 100644 (file)
 %define SYS_WRITE      68      ; Write to an open file
 %define SYS_IOCTL      69      ; Perform an IOCtl Call
 %define SYS_READDIR    70      ; Read from an open directory
-%define SYS_MKDIR      71      ; Create a new directory
-%define SYS_SYMLINK    72      ; Create a symbolic link
-%define SYS_GETACL     73      ; Get an ACL Value
-%define SYS_SETACL     74      ; Set an ACL Value
-%define SYS_FINFO      75      ; Get file information
-%define SYS_SEEK       76      ; Seek to a new position in the file
-%define SYS_TELL       77      ; Return the current file position
-%define SYS_CHDIR      78      ; Change current directory
-%define SYS_GETCWD     79      ; Get current directory
-%define SYS_MOUNT      80      ; Mount a filesystem
+%define SYS_OPENCHILD  71      ; Open a child entry in a directory
+%define SYS_MKDIR      72      ; Create a new directory
+%define SYS_SYMLINK    73      ; Create a symbolic link
+%define SYS_GETACL     74      ; Get an ACL Value
+%define SYS_SETACL     75      ; Set an ACL Value
+%define SYS_FINFO      76      ; Get file information
+%define SYS_SEEK       77      ; Seek to a new position in the file
+%define SYS_TELL       78      ; Return the current file position
+%define SYS_CHDIR      79      ; Change current directory
+%define SYS_GETCWD     80      ; Get current directory
+%define SYS_MOUNT      81      ; Mount a filesystem
index e2f0344..c9d5110 100644 (file)
@@ -266,5 +266,15 @@ extern int VFS_Symlink(char *Name, char *Link);
  * \return Boolean Success
  */
 extern int     VFS_ReadDir(int FD, char *Dest);
+/**
+ * \brief Opens a file via an open directory
+ * \note The file to open must be a direct child of the parent
+ * \param Errno        Error number
+ * \param FD   Parent Directory
+ * \param Name Child name
+ * \param Mode Open mode
+ * \return File handle (same as returned from VFS_Open)
+ */
+extern int     VFS_OpenChild(Uint *Errno, int FD, char *Name, Uint Mode);
 
 #endif
index cafe7c2..3456797 100644 (file)
@@ -235,6 +235,16 @@ void SyscallHandler(tSyscallRegs *Regs)
                ret = VFS_ReadDir( Regs->Arg1, (void*)Regs->Arg2 );
                break;
        
+       // Open a file that is a entry in an open directory
+       case SYS_OPENCHILD:
+               if( !Syscall_ValidString(Regs->Arg2) ) {
+                       err = -EINVAL;
+                       ret = -1;
+                       break;
+               }
+               ret = VFS_OpenChild( &err, Regs->Arg1, (char*)Regs->Arg2, Regs->Arg3);
+               break;
+       
        // Change Directory
        case SYS_CHDIR:
                if( !Syscall_ValidString(Regs->Arg1) ) {
index a83f5d6..c5978be 100644 (file)
@@ -48,6 +48,7 @@ SYS_READ      Read from an open file
 SYS_WRITE      Write to an open file
 SYS_IOCTL      Perform an IOCtl Call
 SYS_READDIR    Read from an open directory
+SYS_OPENCHILD  Open a child entry in a directory
 SYS_MKDIR      Create a new directory
 SYS_SYMLINK    Create a symbolic link
 SYS_GETACL     Get an ACL Value
index ac47683..d203571 100644 (file)
@@ -535,6 +535,107 @@ int VFS_Open(char *Path, Uint Mode)
        return -1;
 }
 
+
+/**
+ * \brief Open a file from an open directory
+ */
+int VFS_OpenChild(Uint *Errno, int FD, char *Name, Uint Mode)
+{
+       tVFS_Handle     *h;
+       tVFS_Node       *node;
+        int    i;
+       
+       // Get handle
+       h = VFS_GetHandle(FD);
+       if(h == NULL) {
+               Log_Warning("VFS", "VFS_OpenChild - Invalid file handle 0x%x", FD);
+               if(Errno)       *Errno = EINVAL;
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       // Check for directory
+       if( !(h->Node->Flags & VFS_FFLAG_DIRECTORY) ) {
+               Log_Warning("VFS", "VFS_OpenChild - Passed handle is not a directory", FD);
+               if(Errno)       *Errno = ENOTDIR;
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       // Find Child
+       node = h->Node->FindDir(h->Node, Name);
+       if(!node) {
+               if(Errno)       *Errno = ENOENT;
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       i = 0;
+       i |= (Mode & VFS_OPENFLAG_EXEC) ? VFS_PERM_EXECUTE : 0;
+       i |= (Mode & VFS_OPENFLAG_READ) ? VFS_PERM_READ : 0;
+       i |= (Mode & VFS_OPENFLAG_WRITE) ? VFS_PERM_WRITE : 0;
+       
+       // Permissions Check
+       if( !VFS_CheckACL(node, i) ) {
+               if(node->Close) node->Close( node );
+               Log_Notice("VFS", "VFS_OpenChild - Permissions Failed");
+               if(Errno)       *Errno = EACCES;
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       // Check for a user open
+       if(Mode & VFS_OPENFLAG_USER)
+       {
+               // Allocate Buffer
+               if( MM_GetPhysAddr( (Uint)gaUserHandles ) == 0 )
+               {
+                       Uint    addr, size;
+                       size = CFGINT(CFG_VFS_MAXFILES) * sizeof(tVFS_Handle);
+                       for(addr = 0; addr < size; addr += 0x1000)
+                               MM_Allocate( (Uint)gaUserHandles + addr );
+                       memset( gaUserHandles, 0, size );
+               }
+               // Get a handle
+               for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
+               {
+                       if(gaUserHandles[i].Node)       continue;
+                       gaUserHandles[i].Node = node;
+                       gaUserHandles[i].Position = 0;
+                       gaUserHandles[i].Mode = Mode;
+                       LEAVE('i', i);
+                       return i;
+               }
+       }
+       else
+       {
+               // Allocate space if not already
+               if( MM_GetPhysAddr( (Uint)gaKernelHandles ) == 0 )
+               {
+                       Uint    addr, size;
+                       size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
+                       for(addr = 0; addr < size; addr += 0x1000)
+                               MM_Allocate( (Uint)gaKernelHandles + addr );
+                       memset( gaKernelHandles, 0, size );
+               }
+               // Get a handle
+               for(i=0;i<MAX_KERNEL_FILES;i++)
+               {
+                       if(gaKernelHandles[i].Node)     continue;
+                       gaKernelHandles[i].Node = node;
+                       gaKernelHandles[i].Position = 0;
+                       gaKernelHandles[i].Mode = Mode;
+                       LEAVE('x', i|VFS_KERNEL_FLAG);
+                       return i|VFS_KERNEL_FLAG;
+               }
+       }
+       
+       Log_Error("VFS", "VFS_OpenChild - Out of handles");
+       if(Errno)       *Errno = ENFILE;
+       LEAVE('i', -1);
+       return -1;
+}
+
 /**
  * \fn void VFS_Close(int FD)
  * \brief Closes an open file handle
@@ -546,7 +647,7 @@ void VFS_Close(int FD)
        // Get handle
        h = VFS_GetHandle(FD);
        if(h == NULL) {
-               Warning("Invalid file handle passed to VFS_Close, 0x%x\n", FD);
+               Log_Warning("VFS", "Invalid file handle passed to VFS_Close, 0x%x\n", FD);
                return;
        }
        
index 709aaac..678ec07 100644 (file)
@@ -6,13 +6,14 @@
 all: $(BIN)
 
 clean:
-       $(RM) $(BIN) $(OBJ)
+       $(RM) $(BIN) $(OBJ) $(BIN).dsm
 
 install: $(BIN)
        $(xCP) $(BIN) $(DISTROOT)/Libs/
 
 $(BIN): $(OBJ)
        $(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
+       @$(OBJDUMP) -d $(BIN) > $(BIN).dsm
 
 %.o: %.c
        $(CC) $(CFLAGS) -o $@ -c $<
index 9acb5eb..a6267f2 100644 (file)
@@ -25,6 +25,6 @@ $(BIN): $(OBJ)
        @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
        @$(STRIP) $(BIN)
        
-%.ao: %.asm syscalls.inc.asm
+%.ao: %.asm syscalls.inc.asm ../../../Kernel/include/syscalls.inc.asm
        @echo $(AS) -o $@
        @$(AS) $(ASFLAGS) -o $@ $<
index deb9751..44bce6b 100644 (file)
@@ -20,3 +20,5 @@ 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*
+
+SYSCALL3       _SysOpenChild, SYS_OPENCHILD
index c034b77..c3c216f 100644 (file)
@@ -92,6 +92,7 @@ extern uint64_t       tell(int fd);
 extern int     ioctl(int fd, int id, void *data);
 extern int     finfo(int fd, t_sysFInfo *info, int maxacls);
 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);
 

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