Usermode/ld-acess - Added two more ARM relocation types
[tpg/acess2.git] / Kernel / vfs / io.c
1 /*
2  * AcessMicro VFS
3  * - File IO Passthru's
4  */
5 #define DEBUG   0
6 #include <acess.h>
7 #include "vfs.h"
8 #include "vfs_int.h"
9
10 // === CODE ===
11 /**
12  * \fn Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer)
13  * \brief Read data from a node (file)
14  */
15 Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer)
16 {
17         tVFS_Handle     *h;
18         Uint64  ret;
19         
20         ENTER("iFD XLength pBuffer", FD, Length, Buffer);
21         
22         h = VFS_GetHandle(FD);
23         if(!h)  LEAVE_RET('i', -1);
24         
25         if( !(h->Mode & VFS_OPENFLAG_READ) || h->Node->Flags & VFS_FFLAG_DIRECTORY )
26                 LEAVE_RET('i', -1);
27
28         if(!h->Node->Read)      LEAVE_RET('i', 0);
29         
30         ret = h->Node->Read(h->Node, h->Position, Length, Buffer);
31         if(ret == -1)   LEAVE_RET('i', -1);
32         
33         h->Position += ret;
34         LEAVE('X', ret);
35         return ret;
36 }
37
38 /**
39  * \fn Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer)
40  * \brief Read data from a given offset (atomic)
41  */
42 Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer)
43 {
44         tVFS_Handle     *h;
45         Uint64  ret;
46         
47         h = VFS_GetHandle(FD);
48         if(!h)  return -1;
49         
50         if( !(h->Mode & VFS_OPENFLAG_READ) )    return -1;
51         if( h->Node->Flags & VFS_FFLAG_DIRECTORY )      return -1;
52
53         if(!h->Node->Read) {
54                 Warning("VFS_ReadAt - Node %p, does not have a read method", h->Node);
55                 return 0;
56         }
57         ret = h->Node->Read(h->Node, Offset, Length, Buffer);
58         if(ret == -1)   return -1;
59         return ret;
60 }
61
62 /**
63  * \fn Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer)
64  * \brief Read data from a node (file)
65  */
66 Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer)
67 {
68         tVFS_Handle     *h;
69         Uint64  ret;
70         
71         h = VFS_GetHandle(FD);
72         if(!h)  return -1;
73         
74         if( !(h->Mode & VFS_OPENFLAG_WRITE) )   return -1;
75         if( h->Node->Flags & VFS_FFLAG_DIRECTORY )      return -1;
76
77         if(!h->Node->Write)     return 0;
78         
79         // TODO: This is a hack, I need to change VFS_Node to have "const void*"
80         ret = h->Node->Write(h->Node, h->Position, Length, (void*)Buffer);
81         if(ret == -1)   return -1;
82         h->Position += ret;
83         return ret;
84 }
85
86 /**
87  * \fn Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer)
88  * \brief Write data to a file at a given offset
89  */
90 Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer)
91 {
92         tVFS_Handle     *h;
93         Uint64  ret;
94         
95         h = VFS_GetHandle(FD);
96         if(!h)  return -1;
97         
98         if( !(h->Mode & VFS_OPENFLAG_WRITE) )   return -1;
99         if( h->Node->Flags & VFS_FFLAG_DIRECTORY )      return -1;
100
101         if(!h->Node->Write)     return 0;
102         // TODO: This is a hack, I need to change VFS_Node to have "const void*"
103         ret = h->Node->Write(h->Node, Offset, Length, (void*)Buffer);
104         if(ret == -1)   return -1;
105         return ret;
106 }
107
108 /**
109  * \fn Uint64 VFS_Tell(int FD)
110  * \brief Returns the current file position
111  */
112 Uint64 VFS_Tell(int FD)
113 {
114         tVFS_Handle     *h;
115         
116         h = VFS_GetHandle(FD);
117         if(!h)  return -1;
118         
119         return h->Position;
120 }
121
122 /**
123  * \fn int VFS_Seek(int FD, Sint64 Offset, int Whence)
124  * \brief Seek to a new location
125  * \param FD    File descriptor
126  * \param Offset        Where to go
127  * \param Whence        From where
128  */
129 int VFS_Seek(int FD, Sint64 Offset, int Whence)
130 {
131         tVFS_Handle     *h;
132         
133         h = VFS_GetHandle(FD);
134         if(!h)  return -1;
135         
136         //Log_Debug("VFS", "VFS_Seek: (fd=0x%x, Offset=0x%llx, Whence=%i)",
137         //      FD, Offset, Whence);
138         
139         // Set relative to current position
140         if(Whence == 0) {
141                 h->Position += Offset;
142                 return 0;
143         }
144         
145         // Set relative to end of file
146         if(Whence < 0) {
147                 if( h->Node->Size == -1 )       return -1;
148
149                 h->Position = h->Node->Size - Offset;
150                 return 0;
151         }
152         
153         // Set relative to start of file
154         h->Position = Offset;
155         return 0;
156 }
157
158 /**
159  * \fn int VFS_IOCtl(int FD, int ID, void *Buffer)
160  * \brief Call an IO Control on a file
161  */
162 int VFS_IOCtl(int FD, int ID, void *Buffer)
163 {
164         tVFS_Handle     *h;
165         
166         h = VFS_GetHandle(FD);
167         if(!h)  return -1;
168
169         if(!h->Node->IOCtl)     return -1;
170         return h->Node->IOCtl(h->Node, ID, Buffer);
171 }
172
173 /**
174  * \fn int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs)
175  * \brief Retrieve file information
176  * \return Number of ACLs stored
177  */
178 int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs)
179 {
180         tVFS_Handle     *h;
181          int    max;
182         
183         h = VFS_GetHandle(FD);
184         if(!h)  return -1;
185
186         if( h->Mount )
187                 Dest->mount = h->Mount->Identifier;
188         else
189                 Dest->mount = 0;
190         Dest->inode = h->Node->Inode;   
191         Dest->uid = h->Node->UID;
192         Dest->gid = h->Node->GID;
193         Dest->size = h->Node->Size;
194         Dest->atime = h->Node->ATime;
195         Dest->ctime = h->Node->MTime;
196         Dest->mtime = h->Node->CTime;
197         Dest->numacls = h->Node->NumACLs;
198         
199         Dest->flags = 0;
200         if(h->Node->Flags & VFS_FFLAG_DIRECTORY)        Dest->flags |= 0x10;
201         if(h->Node->Flags & VFS_FFLAG_SYMLINK)  Dest->flags |= 0x20;
202         
203         max = (MaxACLs < h->Node->NumACLs) ? MaxACLs : h->Node->NumACLs;
204         memcpy(&Dest->acls, h->Node->ACLs, max*sizeof(tVFS_ACL));
205         
206         return max;
207 }
208
209 // === EXPORTS ===
210 EXPORT(VFS_Read);
211 EXPORT(VFS_Write);
212 EXPORT(VFS_ReadAt);
213 EXPORT(VFS_WriteAt);
214 EXPORT(VFS_IOCtl);
215 EXPORT(VFS_Seek);
216 EXPORT(VFS_Tell);

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