Kernel/VTerm - "Fix" wrapping issue in VTerm (why was old behavior there?)
[tpg/acess2.git] / AcessNative / acesskernel_src / vfs_handle.c
index cfe0489..93b6a9d 100644 (file)
@@ -38,15 +38,18 @@ tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate)
        tUserHandles    *ent, *prev = NULL;
        for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
                if( ent->PID == PID ) {
-                       if( bCreate )
-                               Log_Warning("VFS", "Process %i already has a handle list", PID);
+                       //if( bCreate )
+                       //      Log_Warning("VFS", "Process %i already has a handle list", PID);
+                       LOG("Found list for %i", PID);
                        return ent;
                }
                if( ent->PID > PID )    break;
        }
        
-       if(!bCreate)
+       if(!bCreate) {
+               LOG("Not creating for %i", PID);
                return NULL;
+       }
        
        ent = calloc( 1, sizeof(tUserHandles) );
        ent->PID = PID;
@@ -58,7 +61,7 @@ tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate)
                ent->Next = gpUserHandles;
                gpUserHandles = ent;
        }
-       Log_Notice("VFS", "Created handle list for process %i", PID);
+       LOG("Created handle list for process %i", PID);
        return ent;
 }
 
@@ -68,20 +71,59 @@ tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate)
 void VFS_CloneHandleList(int PID)
 {
        tUserHandles    *ent;
-       tUserHandles    *cur;
-        int    i, maxhandles;
+       const tUserHandles      *cur;
+        int    maxhandles;
        
        cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
        if(!cur)        return ;        // Don't need to do anything if the current list is empty
        
        ent = VFS_int_GetUserHandles(PID, 1);
        
-       maxhandles = *Threads_GetMaxFD();
+       maxhandles = *Threads_GetMaxFD(NULL);
        memcpy(ent->Handles, cur->Handles, maxhandles*sizeof(tVFS_Handle));
        
-       for( i = 0; i < maxhandles; i ++ )
+       // Reference all
+       for( int i = 0; i < maxhandles; i ++ )
        {
-               if(!cur->Handles[i].Node)       continue;
+               if(!ent->Handles[i].Node)       continue;
+               
+               if(ent->Handles[i].Node->Type->Reference)
+                       ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node);
+       }
+}
+
+void VFS_CloneHandlesFromList(int PID, int nFD, int FDs[])
+{
+       tUserHandles    *ent;
+       const tUserHandles      *cur;
+        int    maxhandles;
+       
+       cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
+       if(!cur)        return ;        // Don't need to do anything if the current list is empty
+       
+       ent = VFS_int_GetUserHandles(PID, 1);
+
+       LOG("Copying %i FDs from %i", nFD, PID);
+
+       maxhandles = *Threads_GetMaxFD(NULL);
+       if( nFD > maxhandles )
+               nFD = maxhandles;
+       for( int i = 0; i < nFD; i ++ )
+       {
+                int    fd = FDs[i];
+               if( fd >= maxhandles ) {
+                       ent->Handles[i].Node = NULL;
+                       continue ;
+               }
+               memcpy(&ent->Handles[i], &cur->Handles[fd], sizeof(tVFS_Handle));
+       }
+       for( int i = nFD; i < maxhandles; i ++ )
+               ent->Handles[i].Node = NULL;
+       
+       // Reference
+       for( int i = 0; i < maxhandles; i ++ )
+       {
+               if(!ent->Handles[i].Node)       continue;
                
                if(ent->Handles[i].Node->Type->Reference)
                        ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node);
@@ -113,11 +155,10 @@ tVFS_Handle *VFS_GetHandle(int FD)
        }
        else
        {
-               tUserHandles    *ent;
                 int    pid = Threads_GetPID();
-                int    maxhandles = *Threads_GetMaxFD();
+                int    maxhandles = *Threads_GetMaxFD(NULL);
                
-               ent = VFS_int_GetUserHandles(pid, 0);
+               tUserHandles *ent = VFS_int_GetUserHandles(pid, 0);
                if(!ent) {
                        Log_Error("VFS", "Client %i does not have a handle list (>)", pid);
                        return NULL;
@@ -139,19 +180,50 @@ 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 {
+               tUserHandles    *ent;
+                int    pid = Threads_GetPID();
+                int    maxhandles = *Threads_GetMaxFD(NULL);
+               
+               ent = VFS_int_GetUserHandles(pid, 0);
+               if(!ent) {
+                       Log_Error("VFS", "Client %i does not have a handle list (>)", pid);
+                       return -1;
+               }
+               
+               if(FD >= maxhandles) {
+                       LOG("FD (%i) > Limit (%i), RETURN NULL", FD, maxhandles);
+                       return -1;
+               }
+               h = &ent->Handles[ 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)
        {
                tUserHandles    *ent;
-                int    maxhandles = *Threads_GetMaxFD();
+                int    maxhandles = *Threads_GetMaxFD(NULL);
                // Find the PID's handle list
                ent = VFS_int_GetUserHandles(Threads_GetPID(), 1);
                // Get a handle
-               for( i = 0; i < maxhandles; i ++ )
+               for( int i = 0; i < maxhandles; i ++ )
                {
                        if(ent->Handles[i].Node)        continue;
                        ent->Handles[i].Node = Node;
@@ -163,7 +235,7 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
        else
        {
                // 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;
@@ -175,3 +247,18 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
        
        return -1;
 }
+
+void VFS_ClearHandles(int PID)
+{
+       // Find the PID's handle list
+       tUserHandles *ent = VFS_int_GetUserHandles(PID, 0);
+       if( !ent )      return;
+       // Get a handle
+        int    maxhandles = *Threads_GetMaxFD(NULL);
+       for( int i = 0; i < maxhandles; i ++ )
+       {
+               if(ent->Handles[i].Node)        continue;
+               _CloseNode(ent->Handles[i].Node);
+               ent->Handles[i].Node = NULL;
+       }
+}

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