Kernel - Implimented VFS_Reopen
authorJohn Hodge <[email protected]>
Thu, 16 May 2013 05:46:16 +0000 (13:46 +0800)
committerJohn Hodge <[email protected]>
Thu, 16 May 2013 05:46:16 +0000 (13:46 +0800)
KernelLand/Kernel/include/vfs_ext.h
KernelLand/Kernel/include/vfs_int.h
KernelLand/Kernel/syscalls.c
KernelLand/Kernel/vfs/handle.c
KernelLand/Kernel/vfs/open.c

index a3a8564..d18009d 100644 (file)
@@ -222,6 +222,11 @@ extern int VFS_OpenChild(int FD, const char *Name, Uint Mode);
  */
 extern int     VFS_OpenInode(Uint32 Mount, Uint64 Inode, int Mode);
 
+/**
+ * \brief Open a file reusing an old FD
+ */
+extern int     VFS_Reopen(int FD, const char *Path, int Flags);
+
 /**
  * \brief Close a currently open file
  * \param FD   Handle returned by ::VFS_Open
index 06ad8da..c2dacd3 100644 (file)
@@ -73,6 +73,18 @@ static inline void _CloseNode(tVFS_Node *Node)
        if(Node && Node->Type && Node->Type->Close)
                Node->Type->Close( Node );
 }
+static inline void _ReferenceNode(tVFS_Node *Node)
+{
+       if( !MM_GetPhysAddr(Node->Type) ) {
+               Log_Error("VFS", "Node %p's type is invalid (%p bad pointer) - %P corrupted",
+                       Node, Node->Type, MM_GetPhysAddr(&Node->Type));
+               return ;
+       }
+       if( Node->Type && Node->Type->Reference )
+               Node->Type->Reference( Node );
+       else
+               Node->ReferenceCount ++;
+}
 
 
 #endif
index 340a5cc..34a35c5 100644 (file)
@@ -208,6 +208,11 @@ void SyscallHandler(tSyscallRegs *Regs)
                LOG("VFS_Open(\"%s\", 0x%x)", (char*)Regs->Arg1, Regs->Arg2 | VFS_OPENFLAG_USER);
                ret = VFS_Open((char*)Regs->Arg1, Regs->Arg2 | VFS_OPENFLAG_USER);
                break;
+       case SYS_REOPEN:
+               CHECK_STR_NONULL( (char*)Regs->Arg2 );
+               LOG("VFS_Reopen(%i, \"%s\", 0x%x)", Regs->Arg1, (char*)Regs->Arg2, Regs->Arg3 | VFS_OPENFLAG_USER);
+               ret = VFS_Reopen(Regs->Arg1, (char*)Regs->Arg2, Regs->Arg3 | VFS_OPENFLAG_USER);
+               break;
        
        case SYS_CLOSE:
                LOG("VFS_Close(%i)", Regs->Arg1);
index 35aa00c..6173c29 100644 (file)
 #define MAX_KERNEL_FILES       128
 
 // === PROTOTYPES ===
-inline void    _ReferenceNode(tVFS_Node *Node);
 
 // === GLOBALS ===
 tVFS_Handle    *gaUserHandles = (void*)MM_PPD_HANDLES;
 tVFS_Handle    *gaKernelHandles = (void*)MM_KERNEL_VFS;
 
 // === CODE ===
-inline void _ReferenceNode(tVFS_Node *Node)
-{
-       if( !MM_GetPhysAddr(Node->Type) ) {
-               Log_Error("VFS", "Node %p's type is invalid (%p bad pointer) - %P corrupted",
-                       Node, Node->Type, MM_GetPhysAddr(&Node->Type));
-               return ;
-       }
-       if( Node->Type && Node->Type->Reference )
-               Node->Type->Reference( Node );
-       else
-               Node->ReferenceCount ++;
-}
-
 /**
  * \fn tVFS_Handle *VFS_GetHandle(int FD)
  * \brief Gets a pointer to the handle information structure
index 2bfb261..748d0f7 100644 (file)
@@ -722,6 +722,30 @@ int VFS_OpenInode(Uint32 Mount, Uint64 Inode, int Mode)
        LEAVE_RET('x', VFS_int_CreateHandle(node, mnt, Mode));
 }
 
+int VFS_Reopen(int FD, const char *Path, int Flags)
+{
+       tVFS_Handle     *h = VFS_GetHandle(FD);
+       if(!h) {
+               errno = EBADF;
+               return -1;
+       }
+
+       int newf = VFS_Open(Path, Flags);
+       if( newf == -1 ) {
+               return -1;
+       }
+       
+       _CloseNode(h->Node);
+       _DereferenceMount(h->Mount, "Reopen");
+       memcpy(h, VFS_GetHandle(newf), sizeof(*h));
+       _ReferenceNode(h->Node);
+       _ReferenceMount(h->Mount, "Reopen");
+       
+       VFS_Close(newf);        
+
+       return FD;
+}
+
 /**
  * \fn void VFS_Close(int FD)
  * \brief Closes an open file handle
@@ -774,6 +798,8 @@ int VFS_DuplicateFD(int SrcFD, int DstFD)
                        return -1;
                VFS_SetHandle(DstFD, src->Node, src->Mode);
        }
+       _ReferenceMount(src->Mount, "DuplicateFD");
+       _ReferenceNode(src->Node);
        memcpy(VFS_GetHandle(DstFD), src, sizeof(tVFS_Handle));
        return DstFD;
 }

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