X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=AcessNative%2Facesskernel_src%2Fvfs_handle.c;h=93b6a9d674d7354fbb65b8cce57566f1fa7eda6c;hb=2238e69eea50d2274553926f3f294822c1972ff0;hp=cfe048980469b9e75f96b3dede2cc3dbf7e082df;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/AcessNative/acesskernel_src/vfs_handle.c b/AcessNative/acesskernel_src/vfs_handle.c index cfe04898..93b6a9d6 100644 --- a/AcessNative/acesskernel_src/vfs_handle.c +++ b/AcessNative/acesskernel_src/vfs_handle.c @@ -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;iHandles[i].Node) continue; + _CloseNode(ent->Handles[i].Node); + ent->Handles[i].Node = NULL; + } +}