diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-06 22:14:31 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-06 22:14:31 +0100 |
commit | 028afabf6b22664c728f07234bc1dda0f8cb0fbe (patch) | |
tree | f394afd30390209fcd48c28422e972def7065212 /Kernel | |
parent | 3079ef01ce4da0f70b7c53551c8f1ea0699576d7 (diff) | |
download | serenity-028afabf6b22664c728f07234bc1dda0f8cb0fbe.zip |
Kernel: Port more code to KResult and KResultOr<T>.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Device.cpp | 4 | ||||
-rw-r--r-- | Kernel/Device.h | 2 | ||||
-rw-r--r-- | Kernel/FileDescriptor.h | 2 | ||||
-rw-r--r-- | Kernel/KResult.h | 13 | ||||
-rw-r--r-- | Kernel/KSyms.cpp | 16 | ||||
-rw-r--r-- | Kernel/LocalSocket.cpp | 76 | ||||
-rw-r--r-- | Kernel/LocalSocket.h | 4 | ||||
-rw-r--r-- | Kernel/PTYMultiplexer.cpp | 10 | ||||
-rw-r--r-- | Kernel/PTYMultiplexer.h | 2 | ||||
-rw-r--r-- | Kernel/Process.cpp | 78 | ||||
-rw-r--r-- | Kernel/Process.h | 4 | ||||
-rw-r--r-- | Kernel/Socket.cpp | 25 | ||||
-rw-r--r-- | Kernel/Socket.h | 11 | ||||
-rw-r--r-- | Kernel/VirtualFileSystem.cpp | 100 | ||||
-rw-r--r-- | Kernel/VirtualFileSystem.h | 6 |
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); |