aab30fc08b20496b81623b5e241ee694ca522d28
[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 // === PROTOTYPES ===
16 tVFS_Handle     *VFS_GetHandle(int FD);
17  int    VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode);
18
19 typedef struct sUserHandles
20 {
21         struct sUserHandles     *Next;
22          int    PID;
23         tVFS_Handle     Handles[MAX_USER_FILES];
24 }       tUserHandles;
25
26 // === GLOBALS ===
27 tUserHandles    *gpUserHandles = NULL;
28 tVFS_Handle     gaKernelHandles[MAX_KERNEL_FILES];
29
30 // === CODE ===
31 /**
32  * \fn tVFS_Handle *VFS_GetHandle(int FD)
33  * \brief Gets a pointer to the handle information structure
34  */
35 tVFS_Handle *VFS_GetHandle(int FD)
36 {
37         tVFS_Handle     *h;
38         
39         //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
40         
41         if(FD < 0)      return NULL;
42         
43         if(FD & VFS_KERNEL_FLAG) {
44                 FD &= (VFS_KERNEL_FLAG - 1);
45                 if(FD >= MAX_KERNEL_FILES)      return NULL;
46                 h = &gaKernelHandles[ FD ];
47         }
48         else {
49                 tUserHandles    *ent;
50                  int    pid = Threads_GetPID();
51                 for( ent = gpUserHandles; ent; ent = ent->Next ) {
52                         if( ent->PID == pid )   break;
53                         if( ent->PID > pid ) {
54                                 Log_Error("VFS", "PID %i does not have a handle list", pid);
55                                 return NULL;
56                         }
57                 }
58                 if(FD >= CFGINT(CFG_VFS_MAXFILES))      return NULL;
59                 h = &ent->Handles[ FD ];
60         }
61         
62         if(h->Node == NULL)     return NULL;
63         //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
64         return h;
65 }
66
67 int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
68 {
69          int    i;
70         
71         // Check for a user open
72         if(bIsUser)
73         {
74                 tUserHandles    *ent, *prev;
75                  int    pid = Threads_GetPID();
76                 for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
77                         if( ent->PID == pid )   break;
78                         if( ent->PID > pid )    break;
79                 }
80                 if( ent->PID > pid ) {
81                         ent = calloc( 1, sizeof(tUserHandles) );
82                         if( prev ) {
83                                 ent->Next = prev->Next;
84                                 prev->Next = ent;
85                         }
86                         else {
87                                 ent->Next = gpUserHandles;
88                                 gpUserHandles = ent;
89                         }
90                 }
91                 // Get a handle
92                 for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
93                 {
94                         if(ent->Handles[i].Node)        continue;
95                         ent->Handles[i].Node = Node;
96                         ent->Handles[i].Position = 0;
97                         ent->Handles[i].Mode = Mode;
98                         return i;
99                 }
100         }
101         else
102         {
103                 // Get a handle
104                 for(i=0;i<MAX_KERNEL_FILES;i++)
105                 {
106                         if(gaKernelHandles[i].Node)     continue;
107                         gaKernelHandles[i].Node = Node;
108                         gaKernelHandles[i].Position = 0;
109                         gaKernelHandles[i].Mode = Mode;
110                         return i|VFS_KERNEL_FLAG;
111                 }
112         }
113         
114         return -1;
115 }

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