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);
45 if( ent->PID > PID ) break;
51 ent = calloc( 1, sizeof(tUserHandles) );
54 ent->Next = prev->Next;
58 ent->Next = gpUserHandles;
61 Log_Notice("VFS", "Created handle list for process %i", PID);
66 * \brief Clone the handle list of the current process into another
68 void VFS_CloneHandleList(int PID)
74 cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
75 if(!cur) return ; // Don't need to do anything if the current list is empty
77 ent = VFS_int_GetUserHandles(PID, 1);
79 maxhandles = *Threads_GetMaxFD();
80 memcpy(ent->Handles, cur->Handles, maxhandles*sizeof(tVFS_Handle));
82 for( i = 0; i < maxhandles; i ++ )
84 if(!cur->Handles[i].Node) continue;
86 if(ent->Handles[i].Node->Type->Reference)
87 ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node);
92 * \fn tVFS_Handle *VFS_GetHandle(int FD)
93 * \brief Gets a pointer to the handle information structure
95 tVFS_Handle *VFS_GetHandle(int FD)
99 //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
102 LOG("FD (%i) < 0, RETURN NULL", FD);
106 if(FD & VFS_KERNEL_FLAG) {
107 FD &= (VFS_KERNEL_FLAG - 1);
108 if(FD >= MAX_KERNEL_FILES) {
109 LOG("FD (%i) > MAX_KERNEL_FILES (%i), RETURN NULL", FD, MAX_KERNEL_FILES);
112 h = &gaKernelHandles[ FD ];
117 int pid = Threads_GetPID();
118 int maxhandles = *Threads_GetMaxFD();
120 ent = VFS_int_GetUserHandles(pid, 0);
122 Log_Error("VFS", "Client %i does not have a handle list (>)", pid);
126 if(FD >= maxhandles) {
127 LOG("FD (%i) > Limit (%i), RETURN NULL", FD, maxhandles);
130 h = &ent->Handles[ FD ];
131 LOG("FD (%i) -> %p (Mode:0x%x,Node:%p)", FD, h, h->Mode, h->Node);
134 if(h->Node == NULL) {
135 LOG("FD (%i) Unused", FD);
138 //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
142 int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
146 // Check for a user open
150 int maxhandles = *Threads_GetMaxFD();
151 // Find the PID's handle list
152 ent = VFS_int_GetUserHandles(Threads_GetPID(), 1);
154 for( i = 0; i < maxhandles; i ++ )
156 if(ent->Handles[i].Node) continue;
157 ent->Handles[i].Node = Node;
158 ent->Handles[i].Position = 0;
159 ent->Handles[i].Mode = Mode;
166 for(i=0;i<MAX_KERNEL_FILES;i++)
168 if(gaKernelHandles[i].Node) continue;
169 gaKernelHandles[i].Node = Node;
170 gaKernelHandles[i].Position = 0;
171 gaKernelHandles[i].Mode = Mode;
172 return i|VFS_KERNEL_FLAG;