3 * - AllocHandle, GetHandle
12 #define MAX_KERNEL_FILES 128
13 #define MAX_USER_FILES 64
16 extern int Server_GetClientID(void);
19 tVFS_Handle *VFS_GetHandle(int FD);
20 int VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode);
23 typedef struct sUserHandles
25 struct sUserHandles *Next;
27 tVFS_Handle Handles[MAX_USER_FILES];
31 tUserHandles *gpUserHandles = NULL;
32 tVFS_Handle gaKernelHandles[MAX_KERNEL_FILES];
35 tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate)
37 tUserHandles *ent, *prev = NULL;
38 for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
39 if( ent->PID == PID ) {
41 Log_Warning("VFS", "Process %i already has a handle list", PID);
44 if( ent->PID > PID ) break;
50 ent = calloc( 1, sizeof(tUserHandles) );
53 ent->Next = prev->Next;
57 ent->Next = gpUserHandles;
60 Log_Notice("VFS", "Created handle list for process %i", PID);
65 * \brief Clone the handle list of the current process into another
67 void VFS_CloneHandleList(int PID)
73 cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
74 if(!cur) return ; // Don't need to do anything if the current list is empty
76 ent = VFS_int_GetUserHandles(PID, 1);
78 memcpy(ent->Handles, cur->Handles, CFGINT(CFG_VFS_MAXFILES)*sizeof(tVFS_Handle));
80 for( i = 0; i < CFGINT(CFG_VFS_MAXFILES); i ++ )
82 if(!cur->Handles[i].Node) continue;
84 if(ent->Handles[i].Node->Reference)
85 ent->Handles[i].Node->Reference(ent->Handles[i].Node);
90 * \fn tVFS_Handle *VFS_GetHandle(int FD)
91 * \brief Gets a pointer to the handle information structure
93 tVFS_Handle *VFS_GetHandle(int FD)
97 //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
100 LOG("FD (%i) < 0, RETURN NULL", FD);
104 if(FD & VFS_KERNEL_FLAG) {
105 FD &= (VFS_KERNEL_FLAG - 1);
106 if(FD >= MAX_KERNEL_FILES) {
107 LOG("FD (%i) > MAX_KERNEL_FILES (%i), RETURN NULL", FD, MAX_KERNEL_FILES);
110 h = &gaKernelHandles[ FD ];
115 int pid = Threads_GetPID();
117 ent = VFS_int_GetUserHandles(pid, 0);
119 Log_Error("VFS", "Client %i does not have a handle list (>)", pid);
123 if(FD >= CFGINT(CFG_VFS_MAXFILES)) {
124 LOG("FD (%i) > Limit (%i), RETURN NULL", FD, CFGINT(CFG_VFS_MAXFILES));
127 h = &ent->Handles[ FD ];
128 LOG("FD (%i) -> %p (Mode:0x%x,Node:%p)", FD, h, h->Mode, h->Node);
131 if(h->Node == NULL) {
132 LOG("FD (%i) Unused", FD);
135 //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
139 int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
143 // Check for a user open
147 // Find the PID's handle list
148 ent = VFS_int_GetUserHandles(Threads_GetPID(), 1);
150 for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
152 if(ent->Handles[i].Node) continue;
153 ent->Handles[i].Node = Node;
154 ent->Handles[i].Position = 0;
155 ent->Handles[i].Mode = Mode;
162 for(i=0;i<MAX_KERNEL_FILES;i++)
164 if(gaKernelHandles[i].Node) continue;
165 gaKernelHandles[i].Node = Node;
166 gaKernelHandles[i].Position = 0;
167 gaKernelHandles[i].Mode = Mode;
168 return i|VFS_KERNEL_FLAG;