From 077a1c5d962b20dee54c6b31c8f37d2fe79105ad Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 15 Apr 2010 10:11:01 +0800 Subject: [PATCH] Added SYS_OPENCHILD system call - 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 --- Kernel/Makefile | 5 +- Kernel/Makefile.BuildNum | 2 +- Kernel/include/acess.h | 1 + Kernel/include/errno.h | 7 +- Kernel/include/syscalls.h | 27 ++--- Kernel/include/syscalls.inc.asm | 21 ++-- Kernel/include/vfs_ext.h | 10 ++ Kernel/syscalls.c | 10 ++ Kernel/syscalls.lst | 1 + Kernel/vfs/open.c | 103 +++++++++++++++++++- Usermode/Libraries/Makefile.tpl | 3 +- Usermode/Libraries/libacess.so_src/Makefile | 2 +- Usermode/Libraries/libacess.so_src/vfs.asm | 2 + Usermode/include/acess/sys.h | 1 + 14 files changed, 165 insertions(+), 30 deletions(-) diff --git a/Kernel/Makefile b/Kernel/Makefile index 5e6fafba..fa8ff2a0 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -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 diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index 789b571a..9a0157e1 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1837 +BUILD_NUM = 1866 diff --git a/Kernel/include/acess.h b/Kernel/include/acess.h index 963cb9cf..db2dd964 100644 --- a/Kernel/include/acess.h +++ b/Kernel/include/acess.h @@ -399,5 +399,6 @@ extern int DivUp(int num, int dem); #include #include +#include #endif diff --git a/Kernel/include/errno.h b/Kernel/include/errno.h index 0b796c05..f5b23605 100644 --- a/Kernel/include/errno.h +++ b/Kernel/include/errno.h @@ -14,7 +14,12 @@ enum eErrorNums EACCES, ENOTFOUND, EREADONLY, - ENOTIMPL + ENOTIMPL, + ENOENT, + ENFILE, + ENOTDIR, + + NUM_ERRS }; #endif diff --git a/Kernel/include/syscalls.h b/Kernel/include/syscalls.h index 2c44d2c8..fb9a2ff6 100644 --- a/Kernel/include/syscalls.h +++ b/Kernel/include/syscalls.h @@ -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 diff --git a/Kernel/include/syscalls.inc.asm b/Kernel/include/syscalls.inc.asm index 178ecbd6..a379deb1 100644 --- a/Kernel/include/syscalls.inc.asm +++ b/Kernel/include/syscalls.inc.asm @@ -43,13 +43,14 @@ %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 diff --git a/Kernel/include/vfs_ext.h b/Kernel/include/vfs_ext.h index e2f03447..c9d51100 100644 --- a/Kernel/include/vfs_ext.h +++ b/Kernel/include/vfs_ext.h @@ -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 diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c index cafe7c28..34567976 100644 --- a/Kernel/syscalls.c +++ b/Kernel/syscalls.c @@ -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) ) { diff --git a/Kernel/syscalls.lst b/Kernel/syscalls.lst index a83f5d69..c5978bea 100644 --- a/Kernel/syscalls.lst +++ b/Kernel/syscalls.lst @@ -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 diff --git a/Kernel/vfs/open.c b/Kernel/vfs/open.c index ac47683f..d2035713 100644 --- a/Kernel/vfs/open.c +++ b/Kernel/vfs/open.c @@ -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 $(BIN).dsm %.o: %.c $(CC) $(CFLAGS) -o $@ -c $< diff --git a/Usermode/Libraries/libacess.so_src/Makefile b/Usermode/Libraries/libacess.so_src/Makefile index 9acb5ebc..a6267f2d 100644 --- a/Usermode/Libraries/libacess.so_src/Makefile +++ b/Usermode/Libraries/libacess.so_src/Makefile @@ -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 $@ $< diff --git a/Usermode/Libraries/libacess.so_src/vfs.asm b/Usermode/Libraries/libacess.so_src/vfs.asm index deb9751d..44bce6b2 100644 --- a/Usermode/Libraries/libacess.so_src/vfs.asm +++ b/Usermode/Libraries/libacess.so_src/vfs.asm @@ -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 diff --git a/Usermode/include/acess/sys.h b/Usermode/include/acess/sys.h index c034b77f..c3c216f5 100644 --- a/Usermode/include/acess/sys.h +++ b/Usermode/include/acess/sys.h @@ -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); -- 2.20.1