5a94e6d30a20d3f8e749579a987173c58825280b
[tpg/acess2.git] / AcessNative / acesskernel_src / vfs_handle.c
1 /*
2  * Acess2 VFS
3  * - AllocHandle, GetHandle
4  */
5 #define DEBUG   0
6 #include <acess.h>
7 #include "vfs.h"
8 #include "vfs_int.h"
9 #include "vfs_ext.h"
10
11 // === CONSTANTS ===
12 #define MAX_KERNEL_FILES        128
13 #define MAX_USER_FILES  64
14
15 // === IMPORTS ===
16 extern int      Server_GetClientID(void);
17
18 // === PROTOTYPES ===
19 tVFS_Handle     *VFS_GetHandle(int FD);
20  int    VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode);
21
22 // === Types ===
23 typedef struct sUserHandles
24 {
25         struct sUserHandles     *Next;
26          int    PID;
27         tVFS_Handle     Handles[MAX_USER_FILES];
28 }       tUserHandles;
29
30 // === GLOBALS ===
31 tUserHandles    *gpUserHandles = NULL;
32 tVFS_Handle     gaKernelHandles[MAX_KERNEL_FILES];
33
34 // === CODE ===
35 /**
36  * \fn tVFS_Handle *VFS_GetHandle(int FD)
37  * \brief Gets a pointer to the handle information structure
38  */
39 tVFS_Handle *VFS_GetHandle(int FD)
40 {
41         tVFS_Handle     *h;
42         
43         //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
44         
45         if(FD < 0)      return NULL;
46         
47         if(FD & VFS_KERNEL_FLAG) {
48                 FD &= (VFS_KERNEL_FLAG - 1);
49                 if(FD >= MAX_KERNEL_FILES)      return NULL;
50                 h = &gaKernelHandles[ FD ];
51         }
52         else {
53                 tUserHandles    *ent;
54                  int    pid = Server_GetClientID();
55                 for( ent = gpUserHandles; ent; ent = ent->Next ) {
56                         if( ent->PID == pid )   break;
57                         if( ent->PID > pid ) {
58                                 Log_Error("VFS", "PID %i does not have a handle list", pid);
59                                 return NULL;
60                         }
61                 }
62                 if( !ent ) {
63                         Log_Error("VFS", "PID %i does not have a handle list", pid);
64                         return NULL;
65                 }
66                 if(FD >= CFGINT(CFG_VFS_MAXFILES))      return NULL;
67                 h = &ent->Handles[ FD ];
68         }
69         
70         if(h->Node == NULL)     return NULL;
71         //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
72         return h;
73 }
74
75 int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
76 {
77          int    i;
78         
79         // Check for a user open
80         if(bIsUser)
81         {
82                 tUserHandles    *ent, *prev = NULL;
83                  int    pid = Server_GetClientID();
84                 for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
85                         if( ent->PID == pid )   break;
86                         if( ent->PID > pid )    break;
87                 }
88                 if( !ent || ent->PID > pid ) {
89                         ent = calloc( 1, sizeof(tUserHandles) );
90                         ent->PID = pid;
91                         if( prev ) {
92                                 ent->Next = prev->Next;
93                                 prev->Next = ent;
94                         }
95                         else {
96                                 ent->Next = gpUserHandles;
97                                 gpUserHandles = ent;
98                         }
99                 }
100                 // Get a handle
101                 for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
102                 {
103                         if(ent->Handles[i].Node)        continue;
104                         ent->Handles[i].Node = Node;
105                         ent->Handles[i].Position = 0;
106                         ent->Handles[i].Mode = Mode;
107                         return i;
108                 }
109         }
110         else
111         {
112                 // Get a handle
113                 for(i=0;i<MAX_KERNEL_FILES;i++)
114                 {
115                         if(gaKernelHandles[i].Node)     continue;
116                         gaKernelHandles[i].Node = Node;
117                         gaKernelHandles[i].Position = 0;
118                         gaKernelHandles[i].Mode = Mode;
119                         return i|VFS_KERNEL_FLAG;
120                 }
121         }
122         
123         return -1;
124 }

UCC git Repository :: git.ucc.asn.au