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

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