mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 14:38:12 +00:00
Fix up VFS::resolveSymbolicLink() to use a base inode instead of a base path.
Also more VFS error plumbing.
This commit is contained in:
parent
97726862dd
commit
bea106fdb2
4 changed files with 24 additions and 25 deletions
|
@ -234,11 +234,9 @@ Task* Task::createUserTask(const String& path, uid_t uid, gid_t gid, pid_t paren
|
||||||
cwd = parentTask->m_cwd.copyRef();
|
cwd = parentTask->m_cwd.copyRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto handle = VirtualFileSystem::the().open(path, 0, cwd ? cwd->inode : InodeIdentifier());
|
auto handle = VirtualFileSystem::the().open(path, error, 0, cwd ? cwd->inode : InodeIdentifier());
|
||||||
if (!handle) {
|
if (!handle)
|
||||||
error = -ENOENT; // FIXME: Get a more detailed error from VFS.
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
if (!handle->metadata().mayExecute(uid, gid)) {
|
if (!handle->metadata().mayExecute(uid, gid)) {
|
||||||
error = -EACCES;
|
error = -EACCES;
|
||||||
|
@ -786,9 +784,10 @@ int Task::sys$close(int fd)
|
||||||
int Task::sys$lstat(const char* path, Unix::stat* statbuf)
|
int Task::sys$lstat(const char* path, Unix::stat* statbuf)
|
||||||
{
|
{
|
||||||
VALIDATE_USER_BUFFER(statbuf, sizeof(Unix::stat));
|
VALIDATE_USER_BUFFER(statbuf, sizeof(Unix::stat));
|
||||||
auto handle = VirtualFileSystem::the().open(move(path), O_NOFOLLOW_NOERROR, cwdInode());
|
int error;
|
||||||
|
auto handle = VirtualFileSystem::the().open(move(path), error, O_NOFOLLOW_NOERROR, cwdInode());
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -1;
|
return error;
|
||||||
handle->stat(statbuf);
|
handle->stat(statbuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -798,9 +797,10 @@ int Task::sys$readlink(const char* path, char* buffer, size_t size)
|
||||||
VALIDATE_USER_BUFFER(path, strlen(path));
|
VALIDATE_USER_BUFFER(path, strlen(path));
|
||||||
VALIDATE_USER_BUFFER(buffer, size);
|
VALIDATE_USER_BUFFER(buffer, size);
|
||||||
|
|
||||||
auto handle = VirtualFileSystem::the().open(path, O_RDONLY | O_NOFOLLOW_NOERROR, cwdInode());
|
int error;
|
||||||
|
auto handle = VirtualFileSystem::the().open(path, error, O_RDONLY | O_NOFOLLOW_NOERROR, cwdInode());
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -ENOENT; // FIXME: Get a more detailed error from VFS.
|
return error;
|
||||||
|
|
||||||
if (!handle->metadata().isSymbolicLink())
|
if (!handle->metadata().isSymbolicLink())
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -818,9 +818,10 @@ int Task::sys$readlink(const char* path, char* buffer, size_t size)
|
||||||
int Task::sys$chdir(const char* path)
|
int Task::sys$chdir(const char* path)
|
||||||
{
|
{
|
||||||
VALIDATE_USER_BUFFER(path, strlen(path));
|
VALIDATE_USER_BUFFER(path, strlen(path));
|
||||||
auto handle = VirtualFileSystem::the().open(path, 0, cwdInode());
|
int error;
|
||||||
|
auto handle = VirtualFileSystem::the().open(path, error, 0, cwdInode());
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -ENOENT; // FIXME: More detailed error.
|
return error;
|
||||||
if (!handle->isDirectory())
|
if (!handle->isDirectory())
|
||||||
return -ENOTDIR;
|
return -ENOTDIR;
|
||||||
m_cwd = handle->vnode();
|
m_cwd = handle->vnode();
|
||||||
|
@ -842,9 +843,10 @@ int Task::sys$open(const char* path, int options)
|
||||||
VALIDATE_USER_BUFFER(path, strlen(path));
|
VALIDATE_USER_BUFFER(path, strlen(path));
|
||||||
if (m_fileHandles.size() >= m_maxFileHandles)
|
if (m_fileHandles.size() >= m_maxFileHandles)
|
||||||
return -EMFILE;
|
return -EMFILE;
|
||||||
auto handle = VirtualFileSystem::the().open(path, 0, cwdInode());
|
int error;
|
||||||
|
auto handle = VirtualFileSystem::the().open(path, error, 0, cwdInode());
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -ENOENT; // FIXME: Detailed error.
|
return error;
|
||||||
if (options & O_DIRECTORY && !handle->isDirectory())
|
if (options & O_DIRECTORY && !handle->isDirectory())
|
||||||
return -ENOTDIR; // FIXME: This should be handled by VFS::open.
|
return -ENOTDIR; // FIXME: This should be handled by VFS::open.
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,8 @@ static void init_stage2()
|
||||||
|
|
||||||
#ifdef KSYMS
|
#ifdef KSYMS
|
||||||
{
|
{
|
||||||
auto handle = vfs->open("/kernel.map");
|
int error;
|
||||||
|
auto handle = vfs->open("/kernel.map", error);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
kprintf("Failed to open /kernel.map\n");
|
kprintf("Failed to open /kernel.map\n");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -363,11 +363,10 @@ bool VirtualFileSystem::touch(const String& path)
|
||||||
return inode.fileSystem()->setModificationTime(inode, ktime(nullptr));
|
return inode.fileSystem()->setModificationTime(inode, ktime(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnPtr<FileHandle> VirtualFileSystem::open(const String& path, int options, InodeIdentifier base)
|
OwnPtr<FileHandle> VirtualFileSystem::open(const String& path, int& error, int options, InodeIdentifier base)
|
||||||
{
|
{
|
||||||
Locker locker(VirtualFileSystem::lock());
|
Locker locker(VirtualFileSystem::lock());
|
||||||
|
|
||||||
int error;
|
|
||||||
auto inode = resolvePath(path, error, base, options);
|
auto inode = resolvePath(path, error, base, options);
|
||||||
if (!inode.isValid())
|
if (!inode.isValid())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -397,15 +396,12 @@ OwnPtr<FileHandle> VirtualFileSystem::mkdir(const String& path, InodeIdentifier
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
InodeIdentifier VirtualFileSystem::resolveSymbolicLink(const String& basePath, InodeIdentifier symlinkInode)
|
InodeIdentifier VirtualFileSystem::resolveSymbolicLink(InodeIdentifier base, InodeIdentifier symlinkInode, int& error)
|
||||||
{
|
{
|
||||||
auto symlinkContents = symlinkInode.readEntireFile();
|
auto symlinkContents = symlinkInode.readEntireFile();
|
||||||
if (!symlinkContents)
|
if (!symlinkContents)
|
||||||
return { };
|
return { };
|
||||||
char buf[4096];
|
return resolvePath((const char*)symlinkContents.pointer(), error, base);
|
||||||
ksprintf(buf, "/%s/%s", basePath.characters(), String((const char*)symlinkContents.pointer(), symlinkContents.size()).characters());
|
|
||||||
int error;
|
|
||||||
return resolvePath(buf, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String VirtualFileSystem::absolutePath(InodeIdentifier inode)
|
String VirtualFileSystem::absolutePath(InodeIdentifier inode)
|
||||||
|
@ -474,12 +470,13 @@ InodeIdentifier VirtualFileSystem::resolvePath(const String& path, int& error, I
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
return { };
|
return { };
|
||||||
}
|
}
|
||||||
|
auto parent = inode;
|
||||||
inode = inode.fileSystem()->childOfDirectoryInodeWithName(inode, part);
|
inode = inode.fileSystem()->childOfDirectoryInodeWithName(inode, part);
|
||||||
if (!inode.isValid()) {
|
if (!inode.isValid()) {
|
||||||
#ifdef VFS_DEBUG
|
#ifdef VFS_DEBUG
|
||||||
kprintf("bad child\n");
|
kprintf("bad child\n");
|
||||||
#endif
|
#endif
|
||||||
error = -EIO;
|
error = -ENOENT;
|
||||||
return { };
|
return { };
|
||||||
}
|
}
|
||||||
#ifdef VFS_DEBUG
|
#ifdef VFS_DEBUG
|
||||||
|
@ -514,10 +511,9 @@ InodeIdentifier VirtualFileSystem::resolvePath(const String& path, int& error, I
|
||||||
for (unsigned j = 0; j < i; ++j) {
|
for (unsigned j = 0; j < i; ++j) {
|
||||||
p += ksprintf(p, "/%s", parts[j].characters());
|
p += ksprintf(p, "/%s", parts[j].characters());
|
||||||
}
|
}
|
||||||
inode = resolveSymbolicLink(buf, inode);
|
inode = resolveSymbolicLink(parent, inode, error);
|
||||||
if (!inode.isValid()) {
|
if (!inode.isValid()) {
|
||||||
kprintf("Symbolic link resolution failed :(\n");
|
kprintf("Symbolic link resolution failed :(\n");
|
||||||
error = -ENOENT;
|
|
||||||
return { };
|
return { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
bool mountRoot(RetainPtr<FileSystem>&&);
|
bool mountRoot(RetainPtr<FileSystem>&&);
|
||||||
bool mount(RetainPtr<FileSystem>&&, const String& path);
|
bool mount(RetainPtr<FileSystem>&&, const String& path);
|
||||||
|
|
||||||
OwnPtr<FileHandle> open(const String& path, int options = 0, InodeIdentifier base = InodeIdentifier());
|
OwnPtr<FileHandle> open(const String& path, int& error, int options = 0, InodeIdentifier base = InodeIdentifier());
|
||||||
OwnPtr<FileHandle> create(const String& path, InodeIdentifier base = InodeIdentifier());
|
OwnPtr<FileHandle> create(const String& path, InodeIdentifier base = InodeIdentifier());
|
||||||
OwnPtr<FileHandle> mkdir(const String& path, InodeIdentifier base = InodeIdentifier());
|
OwnPtr<FileHandle> mkdir(const String& path, InodeIdentifier base = InodeIdentifier());
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ private:
|
||||||
|
|
||||||
void enumerateDirectoryInode(InodeIdentifier, Function<bool(const FileSystem::DirectoryEntry&)>);
|
void enumerateDirectoryInode(InodeIdentifier, Function<bool(const FileSystem::DirectoryEntry&)>);
|
||||||
InodeIdentifier resolvePath(const String& path, int& error, InodeIdentifier base = InodeIdentifier(), int options = 0);
|
InodeIdentifier resolvePath(const String& path, int& error, InodeIdentifier base = InodeIdentifier(), int options = 0);
|
||||||
InodeIdentifier resolveSymbolicLink(const String& basePath, InodeIdentifier symlinkInode);
|
InodeIdentifier resolveSymbolicLink(InodeIdentifier base, InodeIdentifier symlinkInode, int& error);
|
||||||
|
|
||||||
RetainPtr<Node> allocateNode();
|
RetainPtr<Node> allocateNode();
|
||||||
void freeNode(Node*);
|
void freeNode(Node*);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue