42a8fc4bfecd3925ebf2fe1e4b376f3a59c556ed
[tpg/acess2.git] / Kernel / vfs / handle.c
1 /*
2  * Acess2 VFS
3  * - AllocHandle, GetHandle
4  */
5 #define DEBUG   0
6 #include <acess.h>
7 #include <mm_virt.h>
8 #include "vfs.h"
9 #include "vfs_int.h"
10 #include "vfs_ext.h"
11 #include <threads.h>    // GetMaxFD
12
13 // === CONSTANTS ===
14 #define MAX_KERNEL_FILES        128
15
16 // === PROTOTYPES ===
17 #if 0
18 tVFS_Handle     *VFS_GetHandle(int FD);
19 #endif
20  int    VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode);
21
22 // === GLOBALS ===
23 tVFS_Handle     *gaUserHandles = (void*)MM_PPD_HANDLES;
24 tVFS_Handle     *gaKernelHandles = (void*)MM_KERNEL_VFS;
25
26 // === CODE ===
27 /**
28  * \fn tVFS_Handle *VFS_GetHandle(int FD)
29  * \brief Gets a pointer to the handle information structure
30  */
31 tVFS_Handle *VFS_GetHandle(int FD)
32 {
33         tVFS_Handle     *h;
34         
35         //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
36         
37         if(FD < 0)      return NULL;
38         
39         if(FD & VFS_KERNEL_FLAG) {
40                 FD &= (VFS_KERNEL_FLAG - 1);
41                 if(FD >= MAX_KERNEL_FILES)      return NULL;
42                 h = &gaKernelHandles[ FD ];
43         } else {
44                 if(FD >= *Threads_GetMaxFD())   return NULL;
45                 h = &gaUserHandles[ FD ];
46         }
47         
48         if(h->Node == NULL)     return NULL;
49         //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
50         return h;
51 }
52
53 int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
54 {
55          int    i;
56         
57         // Check for a user open
58         if(bIsUser)
59         {
60                  int    max_handles = *Threads_GetMaxFD();
61                 // Allocate Buffer
62                 if( MM_GetPhysAddr( (tVAddr)gaUserHandles ) == 0 )
63                 {
64                         Uint    addr, size;
65                         size = max_handles * sizeof(tVFS_Handle);
66                         for(addr = 0; addr < size; addr += 0x1000)
67                         {
68                                 if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) )
69                                 {
70                                         Warning("OOM - VFS_AllocHandle");
71                                         Threads_Exit(0, 0xFF);  // Terminate user
72                                 }
73                         }
74                         memset( gaUserHandles, 0, size );
75                 }
76                 // Get a handle
77                 for( i = 0; i < max_handles; i ++ )
78                 {
79                         if(gaUserHandles[i].Node)       continue;
80                         gaUserHandles[i].Node = Node;
81                         gaUserHandles[i].Position = 0;
82                         gaUserHandles[i].Mode = Mode;
83                         return i;
84                 }
85         }
86         else
87         {
88                 // Allocate space if not already
89                 if( MM_GetPhysAddr( (tVAddr)gaKernelHandles ) == 0 )
90                 {
91                         Uint    addr, size;
92                         size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
93                         for(addr = 0; addr < size; addr += 0x1000)
94                         {
95                                 if( !MM_Allocate( (tVAddr)gaKernelHandles + addr ) )
96                                 {
97                                         Panic("OOM - VFS_AllocHandle");
98                                         Threads_Exit(0, 0xFF);  // Terminate application (get some space back)
99                                 }
100                         }
101                         memset( gaKernelHandles, 0, size );
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