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 ) {
40 Log_Warning("VFS", "Process %i already has a handle list", PID);
43 if( ent->PID > PID ) break;
49 ent = calloc( 1, sizeof(tUserHandles) );
52 ent->Next = prev->Next;
56 ent->Next = gpUserHandles;
59 Log_Notice("VFS", "Created handle list for process %i", PID);
64 * \brief Clone the handle list of the current process into another
66 void VFS_CloneHandleList(int PID)
72 cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
73 if(!cur) return ; // Don't need to do anything if the current list is empty
75 ent = VFS_int_GetUserHandles(PID, 1);
77 memcpy(ent->Handles, cur->Handles, CFGINT(CFG_VFS_MAXFILES)*sizeof(tVFS_Handle));
79 for( i = 0; i < CFGINT(CFG_VFS_MAXFILES); i ++ )
81 if(!cur->Handles[i].Node) continue;
83 if(ent->Handles[i].Node->Reference)
84 ent->Handles[i].Node->Reference(ent->Handles[i].Node);
89 * \fn tVFS_Handle *VFS_GetHandle(int FD)
90 * \brief Gets a pointer to the handle information structure
92 tVFS_Handle *VFS_GetHandle(int FD)
96 //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
99 LOG("FD (%i) < 0, RETURN NULL", FD);
103 if(FD & VFS_KERNEL_FLAG) {
104 FD &= (VFS_KERNEL_FLAG - 1);
105 if(FD >= MAX_KERNEL_FILES) {
106 LOG("FD (%i) > MAX_KERNEL_FILES (%i), RETURN NULL", FD, MAX_KERNEL_FILES);
109 h = &gaKernelHandles[ FD ];
114 int pid = Threads_GetPID();
116 ent = VFS_int_GetUserHandles(pid, 0);
118 Log_Error("VFS", "Client %i does not have a handle list (>)", pid);
122 if(FD >= CFGINT(CFG_VFS_MAXFILES)) {
123 LOG("FD (%i) > Limit (%i), RETURN NULL", FD, CFGINT(CFG_VFS_MAXFILES));
126 h = &ent->Handles[ FD ];
127 LOG("FD (%i) -> %p (Mode:0x%x,Node:%p)", FD, h, h->Mode, h->Node);
130 if(h->Node == NULL) {
131 LOG("FD (%i) Unused", FD);
134 //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
138 int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
142 // Check for a user open
146 // Find the PID's handle list
147 ent = VFS_int_GetUserHandles(Threads_GetPID(), 1);
149 for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
151 if(ent->Handles[i].Node) continue;
152 ent->Handles[i].Node = Node;
153 ent->Handles[i].Position = 0;
154 ent->Handles[i].Mode = Mode;
161 for(i=0;i<MAX_KERNEL_FILES;i++)
163 if(gaKernelHandles[i].Node) continue;
164 gaKernelHandles[i].Node = Node;
165 gaKernelHandles[i].Position = 0;
166 gaKernelHandles[i].Mode = Mode;
167 return i|VFS_KERNEL_FLAG;