mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
164 lines
3.7 KiB
C++
164 lines
3.7 KiB
C++
/*
|
|
This file is part of Fennix Kernel.
|
|
|
|
Fennix Kernel is free software: you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation, either version 3 of
|
|
the License, or (at your option) any later version.
|
|
|
|
Fennix Kernel is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <filesystem.hpp>
|
|
|
|
#ifdef DEBUG
|
|
const char *SeekStrings[] =
|
|
{"SEEK_SET",
|
|
"SEEK_CUR",
|
|
"SEEK_END"};
|
|
#endif
|
|
|
|
namespace vfs
|
|
{
|
|
size_t RefNode::read(uint8_t *Buffer, size_t Size)
|
|
{
|
|
if (this->SymlinkTo)
|
|
return this->SymlinkTo->read(Buffer, Size);
|
|
|
|
debug("Reading %d bytes from %s[%d]",
|
|
Size, this->node->FullPath, this->FileOffset.load());
|
|
return this->node->read(Buffer, Size, this->FileOffset.load());
|
|
}
|
|
|
|
size_t RefNode::write(uint8_t *Buffer, size_t Size)
|
|
{
|
|
if (this->SymlinkTo)
|
|
return this->SymlinkTo->write(Buffer, Size);
|
|
|
|
debug("Writing %d bytes to %s[%d]",
|
|
Size, this->node->FullPath, this->FileOffset.load());
|
|
return this->node->write(Buffer, Size, this->FileOffset.load());
|
|
}
|
|
|
|
off_t RefNode::seek(off_t Offset, int Whence)
|
|
{
|
|
if (this->SymlinkTo)
|
|
return this->SymlinkTo->seek(Offset, Whence);
|
|
|
|
// debug("Current offset is %d", this->Offset.load());
|
|
switch (Whence)
|
|
{
|
|
case SEEK_SET:
|
|
{
|
|
if (Offset > this->FileSize)
|
|
return -EINVAL;
|
|
|
|
if (Offset < 0)
|
|
{
|
|
fixme("Negative offset %d is not implemented", Offset);
|
|
Offset = 0;
|
|
}
|
|
|
|
if (Offset > this->FileSize)
|
|
{
|
|
fixme("Offset %d is bigger than file size %d",
|
|
Offset, this->FileSize);
|
|
Offset = this->FileSize;
|
|
}
|
|
|
|
this->FileOffset.store(Offset);
|
|
break;
|
|
}
|
|
case SEEK_CUR:
|
|
{
|
|
off_t NewOffset = off_t(this->FileOffset.load()) + Offset;
|
|
if (NewOffset > this->FileSize ||
|
|
NewOffset < 0)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
this->FileOffset.store(NewOffset);
|
|
break;
|
|
}
|
|
case SEEK_END:
|
|
{
|
|
off_t NewOffset = this->FileSize + Offset;
|
|
if (NewOffset > this->FileSize ||
|
|
NewOffset < 0)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
this->FileOffset.store(NewOffset);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
error("Invalid whence!");
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
off_t RetOffset = off_t(this->FileOffset.load());
|
|
// debug("( %d %ld %s[%d] ) -> %d",
|
|
// Offset, this->Offset.load(),
|
|
// SeekStrings[Whence], Whence,
|
|
// RetOffset);
|
|
return RetOffset;
|
|
}
|
|
|
|
int RefNode::ioctl(unsigned long Request, void *Argp)
|
|
{
|
|
if (this->SymlinkTo)
|
|
return this->SymlinkTo->ioctl(Request, Argp);
|
|
|
|
return this->node->ioctl(Request, Argp);
|
|
}
|
|
|
|
RefNode::RefNode(Node *node)
|
|
{
|
|
this->node = node;
|
|
this->FileSize = node->Size;
|
|
if (this->node->Type == SYMLINK)
|
|
{
|
|
if (!this->node->SymlinkTarget)
|
|
{
|
|
this->node->SymlinkTarget =
|
|
node->vFS->GetNodeFromPath(this->node->Symlink);
|
|
}
|
|
|
|
if (!this->node->SymlinkTarget)
|
|
{
|
|
error("Symlink target %s not found!",
|
|
this->node->Symlink);
|
|
return;
|
|
}
|
|
|
|
/* not standard but useful in kernel-space */
|
|
this->node->Size = this->node->SymlinkTarget->Size;
|
|
this->SymlinkTo = this->node->SymlinkTarget->CreateReference();
|
|
}
|
|
|
|
debug("Created reference node for %s [%#lx]",
|
|
this->node->FullPath, (uintptr_t)this);
|
|
}
|
|
|
|
RefNode::~RefNode()
|
|
{
|
|
if (this->SymlinkTo)
|
|
this->node->SymlinkTarget->RemoveReference(this);
|
|
|
|
this->node->RemoveReference(this);
|
|
|
|
debug("Destroyed reference node for %s [%#lx]",
|
|
this->node->FullPath, (uintptr_t)this);
|
|
}
|
|
}
|