3 * - AllocHandle, GetHandle
13 #define MAX_KERNEL_FILES 128
14 #define MAX_USER_FILES 64
17 extern int Server_GetClientID(void);
20 tVFS_Handle *VFS_GetHandle(int FD);
21 int VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode);
24 typedef struct sUserHandles
26 struct sUserHandles *Next;
28 tVFS_Handle Handles[MAX_USER_FILES];
32 tUserHandles *gpUserHandles = NULL;
33 tVFS_Handle gaKernelHandles[MAX_KERNEL_FILES];
36 tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate)
38 tUserHandles *ent, *prev = NULL;
39 for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
40 if( ent->PID == PID ) {
42 // Log_Warning("VFS", "Process %i already has a handle list", PID);
43 LOG("Found list for %i", PID);
46 if( ent->PID > PID ) break;
50 LOG("Not creating for %i", PID);
54 ent = calloc( 1, sizeof(tUserHandles) );
57 ent->Next = prev->Next;
61 ent->Next = gpUserHandles;
64 LOG("Created handle list for process %i", PID);
69 * \brief Clone the handle list of the current process into another
71 void VFS_CloneHandleList(int PID)
74 const tUserHandles *cur;
77 cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
78 if(!cur) return ; // Don't need to do anything if the current list is empty
80 ent = VFS_int_GetUserHandles(PID, 1);
82 maxhandles = *Threads_GetMaxFD();
83 memcpy(ent->Handles, cur->Handles, maxhandles*sizeof(tVFS_Handle));
86 for( int i = 0; i < maxhandles; i ++ )
88 if(!ent->Handles[i].Node) continue;
90 if(ent->Handles[i].Node->Type->Reference)
91 ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node);
95 void VFS_CloneHandlesFromList(int PID, int nFD, int FDs[])
98 const tUserHandles *cur;
101 cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
102 if(!cur) return ; // Don't need to do anything if the current list is empty
104 ent = VFS_int_GetUserHandles(PID, 1);
106 LOG("Copying %i FDs from %i", nFD, PID);
108 maxhandles = *Threads_GetMaxFD();
109 if( nFD > maxhandles )
111 for( int i = 0; i < nFD; i ++ )
114 if( fd >= maxhandles ) {
115 ent->Handles[i].Node = NULL;
118 memcpy(&ent->Handles[i], &cur->Handles[fd], sizeof(tVFS_Handle));
120 for( int i = nFD; i < maxhandles; i ++ )
121 ent->Handles[i].Node = NULL;
124 for( int i = 0; i < maxhandles; i ++ )
126 if(!ent->Handles[i].Node) continue;
128 if(ent->Handles[i].Node->Type->Reference)
129 ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node);
134 * \fn tVFS_Handle *VFS_GetHandle(int FD)
135 * \brief Gets a pointer to the handle information structure
137 tVFS_Handle *VFS_GetHandle(int FD)
141 //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
144 LOG("FD (%i) < 0, RETURN NULL", FD);
148 if(FD & VFS_KERNEL_FLAG) {
149 FD &= (VFS_KERNEL_FLAG - 1);
150 if(FD >= MAX_KERNEL_FILES) {
151 LOG("FD (%i) > MAX_KERNEL_FILES (%i), RETURN NULL", FD, MAX_KERNEL_FILES);
154 h = &gaKernelHandles[ FD ];
159 int pid = Threads_GetPID();
160 int maxhandles = *Threads_GetMaxFD();
162 ent = VFS_int_GetUserHandles(pid, 0);
164 Log_Error("VFS", "Client %i does not have a handle list (>)", pid);
168 if(FD >= maxhandles) {
169 LOG("FD (%i) > Limit (%i), RETURN NULL", FD, maxhandles);
172 h = &ent->Handles[ FD ];
173 LOG("FD (%i) -> %p (Mode:0x%x,Node:%p)", FD, h, h->Mode, h->Node);
176 if(h->Node == NULL) {
177 LOG("FD (%i) Unused", FD);
180 //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
184 int VFS_SetHandle(int FD, tVFS_Node *Node, int Mode)
187 if(FD < 0) return -1;
189 if( FD & VFS_KERNEL_FLAG ) {
190 FD &= (VFS_KERNEL_FLAG -1);
191 if( FD >= MAX_KERNEL_FILES ) return -1;
192 h = &gaKernelHandles[FD];
196 int pid = Threads_GetPID();
197 int maxhandles = *Threads_GetMaxFD();
199 ent = VFS_int_GetUserHandles(pid, 0);
201 Log_Error("VFS", "Client %i does not have a handle list (>)", pid);
205 if(FD >= maxhandles) {
206 LOG("FD (%i) > Limit (%i), RETURN NULL", FD, maxhandles);
209 h = &ent->Handles[ FD ];
217 int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
219 // Check for a user open
223 int maxhandles = *Threads_GetMaxFD();
224 // Find the PID's handle list
225 ent = VFS_int_GetUserHandles(Threads_GetPID(), 1);
227 for( int i = 0; i < maxhandles; i ++ )
229 if(ent->Handles[i].Node) continue;
230 ent->Handles[i].Node = Node;
231 ent->Handles[i].Position = 0;
232 ent->Handles[i].Mode = Mode;
239 for(int i = 0; i < MAX_KERNEL_FILES; i ++)
241 if(gaKernelHandles[i].Node) continue;
242 gaKernelHandles[i].Node = Node;
243 gaKernelHandles[i].Position = 0;
244 gaKernelHandles[i].Mode = Mode;
245 return i|VFS_KERNEL_FLAG;