kernel+libos+apps: Support block devices and disallow seeking character devices or pipes
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
38fae0c97b
commit
62e14e7580
@ -1,5 +1,6 @@
|
|||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
#include <os/FileSystem.h>
|
#include <os/FileSystem.h>
|
||||||
|
#include <os/Mode.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ static const char* file_type(mode_t mode)
|
|||||||
case S_IFREG: return "regular file";
|
case S_IFREG: return "regular file";
|
||||||
case S_IFDIR: return "directory";
|
case S_IFDIR: return "directory";
|
||||||
case S_IFCHR: return "character special device";
|
case S_IFCHR: return "character special device";
|
||||||
|
case S_IFBLK: return "block special device";
|
||||||
case S_IFLNK: return "symbolic link";
|
case S_IFLNK: return "symbolic link";
|
||||||
case S_IFIFO: return "pipe";
|
case S_IFIFO: return "pipe";
|
||||||
default: return "unknown file type";
|
default: return "unknown file type";
|
||||||
@ -31,10 +33,13 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
TRY(os::FileSystem::stat(path, st, follow_symlinks));
|
TRY(os::FileSystem::stat(path, st, follow_symlinks));
|
||||||
|
|
||||||
|
char buf[11];
|
||||||
|
os::format_mode(st.st_mode, buf);
|
||||||
|
|
||||||
printf(" File: %s\n", path.chars());
|
printf(" File: %s\n", path.chars());
|
||||||
printf(" Size: %zu (%s)\n", st.st_size, file_type(st.st_mode));
|
printf(" Size: %zu (%s)\n", st.st_size, file_type(st.st_mode));
|
||||||
printf("Inode: %lu Links: %lu\n", st.st_ino, st.st_nlink);
|
printf("Inode: %lu Links: %lu\n", st.st_ino, st.st_nlink);
|
||||||
printf(" Mode: %#o UID: %u GID: %u\n", st.st_mode & ~S_IFMT, st.st_uid, st.st_gid);
|
printf(" Mode: (%#o/%s) UID: %u GID: %u\n", st.st_mode & ~S_IFMT, buf, st.st_uid, st.st_gid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -168,6 +168,11 @@ namespace VFS
|
|||||||
return inode->mode() & S_ISGID;
|
return inode->mode() & S_ISGID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_seekable(SharedPtr<Inode> inode)
|
||||||
|
{
|
||||||
|
return inode->type() != InodeType::FIFO && inode->type() != InodeType::CharacterDevice;
|
||||||
|
}
|
||||||
|
|
||||||
Result<void> mount_root(SharedPtr<VFS::FileSystem> fs)
|
Result<void> mount_root(SharedPtr<VFS::FileSystem> fs)
|
||||||
{
|
{
|
||||||
root_fs = fs;
|
root_fs = fs;
|
||||||
|
@ -13,7 +13,8 @@ namespace VFS
|
|||||||
{
|
{
|
||||||
RegularFile,
|
RegularFile,
|
||||||
Directory,
|
Directory,
|
||||||
Device,
|
CharacterDevice,
|
||||||
|
BlockDevice,
|
||||||
Symlink,
|
Symlink,
|
||||||
FIFO,
|
FIFO,
|
||||||
};
|
};
|
||||||
@ -261,7 +262,7 @@ namespace VFS
|
|||||||
|
|
||||||
InodeType type() const override
|
InodeType type() const override
|
||||||
{
|
{
|
||||||
return InodeType::Device;
|
return InodeType::CharacterDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DeviceInode() = default;
|
virtual ~DeviceInode() = default;
|
||||||
@ -285,6 +286,8 @@ namespace VFS
|
|||||||
bool is_setuid(SharedPtr<Inode> inode);
|
bool is_setuid(SharedPtr<Inode> inode);
|
||||||
bool is_setgid(SharedPtr<Inode> inode);
|
bool is_setgid(SharedPtr<Inode> inode);
|
||||||
|
|
||||||
|
bool is_seekable(VFS::InodeType type);
|
||||||
|
|
||||||
Inode& root_inode();
|
Inode& root_inode();
|
||||||
|
|
||||||
Result<void> mount_root(SharedPtr<VFS::FileSystem> fs);
|
Result<void> mount_root(SharedPtr<VFS::FileSystem> fs);
|
||||||
|
@ -18,6 +18,11 @@ class Device
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool is_block_device() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool blocking() const = 0;
|
virtual bool blocking() const = 0;
|
||||||
|
|
||||||
virtual ~Device() = default;
|
virtual ~Device() = default;
|
||||||
|
@ -243,6 +243,11 @@ namespace TmpFS
|
|||||||
public:
|
public:
|
||||||
DeviceInode() = default;
|
DeviceInode() = default;
|
||||||
|
|
||||||
|
VFS::InodeType type() const override
|
||||||
|
{
|
||||||
|
return m_device->is_block_device() ? VFS::InodeType::BlockDevice : VFS::InodeType::CharacterDevice;
|
||||||
|
}
|
||||||
|
|
||||||
void set_fs(FileSystem& fs, Badge<FileSystem>)
|
void set_fs(FileSystem& fs, Badge<FileSystem>)
|
||||||
{
|
{
|
||||||
m_fs = &fs;
|
m_fs = &fs;
|
||||||
|
@ -33,7 +33,7 @@ Result<u64> sys_read(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
usize nread = TRY(descriptor.inode->read(buf, descriptor.offset, size));
|
usize nread = TRY(descriptor.inode->read(buf, descriptor.offset, size));
|
||||||
|
|
||||||
descriptor.offset += nread;
|
if (VFS::is_seekable(descriptor.inode->type())) descriptor.offset += nread;
|
||||||
|
|
||||||
return nread;
|
return nread;
|
||||||
}
|
}
|
||||||
@ -52,11 +52,12 @@ Result<u64> sys_write(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
if (!descriptor.is_writable()) return err(EBADF);
|
if (!descriptor.is_writable()) return err(EBADF);
|
||||||
|
|
||||||
if (descriptor.should_append()) descriptor.offset = descriptor.inode->size();
|
if (descriptor.should_append() && VFS::is_seekable(descriptor.inode->type()))
|
||||||
|
descriptor.offset = descriptor.inode->size();
|
||||||
|
|
||||||
usize nwritten = TRY(descriptor.inode->write(buf, descriptor.offset, size));
|
usize nwritten = TRY(descriptor.inode->write(buf, descriptor.offset, size));
|
||||||
|
|
||||||
descriptor.offset += nwritten;
|
if (VFS::is_seekable(descriptor.inode->type())) descriptor.offset += nwritten;
|
||||||
|
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
@ -71,6 +72,10 @@ Result<u64> sys_lseek(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
auto& descriptor = *TRY(current->resolve_fd(fd));
|
auto& descriptor = *TRY(current->resolve_fd(fd));
|
||||||
|
|
||||||
|
if (descriptor.inode->type() == VFS::InodeType::FIFO) return err(ESPIPE);
|
||||||
|
|
||||||
|
if (!VFS::is_seekable(descriptor.inode->type())) return descriptor.offset;
|
||||||
|
|
||||||
off_t new_offset;
|
off_t new_offset;
|
||||||
|
|
||||||
switch (whence)
|
switch (whence)
|
||||||
|
@ -13,7 +13,8 @@ static mode_t make_mode(mode_t mode, VFS::InodeType type)
|
|||||||
{
|
{
|
||||||
case VFS::InodeType::RegularFile: result |= S_IFREG; break;
|
case VFS::InodeType::RegularFile: result |= S_IFREG; break;
|
||||||
case VFS::InodeType::Directory: result |= S_IFDIR; break;
|
case VFS::InodeType::Directory: result |= S_IFDIR; break;
|
||||||
case VFS::InodeType::Device: result |= S_IFCHR; break;
|
case VFS::InodeType::CharacterDevice: result |= S_IFCHR; break;
|
||||||
|
case VFS::InodeType::BlockDevice: result |= S_IFBLK; break;
|
||||||
case VFS::InodeType::Symlink: result |= S_IFLNK; break;
|
case VFS::InodeType::Symlink: result |= S_IFLNK; break;
|
||||||
case VFS::InodeType::FIFO: result |= S_IFIFO; break;
|
case VFS::InodeType::FIFO: result |= S_IFIFO; break;
|
||||||
default: break;
|
default: break;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define S_IFREG 000000
|
#define S_IFREG 000000
|
||||||
#define S_IFLNK 010000
|
#define S_IFLNK 010000
|
||||||
#define S_IFIFO 020000
|
#define S_IFIFO 020000
|
||||||
|
#define S_IFBLK 030000
|
||||||
#define S_IFDIR 040000
|
#define S_IFDIR 040000
|
||||||
#define S_IFCHR 050000
|
#define S_IFCHR 050000
|
||||||
|
|
||||||
@ -15,6 +16,7 @@
|
|||||||
#define S_ISREG(mode) __CHECK_TYPE(mode, S_IFREG)
|
#define S_ISREG(mode) __CHECK_TYPE(mode, S_IFREG)
|
||||||
#define S_ISDIR(mode) __CHECK_TYPE(mode, S_IFDIR)
|
#define S_ISDIR(mode) __CHECK_TYPE(mode, S_IFDIR)
|
||||||
#define S_ISCHR(mode) __CHECK_TYPE(mode, S_IFCHR)
|
#define S_ISCHR(mode) __CHECK_TYPE(mode, S_IFCHR)
|
||||||
|
#define S_ISBLK(mode) __CHECK_TYPE(mode, S_IFBLK)
|
||||||
#define S_ISLNK(mode) __CHECK_TYPE(mode, S_IFLNK)
|
#define S_ISLNK(mode) __CHECK_TYPE(mode, S_IFLNK)
|
||||||
#define S_ISFIFO(mode) __CHECK_TYPE(mode, S_IFIFO)
|
#define S_ISFIFO(mode) __CHECK_TYPE(mode, S_IFIFO)
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ namespace os
|
|||||||
if (S_ISDIR(mode)) return 'd';
|
if (S_ISDIR(mode)) return 'd';
|
||||||
|
|
||||||
if (S_ISCHR(mode)) return 'c';
|
if (S_ISCHR(mode)) return 'c';
|
||||||
|
if (S_ISBLK(mode)) return 'b';
|
||||||
if (S_ISLNK(mode)) return 'l';
|
if (S_ISLNK(mode)) return 'l';
|
||||||
if (S_ISFIFO(mode)) return 'p';
|
if (S_ISFIFO(mode)) return 'p';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user