summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-06 22:14:31 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-06 22:14:31 +0100
commit028afabf6b22664c728f07234bc1dda0f8cb0fbe (patch)
treef394afd30390209fcd48c28422e972def7065212 /Kernel
parent3079ef01ce4da0f70b7c53551c8f1ea0699576d7 (diff)
downloadserenity-028afabf6b22664c728f07234bc1dda0f8cb0fbe.zip
Kernel: Port more code to KResult and KResultOr<T>.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Device.cpp4
-rw-r--r--Kernel/Device.h2
-rw-r--r--Kernel/FileDescriptor.h2
-rw-r--r--Kernel/KResult.h13
-rw-r--r--Kernel/KSyms.cpp16
-rw-r--r--Kernel/LocalSocket.cpp76
-rw-r--r--Kernel/LocalSocket.h4
-rw-r--r--Kernel/PTYMultiplexer.cpp10
-rw-r--r--Kernel/PTYMultiplexer.h2
-rw-r--r--Kernel/Process.cpp78
-rw-r--r--Kernel/Process.h4
-rw-r--r--Kernel/Socket.cpp25
-rw-r--r--Kernel/Socket.h11
-rw-r--r--Kernel/VirtualFileSystem.cpp100
-rw-r--r--Kernel/VirtualFileSystem.h6
15 files changed, 155 insertions, 198 deletions
diff --git a/Kernel/Device.cpp b/Kernel/Device.cpp
index 226cbcc2c5..e04f196e5b 100644
--- a/Kernel/Device.cpp
+++ b/Kernel/Device.cpp
@@ -13,9 +13,9 @@ Device::~Device()
VFS::the().unregister_device(*this);
}
-RetainPtr<FileDescriptor> Device::open(int& error, int options)
+KResultOr<Retained<FileDescriptor>> Device::open(int options)
{
- return VFS::the().open(*this, error, options);
+ return VFS::the().open(*this, options);
}
void Device::close()
diff --git a/Kernel/Device.h b/Kernel/Device.h
index 19bf9d8ed4..27e31bad8d 100644
--- a/Kernel/Device.h
+++ b/Kernel/Device.h
@@ -13,7 +13,7 @@ public:
InodeMetadata metadata() const { return { }; }
- virtual RetainPtr<FileDescriptor> open(int& error, int options);
+ virtual KResultOr<Retained<FileDescriptor>> open(int options);
virtual void close();
virtual bool can_read(Process&) const = 0;
diff --git a/Kernel/FileDescriptor.h b/Kernel/FileDescriptor.h
index 2e59867a9d..55b08d9af3 100644
--- a/Kernel/FileDescriptor.h
+++ b/Kernel/FileDescriptor.h
@@ -86,7 +86,7 @@ public:
ByteBuffer& generator_cache() { return m_generator_cache; }
- void set_original_inode(Badge<VFS>, RetainPtr<Inode>&& inode) { m_inode = move(inode); }
+ void set_original_inode(Badge<VFS>, Retained<Inode>&& inode) { m_inode = move(inode); }
void set_socket_role(SocketRole);
diff --git a/Kernel/KResult.h b/Kernel/KResult.h
index a954633973..309d9340f4 100644
--- a/Kernel/KResult.h
+++ b/Kernel/KResult.h
@@ -34,6 +34,19 @@ public:
new (&m_storage) T(move(value));
}
+ template<typename U>
+ KResultOr(U&& value)
+ {
+ new (&m_storage) T(move(value));
+ }
+
+ KResultOr(KResultOr&& other)
+ {
+ new (&m_storage) T(move(other.value()));
+ other.m_is_error = true;
+ other.m_error = KSuccess;
+ }
+
~KResultOr()
{
if (!m_is_error)
diff --git a/Kernel/KSyms.cpp b/Kernel/KSyms.cpp
index 56321eb62e..a9adf83a0b 100644
--- a/Kernel/KSyms.cpp
+++ b/Kernel/KSyms.cpp
@@ -126,14 +126,10 @@ void init_ksyms()
void load_ksyms()
{
- int error;
- auto descriptor = VFS::the().open("/kernel.map", error, 0, 0, *VFS::the().root_inode());
- if (!descriptor) {
- kprintf("Failed to open /kernel.map\n");
- } else {
- auto buffer = descriptor->read_entire_file(*current);
- ASSERT(buffer);
- load_ksyms_from_data(buffer);
- }
+ auto result = VFS::the().open("/kernel.map", 0, 0, *VFS::the().root_inode());
+ ASSERT(!result.is_error());
+ auto descriptor = result.value();
+ auto buffer = descriptor->read_entire_file(*current);
+ ASSERT(buffer);
+ load_ksyms_from_data(buffer);
}
-
diff --git a/Kernel/LocalSocket.cpp b/Kernel/LocalSocket.cpp
index 95f98bf5b0..c1a77f1f92 100644
--- a/Kernel/LocalSocket.cpp
+++ b/Kernel/LocalSocket.cpp
@@ -33,17 +33,13 @@ bool LocalSocket::get_address(sockaddr* address, socklen_t* address_size)
return true;
}
-bool LocalSocket::bind(const sockaddr* address, socklen_t address_size, int& error)
+KResult LocalSocket::bind(const sockaddr* address, socklen_t address_size)
{
ASSERT(!is_connected());
- if (address_size != sizeof(sockaddr_un)) {
- error = -EINVAL;
- return false;
- }
- if (address->sa_family != AF_LOCAL) {
- error = -EINVAL;
- return false;
- }
+ if (address_size != sizeof(sockaddr_un))
+ return KResult(-EINVAL);
+ if (address->sa_family != AF_LOCAL)
+ return KResult(-EINVAL);
const sockaddr_un& local_address = *reinterpret_cast<const sockaddr_un*>(address);
char safe_address[sizeof(local_address.sun_path) + 1];
@@ -53,32 +49,29 @@ bool LocalSocket::bind(const sockaddr* address, socklen_t address_size, int& err
kprintf("%s(%u) LocalSocket{%p} bind(%s)\n", current->name().characters(), current->pid(), this, safe_address);
#endif
- m_file = VFS::the().open(safe_address, error, O_CREAT | O_EXCL, S_IFSOCK | 0666, current->cwd_inode());
- if (!m_file) {
- if (error == -EEXIST)
- error = -EADDRINUSE;
- return false;
+ auto result = VFS::the().open(safe_address, O_CREAT | O_EXCL, S_IFSOCK | 0666, current->cwd_inode());
+ if (result.is_error()) {
+ if (result.error() == -EEXIST)
+ return KResult(-EADDRINUSE);
+ return result.error();
}
+ m_file = move(result.value());
ASSERT(m_file->inode());
m_file->inode()->bind_socket(*this);
m_address = local_address;
m_bound = true;
- return true;
+ return KSuccess;
}
-bool LocalSocket::connect(const sockaddr* address, socklen_t address_size, int& error)
+KResult LocalSocket::connect(const sockaddr* address, socklen_t address_size)
{
ASSERT(!m_bound);
- if (address_size != sizeof(sockaddr_un)) {
- error = -EINVAL;
- return false;
- }
- if (address->sa_family != AF_LOCAL) {
- error = -EINVAL;
- return false;
- }
+ if (address_size != sizeof(sockaddr_un))
+ return KResult(-EINVAL);
+ if (address->sa_family != AF_LOCAL)
+ return KResult(-EINVAL);
const sockaddr_un& local_address = *reinterpret_cast<const sockaddr_un*>(address);
char safe_address[sizeof(local_address.sun_path) + 1];
@@ -88,36 +81,23 @@ bool LocalSocket::connect(const sockaddr* address, socklen_t address_size, int&
kprintf("%s(%u) LocalSocket{%p} connect(%s)\n", current->name().characters(), current->pid(), this, safe_address);
#endif
- m_file = VFS::the().open(safe_address, error, 0, 0, current->cwd_inode());
- if (!m_file) {
- error = -ECONNREFUSED;
- return false;
- }
+ auto descriptor_or_error = VFS::the().open(safe_address, 0, 0, current->cwd_inode());
+ if (descriptor_or_error.is_error())
+ return KResult(-ECONNREFUSED);
+ m_file = move(descriptor_or_error.value());
+
ASSERT(m_file->inode());
- if (!m_file->inode()->socket()) {
- error = -ECONNREFUSED;
- return false;
- }
+ if (!m_file->inode()->socket())
+ return KResult(-ECONNREFUSED);
m_address = local_address;
auto peer = m_file->inode()->socket();
-#ifdef DEBUG_LOCAL_SOCKET
- kprintf("Queueing up connection\n");
-#endif
- if (!peer->queue_connection_from(*this, error))
- return false;
-
-#ifdef DEBUG_LOCAL_SOCKET
- kprintf("Waiting for connect...\n");
-#endif
- if (!current->wait_for_connect(*this, error))
- return false;
+ auto result = peer->queue_connection_from(*this);
+ if (result.is_error())
+ return result;
-#ifdef DEBUG_LOCAL_SOCKET
- kprintf("CONNECTED!\n");
-#endif
- return true;
+ return current->wait_for_connect(*this);
}
void LocalSocket::attach_fd(SocketRole role)
diff --git a/Kernel/LocalSocket.h b/Kernel/LocalSocket.h
index 435c15a99c..e0c49d7b79 100644
--- a/Kernel/LocalSocket.h
+++ b/Kernel/LocalSocket.h
@@ -10,8 +10,8 @@ public:
static Retained<LocalSocket> create(int type);
virtual ~LocalSocket() override;
- virtual bool bind(const sockaddr*, socklen_t, int& error) override;
- virtual bool connect(const sockaddr*, socklen_t, int& error) override;
+ virtual KResult bind(const sockaddr*, socklen_t) override;
+ virtual KResult connect(const sockaddr*, socklen_t) override;
virtual bool get_address(sockaddr*, socklen_t*) override;
virtual void attach_fd(SocketRole) override;
virtual void detach_fd(SocketRole) override;
diff --git a/Kernel/PTYMultiplexer.cpp b/Kernel/PTYMultiplexer.cpp
index ef3583a45f..3fcaa7b130 100644
--- a/Kernel/PTYMultiplexer.cpp
+++ b/Kernel/PTYMultiplexer.cpp
@@ -26,17 +26,15 @@ PTYMultiplexer::~PTYMultiplexer()
{
}
-RetainPtr<FileDescriptor> PTYMultiplexer::open(int& error, int options)
+KResultOr<Retained<FileDescriptor>> PTYMultiplexer::open(int options)
{
LOCKER(m_lock);
- if (m_freelist.is_empty()) {
- error = -EBUSY;
- return nullptr;
- }
+ if (m_freelist.is_empty())
+ return KResult(-EBUSY);
auto master_index = m_freelist.take_last();
auto master = adopt(*new MasterPTY(master_index));
dbgprintf("PTYMultiplexer::open: Vending master %u\n", master->index());
- return VFS::the().open(move(master), error, options);
+ return VFS::the().open(move(master), options);
}
void PTYMultiplexer::notify_master_destroyed(Badge<MasterPTY>, unsigned index)
diff --git a/Kernel/PTYMultiplexer.h b/Kernel/PTYMultiplexer.h
index 5e34d65324..d5d875235d 100644
--- a/Kernel/PTYMultiplexer.h
+++ b/Kernel/PTYMultiplexer.h
@@ -15,7 +15,7 @@ public:
static PTYMultiplexer& the();
// ^CharacterDevice
- virtual RetainPtr<FileDescriptor> open(int& error, int options) override;
+ virtual KResultOr<Retained<FileDescriptor>> open(int options) override;
virtual ssize_t read(Process&, byte*, ssize_t) override { return 0; }
virtual ssize_t write(Process&, const byte*, ssize_t) override { return 0; }
virtual bool can_read(Process&) const override { return true; }
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index 5d1cd3ceb5..977ef02049 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -293,12 +293,10 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
if (parts.is_empty())
return -ENOENT;
- int error;
- auto descriptor = VFS::the().open(path, error, 0, 0, cwd_inode());
- if (!descriptor) {
- ASSERT(error != 0);
- return error;
- }
+ auto result = VFS::the().open(path, 0, 0, cwd_inode());
+ if (result.is_error())
+ return result.error();
+ auto descriptor = result.value();
if (!descriptor->metadata().may_execute(m_euid, m_gids))
return -EACCES;
@@ -644,10 +642,9 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring
} else {
m_fds.resize(m_max_open_file_descriptors);
auto& device_to_use_as_tty = tty ? (CharacterDevice&)*tty : NullDevice::the();
- int error;
- m_fds[0].set(device_to_use_as_tty.open(error, O_RDONLY));
- m_fds[1].set(device_to_use_as_tty.open(error, O_WRONLY));
- m_fds[2].set(device_to_use_as_tty.open(error, O_WRONLY));
+ m_fds[0].set(*device_to_use_as_tty.open(O_RDONLY).value());
+ m_fds[1].set(*device_to_use_as_tty.open(O_WRONLY).value());
+ m_fds[2].set(*device_to_use_as_tty.open(O_WRONLY).value());
}
if (fork_parent)
@@ -1306,7 +1303,7 @@ int Process::sys$fcntl(int fd, int cmd, dword arg)
}
if (new_fd == -1)
return -EMFILE;
- m_fds[new_fd].set(descriptor);
+ m_fds[new_fd].set(*descriptor);
break;
}
case F_GETFD:
@@ -1359,10 +1356,10 @@ int Process::sys$readlink(const char* path, char* buffer, ssize_t size)
if (!validate_write(buffer, size))
return -EFAULT;
- int error;
- auto descriptor = VFS::the().open(path, error, O_RDONLY | O_NOFOLLOW_NOERROR, 0, cwd_inode());
- if (!descriptor)
- return error;
+ auto result = VFS::the().open(path, O_RDONLY | O_NOFOLLOW_NOERROR, 0, cwd_inode());
+ if (result.is_error())
+ return result.error();
+ auto descriptor = result.value();
if (!descriptor->metadata().is_symlink())
return -EINVAL;
@@ -1422,10 +1419,11 @@ int Process::sys$open(const char* path, int options, mode_t mode)
return -EFAULT;
if (number_of_open_file_descriptors() >= m_max_open_file_descriptors)
return -EMFILE;
- int error = -EWHYTHO;
- auto descriptor = VFS::the().open(path, error, options, mode & ~umask(), cwd_inode());
- if (!descriptor)
- return error;
+
+ auto result = VFS::the().open(path, options, mode & ~umask(), cwd_inode());
+ if (result.is_error())
+ return result.error();
+ auto descriptor = result.value();
if (options & O_DIRECTORY && !descriptor->is_directory())
return -ENOTDIR; // FIXME: This should be handled by VFS::open.
if (options & O_NONBLOCK)
@@ -1952,7 +1950,7 @@ int Process::sys$dup(int old_fd)
if (!m_fds[new_fd])
break;
}
- m_fds[new_fd].set(descriptor);
+ m_fds[new_fd].set(*descriptor);
return new_fd;
}
@@ -1963,7 +1961,7 @@ int Process::sys$dup2(int old_fd, int new_fd)
return -EBADF;
if (number_of_open_file_descriptors() == m_max_open_file_descriptors)
return -EMFILE;
- m_fds[new_fd].set(descriptor);
+ m_fds[new_fd].set(*descriptor);
return new_fd;
}
@@ -2400,11 +2398,10 @@ int Process::sys$socket(int domain, int type, int protocol)
if (!m_fds[fd])
break;
}
- int error;
- auto socket = Socket::create(domain, type, protocol, error);
- if (!socket)
- return error;
- auto descriptor = FileDescriptor::create(move(socket));
+ auto result = Socket::create(domain, type, protocol);
+ if (result.is_error())
+ return result.error();
+ auto descriptor = FileDescriptor::create(*result.value());
unsigned flags = 0;
if (type & SOCK_CLOEXEC)
flags |= FD_CLOEXEC;
@@ -2424,10 +2421,7 @@ int Process::sys$bind(int sockfd, const sockaddr* address, socklen_t address_len
if (!descriptor->is_socket())
return -ENOTSOCK;
auto& socket = *descriptor->socket();
- int error;
- if (!socket.bind(address, address_length, error))
- return error;
- return 0;
+ return socket.bind(address, address_length);
}
int Process::sys$listen(int sockfd, int backlog)
@@ -2438,9 +2432,9 @@ int Process::sys$listen(int sockfd, int backlog)
if (!descriptor->is_socket())
return -ENOTSOCK;
auto& socket = *descriptor->socket();
- int error;
- if (!socket.listen(backlog, error))
- return error;
+ auto result = socket.listen(backlog);
+ if (result.is_error())
+ return result;
descriptor->set_socket_role(SocketRole::Listener);
return 0;
}
@@ -2497,26 +2491,24 @@ int Process::sys$connect(int sockfd, const sockaddr* address, socklen_t address_
if (!descriptor->is_socket())
return -ENOTSOCK;
auto& socket = *descriptor->socket();
- int error;
- if (!socket.connect(address, address_size, error))
- return error;
+ auto result = socket.connect(address, address_size);
+ if (result.is_error())
+ return result;
descriptor->set_socket_role(SocketRole::Connected);
return 0;
}
-bool Process::wait_for_connect(Socket& socket, int& error)
+KResult Process::wait_for_connect(Socket& socket)
{
if (socket.is_connected())
- return true;
+ return KSuccess;
m_blocked_connecting_socket = socket;
block(BlockedConnect);
Scheduler::yield();
m_blocked_connecting_socket = nullptr;
- if (!socket.is_connected()) {
- error = -ECONNREFUSED;
- return false;
- }
- return true;
+ if (!socket.is_connected())
+ return KResult(-ECONNREFUSED);
+ return KSuccess;
}
struct SharedBuffer {
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 36e6f0bd19..62bfb9b960 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -236,7 +236,7 @@ public:
void* sys$get_shared_buffer(int shared_buffer_id);
int sys$release_shared_buffer(int shared_buffer_id);
- bool wait_for_connect(Socket&, int& error);
+ KResult wait_for_connect(Socket&);
static void initialize();
@@ -349,7 +349,7 @@ private:
struct FileDescriptorAndFlags {
operator bool() const { return !!descriptor; }
void clear() { descriptor = nullptr; flags = 0; }
- void set(RetainPtr<FileDescriptor>&& d, dword f = 0) { descriptor = move(d); flags = f; }
+ void set(Retained<FileDescriptor>&& d, dword f = 0) { descriptor = move(d); flags = f; }
RetainPtr<FileDescriptor> descriptor;
dword flags { 0 };
};
diff --git a/Kernel/Socket.cpp b/Kernel/Socket.cpp
index e6cf5dd26b..454ce920f3 100644
--- a/Kernel/Socket.cpp
+++ b/Kernel/Socket.cpp
@@ -4,15 +4,14 @@
#include <Kernel/Process.h>
#include <LibC/errno_numbers.h>
-RetainPtr<Socket> Socket::create(int domain, int type, int protocol, int& error)
+KResultOr<Retained<Socket>> Socket::create(int domain, int type, int protocol)
{
(void)protocol;
switch (domain) {
case AF_LOCAL:
return LocalSocket::create(type & SOCK_TYPE_MASK);
default:
- error = EAFNOSUPPORT;
- return nullptr;
+ return KResult(-EAFNOSUPPORT);
}
}
@@ -28,16 +27,14 @@ Socket::~Socket()
{
}
-bool Socket::listen(int backlog, int& error)
+KResult Socket::listen(int backlog)
{
LOCKER(m_lock);
- if (m_type != SOCK_STREAM) {
- error = -EOPNOTSUPP;
- return false;
- }
+ if (m_type != SOCK_STREAM)
+ return KResult(-EOPNOTSUPP);
m_backlog = backlog;
kprintf("Socket{%p} listening with backlog=%d\n", this, m_backlog);
- return true;
+ return KSuccess;
}
RetainPtr<Socket> Socket::accept()
@@ -52,13 +49,11 @@ RetainPtr<Socket> Socket::accept()
return client;
}
-bool Socket::queue_connection_from(Socket& peer, int& error)
+KResult Socket::queue_connection_from(Socket& peer)
{
LOCKER(m_lock);
- if (m_pending.size() >= m_backlog) {
- error = -ECONNREFUSED;
- return false;
- }
+ if (m_pending.size() >= m_backlog)
+ return KResult(-ECONNREFUSED);
m_pending.append(peer);
- return true;
+ return KSuccess;
}
diff --git a/Kernel/Socket.h b/Kernel/Socket.h
index d62154b089..1144ece54a 100644
--- a/Kernel/Socket.h
+++ b/Kernel/Socket.h
@@ -6,12 +6,13 @@
#include <AK/HashTable.h>
#include <AK/Vector.h>
#include <Kernel/UnixTypes.h>
+#include <Kernel/KResult.h>
enum class SocketRole { None, Listener, Accepted, Connected };
class Socket : public Retainable<Socket> {
public:
- static RetainPtr<Socket> create(int domain, int type, int protocol, int& error);
+ static KResultOr<Retained<Socket>> create(int domain, int type, int protocol);
virtual ~Socket();
int domain() const { return m_domain; }
@@ -21,10 +22,10 @@ public:
bool can_accept() const { return !m_pending.is_empty(); }
RetainPtr<Socket> accept();
bool is_connected() const { return m_connected; }
- bool listen(int backlog, int& error);
+ KResult listen(int backlog);
- virtual bool bind(const sockaddr*, socklen_t, int& error) = 0;
- virtual bool connect(const sockaddr*, socklen_t, int& error) = 0;
+ virtual KResult bind(const sockaddr*, socklen_t) = 0;
+ virtual KResult connect(const sockaddr*, socklen_t) = 0;
virtual bool get_address(sockaddr*, socklen_t*) = 0;
virtual bool is_local() const { return false; }
virtual void attach_fd(SocketRole) = 0;
@@ -39,7 +40,7 @@ public:
protected:
Socket(int domain, int type, int protocol);
- bool queue_connection_from(Socket&, int& error);
+ KResult queue_connection_from(Socket&);
private:
Lock m_lock;
diff --git a/Kernel/VirtualFileSystem.cpp b/Kernel/VirtualFileSystem.cpp
index 801b207809..773205dd16 100644
--- a/Kernel/VirtualFileSystem.cpp
+++ b/Kernel/VirtualFileSystem.cpp
@@ -123,26 +123,25 @@ void VFS::traverse_directory_inode(Inode& dir_inode, Function<bool(const FS::Dir
});
}
-RetainPtr<FileDescriptor> VFS::open(RetainPtr<Device>&& device, int& error, int options)
+KResultOr<Retained<FileDescriptor>> VFS::open(RetainPtr<Device>&& device, int options)
{
// FIXME: Respect options.
- (void) options;
- (void) error;
+ (void)options;
return FileDescriptor::create(move(device));
}
KResult VFS::utime(const String& path, Inode& base, time_t atime, time_t mtime)
{
- int error;
- auto descriptor = VFS::the().open(move(path), error, 0, 0, base);
- if (!descriptor)
- return KResult(error);
- auto& inode = *descriptor->inode();
+ auto descriptor_or_error = VFS::the().open(move(path), 0, 0, base);
+ if (descriptor_or_error.is_error())
+ return descriptor_or_error.error();
+ auto& inode = *descriptor_or_error.value()->inode();
if (inode.fs().is_readonly())
return KResult(-EROFS);
if (inode.metadata().uid != current->euid())
return KResult(-EACCES);
- error = inode.set_atime(atime);
+
+ int error = inode.set_atime(atime);
if (error)
return KResult(error);
error = inode.set_mtime(mtime);
@@ -159,60 +158,50 @@ KResult VFS::stat(const String& path, int options, Inode& base, struct stat& sta
return FileDescriptor::create(inode_or_error.value().ptr())->fstat(statbuf);
}
-RetainPtr<FileDescriptor> VFS::open(const String& path, int& error, int options, mode_t mode, Inode& base)
+KResultOr<Retained<FileDescriptor>> VFS::open(const String& path, int options, mode_t mode, Inode& base)
{
- auto inode_id = old_resolve_path(path, base.identifier(), error, options);
- auto inode = get_inode(inode_id);
+ auto inode_or_error = resolve_path_to_inode(path, base, nullptr, options);
if (options & O_CREAT) {
- if (!inode)
- return create(path, error, options, mode, base);
- else if (options & O_EXCL) {
- error = -EEXIST;
- return nullptr;
- }
+ if (inode_or_error.is_error())
+ return create(path, options, mode, base);
+ if (options & O_EXCL)
+ return KResult(-EEXIST);
}
- if (!inode)
- return nullptr;
+ if (inode_or_error.is_error())
+ return inode_or_error.error();
- auto metadata = inode->metadata();
+ auto metadata = inode_or_error.value()->metadata();
// NOTE: Read permission is a bit weird, since O_RDONLY == 0,
// so we check if (NOT write_only OR read_and_write)
if (!(options & O_WRONLY) || (options & O_RDWR)) {
- if (!metadata.may_read(*current)) {
- error = -EACCES;
- return nullptr;
- }
+ if (!metadata.may_read(*current))
+ return KResult(-EACCES);
}
if ((options & O_WRONLY) || (options & O_RDWR)) {
- if (!metadata.may_write(*current)) {
- error = -EACCES;
- return nullptr;
- }
- if (metadata.is_directory()) {
- error = -EISDIR;
- return nullptr;
- }
+ if (!metadata.may_write(*current))
+ return KResult(-EACCES);
+ if (metadata.is_directory())
+ return KResult(-EISDIR);
}
if (metadata.is_device()) {
auto it = m_devices.find(encoded_device(metadata.major_device, metadata.minor_device));
if (it == m_devices.end()) {
kprintf("VFS::open: no such device %u,%u\n", metadata.major_device, metadata.minor_device);
- error = -ENODEV;
- return nullptr;
+ return KResult(-ENODEV);
}
- auto descriptor = (*it).value->open(error, options);
- descriptor->set_original_inode(Badge<VFS>(), move(inode));
+ auto descriptor = (*it).value->open(options);
+ ASSERT(!descriptor.is_error());
+ descriptor.value()->set_original_inode(Badge<VFS>(), *inode_or_error.value());
return descriptor;
}
- return FileDescriptor::create(move(inode));
+ return FileDescriptor::create(*inode_or_error.value());
}
-RetainPtr<FileDescriptor> VFS::create(const String& path, int& error, int options, mode_t mode, Inode& base)
+KResultOr<Retained<FileDescriptor>> VFS::create(const String& path, int options, mode_t mode, Inode& base)
{
- (void) options;
- error = -EWHYTHO;
+ (void)options;
if (!is_socket(mode) && !is_fifo(mode) && !is_block_device(mode) && !is_character_device(mode)) {
// Turn it into a regular file. (This feels rather hackish.)
@@ -220,30 +209,23 @@ RetainPtr<FileDescriptor> VFS::create(const String& path, int& error, int option
}
RetainPtr<Inode> parent_inode;
- auto existing_file = resolve_path_to_inode(path, base, error, &parent_inode);
- if (existing_file) {
- error = -EEXIST;
- return nullptr;
- }
- if (!parent_inode) {
- error = -ENOENT;
- return nullptr;
- }
- if (error != -ENOENT) {
- return nullptr;
- }
- if (!parent_inode->metadata().may_write(*current)) {
- error = -EACCES;
- return nullptr;
- }
+ auto existing_file_or_error = resolve_path_to_inode(path, base, &parent_inode);
+ if (!existing_file_or_error.is_error())
+ return KResult(-EEXIST);
+ if (!parent_inode)
+ return KResult(-ENOENT);
+ if (existing_file_or_error.error() != -ENOENT)
+ return existing_file_or_error.error();
+ if (!parent_inode->metadata().may_write(*current))
+ return KResult(-EACCES);
FileSystemPath p(path);
dbgprintf("VFS::create_file: '%s' in %u:%u\n", p.basename().characters(), parent_inode->fsid(), parent_inode->index());
+ int error;
auto new_file = parent_inode->fs().create_inode(parent_inode->identifier(), p.basename(), mode, 0, error);
if (!new_file)
- return nullptr;
+ return KResult(error);
- error = 0;
return FileDescriptor::create(move(new_file));
}
diff --git a/Kernel/VirtualFileSystem.h b/Kernel/VirtualFileSystem.h
index 9ea065ede1..d72cf9fb3c 100644
--- a/Kernel/VirtualFileSystem.h
+++ b/Kernel/VirtualFileSystem.h
@@ -62,9 +62,9 @@ public:
bool mount_root(RetainPtr<FS>&&);
bool mount(RetainPtr<FS>&&, const String& path);
- RetainPtr<FileDescriptor> open(RetainPtr<Device>&&, int& error, int options);
- RetainPtr<FileDescriptor> open(const String& path, int& error, int options, mode_t mode, Inode& base);
- RetainPtr<FileDescriptor> create(const String& path, int& error, int options, mode_t mode, Inode& base);
+ KResultOr<Retained<FileDescriptor>> open(RetainPtr<Device>&&, int options);
+ KResultOr<Retained<FileDescriptor>> open(const String& path, int options, mode_t mode, Inode& base);
+ KResultOr<Retained<FileDescriptor>> create(const String& path, int options, mode_t mode, Inode& base);
KResult mkdir(const String& path, mode_t mode, Inode& base);
KResult link(const String& old_path, const String& new_path, Inode& base);
KResult unlink(const String& path, Inode& base);