23 * \fn Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer)
24 * \brief Read data from a node (file)
26 Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer)
31 ENTER("iFD XLength pBuffer", FD, Length, Buffer);
33 h = VFS_GetHandle(FD);
36 if( !(h->Mode & VFS_OPENFLAG_READ) || h->Node->Flags & VFS_FFLAG_DIRECTORY ) {
46 ret = h->Node->Read(h->Node, h->Position, Length, Buffer);
58 * \fn Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer)
59 * \brief Read data from a given offset (atomic)
61 Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer)
66 h = VFS_GetHandle(FD);
69 if( !(h->Mode & VFS_OPENFLAG_READ) ) return -1;
70 if( h->Node->Flags & VFS_FFLAG_DIRECTORY ) return -1;
73 Warning("VFS_ReadAt - Node %p, does not have a read method", h->Node);
76 ret = h->Node->Read(h->Node, Offset, Length, Buffer);
77 if(ret == -1) return -1;
82 * \fn Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer)
83 * \brief Read data from a node (file)
85 Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer)
90 h = VFS_GetHandle(FD);
93 if( !(h->Mode & VFS_OPENFLAG_WRITE) ) return -1;
94 if( h->Node->Flags & VFS_FFLAG_DIRECTORY ) return -1;
96 if(!h->Node->Write) return 0;
98 // TODO: This is a hack, I need to change VFS_Node to have "const void*"
99 ret = h->Node->Write(h->Node, h->Position, Length, (void*)Buffer);
100 if(ret == -1) return -1;
106 * \fn Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer)
107 * \brief Write data to a file at a given offset
109 Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer)
114 h = VFS_GetHandle(FD);
117 if( !(h->Mode & VFS_OPENFLAG_WRITE) ) return -1;
118 if( h->Node->Flags & VFS_FFLAG_DIRECTORY ) return -1;
120 if(!h->Node->Write) return 0;
121 // TODO: This is a hack, I need to change VFS_Node to have "const void*"
122 ret = h->Node->Write(h->Node, Offset, Length, (void*)Buffer);
123 if(ret == -1) return -1;
128 * \fn Uint64 VFS_Tell(int FD)
129 * \brief Returns the current file position
131 Uint64 VFS_Tell(int FD)
135 h = VFS_GetHandle(FD);
142 * \fn int VFS_Seek(int FD, Sint64 Offset, int Whence)
143 * \brief Seek to a new location
144 * \param FD File descriptor
145 * \param Offset Where to go
146 * \param Whence From where
148 int VFS_Seek(int FD, Sint64 Offset, int Whence)
152 h = VFS_GetHandle(FD);
155 //Log_Debug("VFS", "VFS_Seek: (fd=0x%x, Offset=0x%llx, Whence=%i)",
156 // FD, Offset, Whence);
158 // Set relative to current position
160 h->Position += Offset;
164 // Set relative to end of file
166 h->Position = h->Node->Size - Offset;
170 // Set relative to start of file
171 h->Position = Offset;
176 * \fn int VFS_IOCtl(int FD, int ID, void *Buffer)
177 * \brief Call an IO Control on a file
179 int VFS_IOCtl(int FD, int ID, void *Buffer)
183 h = VFS_GetHandle(FD);
186 if(!h->Node->IOCtl) return -1;
187 return h->Node->IOCtl(h->Node, ID, Buffer);
191 * \fn int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs)
192 * \brief Retrieve file information
193 * \return Number of ACLs stored
195 int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs)
200 h = VFS_GetHandle(FD);
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;
212 if(h->Node->Flags & VFS_FFLAG_DIRECTORY) Dest->flags |= 0x10;
213 if(h->Node->Flags & VFS_FFLAG_SYMLINK) Dest->flags |= 0x20;
215 max = (MaxACLs < h->Node->NumACLs) ? MaxACLs : h->Node->NumACLs;
216 memcpy(&Dest->acls, h->Node->ACLs, max*sizeof(tVFS_ACL));