Kernel: Improve open() POSIX compatability
Also rename Process::sys_creat -> create_file since it is not actually a syscall and only used by open as a healper.
This commit is contained in:
parent
720bc418a6
commit
202c38a65a
|
@ -89,12 +89,12 @@ namespace Kernel
|
|||
BAN::ErrorOr<long> sys_getegid() const { return m_credentials.egid(); }
|
||||
BAN::ErrorOr<long> sys_getpgid(pid_t);
|
||||
|
||||
BAN::ErrorOr<void> create_file(BAN::StringView name, mode_t mode);
|
||||
BAN::ErrorOr<long> sys_open(BAN::StringView, int, mode_t = 0);
|
||||
BAN::ErrorOr<long> sys_openat(int, BAN::StringView, int, mode_t = 0);
|
||||
BAN::ErrorOr<long> sys_close(int fd);
|
||||
BAN::ErrorOr<long> sys_read(int fd, void* buffer, size_t count);
|
||||
BAN::ErrorOr<long> sys_write(int fd, const void* buffer, size_t count);
|
||||
BAN::ErrorOr<long> sys_creat(BAN::StringView name, mode_t);
|
||||
|
||||
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
|
||||
BAN::ErrorOr<long> sys_dup(int fildes);
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<int> OpenFileDescriptorSet::open(BAN::StringView absolute_path, int flags)
|
||||
{
|
||||
if (flags & ~(O_RDONLY | O_WRONLY | O_NOFOLLOW | O_SEARCH | O_APPEND | O_TRUNC | O_CLOEXEC | O_TTY_INIT))
|
||||
if (flags & ~(O_RDONLY | O_WRONLY | O_NOFOLLOW | O_SEARCH | O_APPEND | O_TRUNC | O_CLOEXEC | O_TTY_INIT | O_DIRECTORY))
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
|
||||
int access_mask = O_EXEC | O_RDONLY | O_WRONLY | O_SEARCH;
|
||||
|
@ -64,7 +64,10 @@ namespace Kernel
|
|||
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags));
|
||||
|
||||
if (flags & O_TRUNC)
|
||||
if ((flags & O_DIRECTORY) && !file.inode->mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
|
||||
if ((flags & O_TRUNC) && (flags & O_WRONLY) && file.inode->mode().ifreg())
|
||||
TRY(file.inode->truncate(0));
|
||||
|
||||
int fd = TRY(get_free_fd());
|
||||
|
|
|
@ -598,6 +598,26 @@ namespace Kernel
|
|||
m_has_called_exec = true;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Process::create_file(BAN::StringView path, mode_t mode)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
auto absolute_path = TRY(absolute_path_of(path));
|
||||
|
||||
size_t index;
|
||||
for (index = absolute_path.size(); index > 0; index--)
|
||||
if (absolute_path[index - 1] == '/')
|
||||
break;
|
||||
|
||||
auto directory = absolute_path.sv().substring(0, index);
|
||||
auto file_name = absolute_path.sv().substring(index);
|
||||
|
||||
auto parent_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, directory, O_WRONLY)).inode;
|
||||
TRY(parent_inode->create_file(file_name, S_IFREG | (mode & 0777), m_credentials.euid(), m_credentials.egid()));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_open(BAN::StringView path, int flags, mode_t mode)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
@ -605,11 +625,13 @@ namespace Kernel
|
|||
|
||||
if (flags & O_CREAT)
|
||||
{
|
||||
if (flags & O_DIRECTORY)
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
auto file_or_error = VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_WRONLY);
|
||||
if (file_or_error.is_error())
|
||||
{
|
||||
if (file_or_error.error().get_error_code() == ENOENT)
|
||||
TRY(sys_creat(path, mode));
|
||||
TRY(create_file(path, mode));
|
||||
else
|
||||
return file_or_error.release_error();
|
||||
}
|
||||
|
@ -697,29 +719,6 @@ namespace Kernel
|
|||
return TRY(m_open_file_descriptors.tell(fd));
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_creat(BAN::StringView path, mode_t mode)
|
||||
{
|
||||
if ((mode & 0777) != mode)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
LockGuard _(m_lock);
|
||||
|
||||
auto absolute_path = TRY(absolute_path_of(path));
|
||||
|
||||
size_t index;
|
||||
for (index = absolute_path.size(); index > 0; index--)
|
||||
if (absolute_path[index - 1] == '/')
|
||||
break;
|
||||
|
||||
auto directory = absolute_path.sv().substring(0, index);
|
||||
auto file_name = absolute_path.sv().substring(index);
|
||||
|
||||
auto parent_file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, directory, O_WRONLY));
|
||||
TRY(parent_file.inode->create_file(file_name, S_IFREG | mode, m_credentials.euid(), m_credentials.egid()));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Process::mount(BAN::StringView source, BAN::StringView target)
|
||||
{
|
||||
BAN::String absolute_source, absolute_target;
|
||||
|
|
Loading…
Reference in New Issue