AcessNative - Fixing Fixing Fixing
[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                 h->Position = h->Node->Size - Offset;
148                 return 0;
149         }
150         
151         // Set relative to start of file
152         h->Position = Offset;
153         return 0;
154 }
155
156 /**
157  * \fn int VFS_IOCtl(int FD, int ID, void *Buffer)
158  * \brief Call an IO Control on a file
159  */
160 int VFS_IOCtl(int FD, int ID, void *Buffer)
161 {
162         tVFS_Handle     *h;
163         
164         h = VFS_GetHandle(FD);
165         if(!h)  return -1;
166
167         if(!h->Node->IOCtl)     return -1;
168         return h->Node->IOCtl(h->Node, ID, Buffer);
169 }
170
171 /**
172  * \fn int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs)
173  * \brief Retrieve file information
174  * \return Number of ACLs stored
175  */
176 int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs)
177 {
178         tVFS_Handle     *h;
179          int    max;
180         
181         h = VFS_GetHandle(FD);
182         if(!h)  return -1;
183         
184         Dest->uid = h->Node->UID;
185         Dest->gid = h->Node->GID;
186         Dest->size = h->Node->Size;
187         Dest->atime = h->Node->ATime;
188         Dest->ctime = h->Node->MTime;
189         Dest->mtime = h->Node->CTime;
190         Dest->numacls = h->Node->NumACLs;
191         
192         Dest->flags = 0;
193         if(h->Node->Flags & VFS_FFLAG_DIRECTORY)        Dest->flags |= 0x10;
194         if(h->Node->Flags & VFS_FFLAG_SYMLINK)  Dest->flags |= 0x20;
195         
196         max = (MaxACLs < h->Node->NumACLs) ? MaxACLs : h->Node->NumACLs;
197         memcpy(&Dest->acls, h->Node->ACLs, max*sizeof(tVFS_ACL));
198         
199         return max;
200 }
201
202 // === EXPORTS ===
203 EXPORT(VFS_Read);
204 EXPORT(VFS_Write);
205 EXPORT(VFS_ReadAt);
206 EXPORT(VFS_WriteAt);
207 EXPORT(VFS_IOCtl);
208 EXPORT(VFS_Seek);
209 EXPORT(VFS_Tell);

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