X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=AcessNative%2Facesskernel_src%2Fvfs_handle.c;h=724e76fc483db6249d6afdaa5e1533b654f4dd3e;hb=b6198d9a828e247771a8913099070d51df76db4b;hp=5a94e6d30a20d3f8e749579a987173c58825280b;hpb=9ed2477f5f7e5b01501368719e93259aa336932f;p=tpg%2Facess2.git diff --git a/AcessNative/acesskernel_src/vfs_handle.c b/AcessNative/acesskernel_src/vfs_handle.c index 5a94e6d3..724e76fc 100644 --- a/AcessNative/acesskernel_src/vfs_handle.c +++ b/AcessNative/acesskernel_src/vfs_handle.c @@ -4,9 +4,10 @@ */ #define DEBUG 0 #include -#include "vfs.h" -#include "vfs_int.h" -#include "vfs_ext.h" +#include +#include +#include +#include // === CONSTANTS === #define MAX_KERNEL_FILES 128 @@ -32,6 +33,95 @@ tUserHandles *gpUserHandles = NULL; tVFS_Handle gaKernelHandles[MAX_KERNEL_FILES]; // === CODE === +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); + return ent; + } + if( ent->PID > PID ) break; + } + + if(!bCreate) + return NULL; + + ent = calloc( 1, sizeof(tUserHandles) ); + ent->PID = PID; + if( prev ) { + ent->Next = prev->Next; + prev->Next = ent; + } + else { + ent->Next = gpUserHandles; + gpUserHandles = ent; + } + Log_Notice("VFS", "Created handle list for process %i", PID); + return ent; +} + +/** + * \brief Clone the handle list of the current process into another + */ +void VFS_CloneHandleList(int PID) +{ + tUserHandles *ent; + tUserHandles *cur; + int i, 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(); + memcpy(ent->Handles, cur->Handles, maxhandles*sizeof(tVFS_Handle)); + + for( i = 0; i < maxhandles; i ++ ) + { + if(!cur->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; + tUserHandles *cur; + int i, 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(); + if( nFD > maxhandles ) + nFD = maxhandles; + for( i = 0; i < nFD; i ++ ) + { + if( FDs[i] >= maxhandles ) { + ent->Handles[i].Node = NULL; + continue ; + } + memcpy(&ent->Handles[i], &cur->Handles[ FDs[i] ], sizeof(tVFS_Handle)); + } + for( ; i < maxhandles; i ++ ) + cur->Handles[i].Node = NULL; + + for( i = 0; i < maxhandles; i ++ ) + { + if(!cur->Handles[i].Node) continue; + + if(ent->Handles[i].Node->Type->Reference) + ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node); + } +} + /** * \fn tVFS_Handle *VFS_GetHandle(int FD) * \brief Gets a pointer to the handle information structure @@ -42,32 +132,43 @@ tVFS_Handle *VFS_GetHandle(int FD) //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD); - if(FD < 0) return NULL; + if(FD < 0) { + LOG("FD (%i) < 0, RETURN NULL", FD); + return NULL; + } if(FD & VFS_KERNEL_FLAG) { FD &= (VFS_KERNEL_FLAG - 1); - if(FD >= MAX_KERNEL_FILES) return NULL; + if(FD >= MAX_KERNEL_FILES) { + LOG("FD (%i) > MAX_KERNEL_FILES (%i), RETURN NULL", FD, MAX_KERNEL_FILES); + return NULL; + } h = &gaKernelHandles[ FD ]; } - else { + else + { tUserHandles *ent; - int pid = Server_GetClientID(); - for( ent = gpUserHandles; ent; ent = ent->Next ) { - if( ent->PID == pid ) break; - if( ent->PID > pid ) { - Log_Error("VFS", "PID %i does not have a handle list", pid); - return NULL; - } + int pid = Threads_GetPID(); + int maxhandles = *Threads_GetMaxFD(); + + ent = VFS_int_GetUserHandles(pid, 0); + if(!ent) { + Log_Error("VFS", "Client %i does not have a handle list (>)", pid); + return NULL; } - if( !ent ) { - Log_Error("VFS", "PID %i does not have a handle list", pid); + + if(FD >= maxhandles) { + LOG("FD (%i) > Limit (%i), RETURN NULL", FD, maxhandles); return NULL; } - if(FD >= CFGINT(CFG_VFS_MAXFILES)) return NULL; h = &ent->Handles[ FD ]; + LOG("FD (%i) -> %p (Mode:0x%x,Node:%p)", FD, h, h->Mode, h->Node); } - if(h->Node == NULL) return NULL; + if(h->Node == NULL) { + LOG("FD (%i) Unused", FD); + return NULL; + } //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h); return h; } @@ -79,26 +180,12 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode) // Check for a user open if(bIsUser) { - tUserHandles *ent, *prev = NULL; - int pid = Server_GetClientID(); - for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) { - if( ent->PID == pid ) break; - if( ent->PID > pid ) break; - } - if( !ent || ent->PID > pid ) { - ent = calloc( 1, sizeof(tUserHandles) ); - ent->PID = pid; - if( prev ) { - ent->Next = prev->Next; - prev->Next = ent; - } - else { - ent->Next = gpUserHandles; - gpUserHandles = ent; - } - } + tUserHandles *ent; + int maxhandles = *Threads_GetMaxFD(); + // Find the PID's handle list + ent = VFS_int_GetUserHandles(Threads_GetPID(), 1); // Get a handle - for(i=0;iHandles[i].Node) continue; ent->Handles[i].Node = Node;