/// <summary> /// Manipulates underlying parameters in files /// </summary> /// <param name="fd">The file descriptor</param> /// <param name="request">The request</param> /// <param name="arg">An optional argument</param> /// <returns>The errorcode or return value from IOCtl</returns> public static unsafe int IOCtl(int fd, int request, void *arg) { FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors; Node node = descriptors.GetNode(fd); if (node == null) { return(-(int)ErrorCode.EBADF); } return(VFS.IOCtl(node, request, arg)); }
/// <summary> /// Truncates a file by a file descriptor /// </summary> /// <param name="descriptor">The file descriptor</param> /// <param name="length">The length to truncate to</param> /// <returns>Errorcode</returns> public static int FTruncate(int descriptor, uint length) { FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors; Node node = descriptors.GetNode(descriptor); if (node == null) { return(-(int)ErrorCode.EBADF); } VFS.Truncate(node, length); return(0); }
/// <summary> /// Gets the file status of a descriptor /// </summary> /// <param name="descriptor">The descriptor ID</param> /// <param name="st">The stat structure</param> /// <returns>The errorcode</returns> public static unsafe ErrorCode FStat(int descriptor, Stat *st) { FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors; Node node = descriptors.GetNode(descriptor); if (node == null) { return(ErrorCode.EBADF); } node.Stat(st); return(ErrorCode.SUCCESS); }
/// <summary> /// Sets the file position of the descriptor to the given offset /// </summary> /// <param name="descriptor">The descriptor</param> /// <param name="offset">The offset</param> /// <param name="whence">The direction</param> /// <returns>The new offset from the beginning of the file in bytes</returns> public static int Seek(int descriptor, int offset, FileWhence whence) { FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors; Node node = descriptors.GetNode(descriptor); if (node == null) { return(-(int)ErrorCode.EBADF); } uint currentOffset = descriptors.GetOffset(descriptor); if (whence == FileWhence.SEEK_CUR) { currentOffset = (uint)(currentOffset + offset); } else if (whence == FileWhence.SEEK_SET) { if (offset < 0) { currentOffset = 0; } else { currentOffset = (uint)offset; } } else if (whence == FileWhence.SEEK_END) { if (offset > 0) { currentOffset = node.Size; } else { currentOffset = (uint)(node.Size + offset); } } else { return(-(int)ErrorCode.EINVAL); } descriptors.SetOffset(descriptor, currentOffset); return((int)currentOffset); }
/// <summary> /// Write to a file descriptor /// </summary> /// <param name="descriptor">The descriptor ID</param> /// <param name="buffer">The buffer</param> /// <param name="size">The size</param> /// <returns>The amount of bytes written</returns> public static int Write(int descriptor, byte[] buffer, uint size) { FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors; Node node = descriptors.GetNode(descriptor); if (node == null) { return(-(int)ErrorCode.EBADF); } uint offset = descriptors.GetOffset(descriptor); descriptors.SetOffset(descriptor, offset + size); return((int)VFS.Write(node, offset, size, buffer)); }
/// <summary> /// Read from a file descriptor /// </summary> /// <param name="descriptor">The descriptor ID</param> /// <param name="buffer">The buffer</param> /// <param name="size">The size</param> /// <returns>The amount of bytes read</returns> public static int Read(int descriptor, byte[] buffer, uint size) { FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors; Node node = descriptors.GetNode(descriptor); if (node == null) { return(-(int)ErrorCode.EBADF); } // Can't do read from a directory if ((node.Flags & NodeFlags.DIRECTORY) == NodeFlags.DIRECTORY) { return(-(int)ErrorCode.EISDIR); } bool isNonBlocking = ((node.OpenFlags & O_NONBLOCK) == O_NONBLOCK); // Wait until data is available if its blocking if (!isNonBlocking) { while (VFS.GetSize(node) == 0) { Tasking.Yield(); } } // Non-blocking but no data available? else { if (VFS.GetSize(node) == 0) { return(-(int)ErrorCode.EAGAIN); } } uint offset = descriptors.GetOffset(descriptor); uint readBytes = VFS.Read(node, offset, size, buffer); descriptors.SetOffset(descriptor, offset + readBytes); return((int)readBytes); }
/// <summary> /// Reads a directory entry /// </summary> /// <param name="descriptor">The descriptor</param> /// <param name="entry">The directory entry</param> /// <param name="index">The index</param> /// <returns>Errorcode</returns> public static unsafe ErrorCode Readdir(int descriptor, DirEntry *entry, uint index) { FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors; Node node = descriptors.GetNode(descriptor); if (node == null) { return(ErrorCode.EBADF); } DirEntry *gotEntry = VFS.ReadDir(node, index); if (gotEntry == null) { return(ErrorCode.ENOENT); } Memory.Memcpy(entry, gotEntry, sizeof(DirEntry)); Heap.Free(gotEntry); return(ErrorCode.SUCCESS); }