Kernel - Working on SYS_COPYFD
authorJohn Hodge <[email protected]>
Wed, 15 May 2013 08:12:34 +0000 (16:12 +0800)
committerJohn Hodge <[email protected]>
Wed, 15 May 2013 08:12:34 +0000 (16:12 +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 2cd4101..1bae964 100644 (file)
@@ -226,6 +226,13 @@ extern int VFS_OpenInode(Uint32 Mount, Uint64 Inode, int Mode);
  */
 extern void    VFS_Close(int FD);
 
+/**
+ * \brief Copy one FD to another
+ * \param SrcFD        Source file descriptor
+ * \param DstFD        Destination file descriptor (-1 means allocate new)
+ */
+extern int     VFS_DuplicateFD(int SrcFD, int DstFD);
+
 /**
  * \brief Get file information from an open file
  * \param FD   File handle returned by ::VFS_Open
index 232c55e..06ad8da 100644 (file)
@@ -62,6 +62,9 @@ extern int    VFS_CheckACL(tVFS_Node *Node, Uint Permissions);
 extern tVFS_Mount      *VFS_GetMountByIdent(Uint32 MountID);
 // --- dir.c ---
 extern int     VFS_MkNod(const char *Path, Uint Flags);
+// --- handle.c ---
+extern int     VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode);
+extern int     VFS_SetHandle(int FD, tVFS_Node *Node, int Mode);
 
 
 // --- VFS Helpers ---
index 635f69a..4416ec4 100644 (file)
@@ -214,6 +214,11 @@ void SyscallHandler(tSyscallRegs *Regs)
                VFS_Close( Regs->Arg1 );
                break;
        
+       case SYS_COPYFD:
+               LOG("VFS_DuplicateFD(%i,%i)", Regs->Arg1, Regs->Arg2);
+               ret = VFS_DuplicateFD(Regs->Arg1, Regs->Arg2);
+               break;
+       
        case SYS_SEEK:
                #if BITS == 64
                ret = VFS_Seek( Regs->Arg1, Regs->Arg2, Regs->Arg3 );
index cb4fae1..35aa00c 100644 (file)
 #define MAX_KERNEL_FILES       128
 
 // === PROTOTYPES ===
-#if 0
-tVFS_Handle    *VFS_GetHandle(int FD);
-#endif
 inline void    _ReferenceNode(tVFS_Node *Node);
- int   VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode);
 
 // === GLOBALS ===
 tVFS_Handle    *gaUserHandles = (void*)MM_PPD_HANDLES;
@@ -66,10 +62,27 @@ tVFS_Handle *VFS_GetHandle(int FD)
        return h;
 }
 
-int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
+int VFS_SetHandle(int FD, tVFS_Node *Node, int Mode)
 {
-        int    i;
+       tVFS_Handle     *h;
+       if(FD < 0)      return -1;
        
+       if( FD & VFS_KERNEL_FLAG ) {
+               FD &= (VFS_KERNEL_FLAG -1);
+               if( FD >= MAX_KERNEL_FILES )    return -1;
+               h = &gaKernelHandles[FD];
+       }
+       else {
+               if( FD >= *Threads_GetMaxFD())  return -1;
+               h = &gaUserHandles[FD];
+       }
+       h->Node = Node;
+       h->Mode = Mode;
+       return FD;
+}
+
+int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
+{
        // Check for a user open
        if(bIsUser)
        {
@@ -90,7 +103,7 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
                        memset( gaUserHandles, 0, size );
                }
                // Get a handle
-               for( i = 0; i < max_handles; i ++ )
+               for( int i = 0; i < max_handles; i ++ )
                {
                        if(gaUserHandles[i].Node)       continue;
                        gaUserHandles[i].Node = Node;
@@ -117,7 +130,7 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
                        memset( gaKernelHandles, 0, size );
                }
                // Get a handle
-               for(i=0;i<MAX_KERNEL_FILES;i++)
+               for(int i=0;i<MAX_KERNEL_FILES;i++)
                {
                        if(gaKernelHandles[i].Node)     continue;
                        gaKernelHandles[i].Node = Node;
index e83ace8..67ef58a 100644 (file)
@@ -18,7 +18,6 @@
 
 // === IMPORTS ===
 extern tVFS_Mount      *gVFS_RootMount;
-extern int     VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode);
 extern tVFS_Node       *VFS_MemFile_Create(const char *Path);
 
 // === PROTOTYPES ===
@@ -752,6 +751,24 @@ void VFS_Close(int FD)
        h->Node = NULL;
 }
 
+int VFS_DuplicateFD(int SrcFD, int DstFD)
+{
+        int    isUser = !(SrcFD & VFS_KERNEL_FLAG);
+       tVFS_Handle     *src = VFS_GetHandle(SrcFD);
+       if( !src )      return -1;
+       if( DstFD == -1 ) {
+               DstFD = VFS_AllocHandle(isUser, src->Node, src->Mode);
+       }
+       else {
+               // Can't overwrite
+               if( VFS_GetHandle(DstFD) )
+                       return -1;
+               VFS_SetHandle(DstFD, src->Node, src->Mode);
+       }
+       memcpy(VFS_GetHandle(DstFD), src, sizeof(tVFS_Handle));
+       return DstFD;
+}
+
 /**
  * \brief Change current working directory
  */

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