Преглед на файлове

Kernel: Port more code to KResult and KResultOr<T>.

Andreas Kling преди 6 години
родител
ревизия
028afabf6b
променени са 15 файла, в които са добавени 155 реда и са изтрити 198 реда
  1. 2 2
      Kernel/Device.cpp
  2. 1 1
      Kernel/Device.h
  3. 1 1
      Kernel/FileDescriptor.h
  4. 13 0
      Kernel/KResult.h
  5. 6 10
      Kernel/KSyms.cpp
  6. 28 48
      Kernel/LocalSocket.cpp
  7. 2 2
      Kernel/LocalSocket.h
  8. 4 6
      Kernel/PTYMultiplexer.cpp
  9. 1 1
      Kernel/PTYMultiplexer.h
  10. 35 43
      Kernel/Process.cpp
  11. 2 2
      Kernel/Process.h
  12. 10 15
      Kernel/Socket.cpp
  13. 6 5
      Kernel/Socket.h
  14. 41 59
      Kernel/VirtualFileSystem.cpp
  15. 3 3
      Kernel/VirtualFileSystem.h

+ 2 - 2
Kernel/Device.cpp

@@ -13,9 +13,9 @@ Device::~Device()
     VFS::the().unregister_device(*this);
     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()
 void Device::close()

+ 1 - 1
Kernel/Device.h

@@ -13,7 +13,7 @@ public:
 
 
     InodeMetadata metadata() const { return { }; }
     InodeMetadata metadata() const { return { }; }
 
 
-    virtual RetainPtr<FileDescriptor> open(int& error, int options);
+    virtual KResultOr<Retained<FileDescriptor>> open(int options);
     virtual void close();
     virtual void close();
 
 
     virtual bool can_read(Process&) const = 0;
     virtual bool can_read(Process&) const = 0;

+ 1 - 1
Kernel/FileDescriptor.h

@@ -86,7 +86,7 @@ public:
 
 
     ByteBuffer& generator_cache() { return m_generator_cache; }
     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);
     void set_socket_role(SocketRole);
 
 

+ 13 - 0
Kernel/KResult.h

@@ -34,6 +34,19 @@ public:
         new (&m_storage) T(move(value));
         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()
     ~KResultOr()
     {
     {
         if (!m_is_error)
         if (!m_is_error)

+ 6 - 10
Kernel/KSyms.cpp

@@ -126,14 +126,10 @@ void init_ksyms()
 
 
 void load_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);
 }
 }
-

+ 28 - 48
Kernel/LocalSocket.cpp

@@ -33,17 +33,13 @@ bool LocalSocket::get_address(sockaddr* address, socklen_t* address_size)
     return true;
     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());
     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);
     const sockaddr_un& local_address = *reinterpret_cast<const sockaddr_un*>(address);
     char safe_address[sizeof(local_address.sun_path) + 1];
     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);
     kprintf("%s(%u) LocalSocket{%p} bind(%s)\n", current->name().characters(), current->pid(), this, safe_address);
 #endif
 #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());
     ASSERT(m_file->inode());
     m_file->inode()->bind_socket(*this);
     m_file->inode()->bind_socket(*this);
 
 
     m_address = local_address;
     m_address = local_address;
     m_bound = true;
     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);
     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);
     const sockaddr_un& local_address = *reinterpret_cast<const sockaddr_un*>(address);
     char safe_address[sizeof(local_address.sun_path) + 1];
     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);
     kprintf("%s(%u) LocalSocket{%p} connect(%s)\n", current->name().characters(), current->pid(), this, safe_address);
 #endif
 #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());
     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;
     m_address = local_address;
 
 
     auto peer = m_file->inode()->socket();
     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)
 void LocalSocket::attach_fd(SocketRole role)

+ 2 - 2
Kernel/LocalSocket.h

@@ -10,8 +10,8 @@ public:
     static Retained<LocalSocket> create(int type);
     static Retained<LocalSocket> create(int type);
     virtual ~LocalSocket() override;
     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 bool get_address(sockaddr*, socklen_t*) override;
     virtual void attach_fd(SocketRole) override;
     virtual void attach_fd(SocketRole) override;
     virtual void detach_fd(SocketRole) override;
     virtual void detach_fd(SocketRole) override;

+ 4 - 6
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);
     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_index = m_freelist.take_last();
     auto master = adopt(*new MasterPTY(master_index));
     auto master = adopt(*new MasterPTY(master_index));
     dbgprintf("PTYMultiplexer::open: Vending master %u\n", 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)
 void PTYMultiplexer::notify_master_destroyed(Badge<MasterPTY>, unsigned index)

+ 1 - 1
Kernel/PTYMultiplexer.h

@@ -15,7 +15,7 @@ public:
     static PTYMultiplexer& the();
     static PTYMultiplexer& the();
 
 
     // ^CharacterDevice
     // ^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 read(Process&, byte*, ssize_t) override { return 0; }
     virtual ssize_t write(Process&, const 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; }
     virtual bool can_read(Process&) const override { return true; }

+ 35 - 43
Kernel/Process.cpp

@@ -293,12 +293,10 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
     if (parts.is_empty())
     if (parts.is_empty())
         return -ENOENT;
         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))
     if (!descriptor->metadata().may_execute(m_euid, m_gids))
         return -EACCES;
         return -EACCES;
@@ -644,10 +642,9 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring
     } else {
     } else {
         m_fds.resize(m_max_open_file_descriptors);
         m_fds.resize(m_max_open_file_descriptors);
         auto& device_to_use_as_tty = tty ? (CharacterDevice&)*tty : NullDevice::the();
         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)
     if (fork_parent)
@@ -1306,7 +1303,7 @@ int Process::sys$fcntl(int fd, int cmd, dword arg)
         }
         }
         if (new_fd == -1)
         if (new_fd == -1)
             return -EMFILE;
             return -EMFILE;
-        m_fds[new_fd].set(descriptor);
+        m_fds[new_fd].set(*descriptor);
         break;
         break;
     }
     }
     case F_GETFD:
     case F_GETFD:
@@ -1359,10 +1356,10 @@ int Process::sys$readlink(const char* path, char* buffer, ssize_t size)
     if (!validate_write(buffer, size))
     if (!validate_write(buffer, size))
         return -EFAULT;
         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())
     if (!descriptor->metadata().is_symlink())
         return -EINVAL;
         return -EINVAL;
@@ -1422,10 +1419,11 @@ int Process::sys$open(const char* path, int options, mode_t mode)
         return -EFAULT;
         return -EFAULT;
     if (number_of_open_file_descriptors() >= m_max_open_file_descriptors)
     if (number_of_open_file_descriptors() >= m_max_open_file_descriptors)
         return -EMFILE;
         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())
     if (options & O_DIRECTORY && !descriptor->is_directory())
         return -ENOTDIR; // FIXME: This should be handled by VFS::open.
         return -ENOTDIR; // FIXME: This should be handled by VFS::open.
     if (options & O_NONBLOCK)
     if (options & O_NONBLOCK)
@@ -1952,7 +1950,7 @@ int Process::sys$dup(int old_fd)
         if (!m_fds[new_fd])
         if (!m_fds[new_fd])
             break;
             break;
     }
     }
-    m_fds[new_fd].set(descriptor);
+    m_fds[new_fd].set(*descriptor);
     return new_fd;
     return new_fd;
 }
 }
 
 
@@ -1963,7 +1961,7 @@ int Process::sys$dup2(int old_fd, int new_fd)
         return -EBADF;
         return -EBADF;
     if (number_of_open_file_descriptors() == m_max_open_file_descriptors)
     if (number_of_open_file_descriptors() == m_max_open_file_descriptors)
         return -EMFILE;
         return -EMFILE;
-    m_fds[new_fd].set(descriptor);
+    m_fds[new_fd].set(*descriptor);
     return new_fd;
     return new_fd;
 }
 }
 
 
@@ -2400,11 +2398,10 @@ int Process::sys$socket(int domain, int type, int protocol)
         if (!m_fds[fd])
         if (!m_fds[fd])
             break;
             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;
     unsigned flags = 0;
     if (type & SOCK_CLOEXEC)
     if (type & SOCK_CLOEXEC)
         flags |= FD_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())
     if (!descriptor->is_socket())
         return -ENOTSOCK;
         return -ENOTSOCK;
     auto& socket = *descriptor->socket();
     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)
 int Process::sys$listen(int sockfd, int backlog)
@@ -2438,9 +2432,9 @@ int Process::sys$listen(int sockfd, int backlog)
     if (!descriptor->is_socket())
     if (!descriptor->is_socket())
         return -ENOTSOCK;
         return -ENOTSOCK;
     auto& socket = *descriptor->socket();
     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);
     descriptor->set_socket_role(SocketRole::Listener);
     return 0;
     return 0;
 }
 }
@@ -2497,26 +2491,24 @@ int Process::sys$connect(int sockfd, const sockaddr* address, socklen_t address_
     if (!descriptor->is_socket())
     if (!descriptor->is_socket())
         return -ENOTSOCK;
         return -ENOTSOCK;
     auto& socket = *descriptor->socket();
     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);
     descriptor->set_socket_role(SocketRole::Connected);
     return 0;
     return 0;
 }
 }
 
 
-bool Process::wait_for_connect(Socket& socket, int& error)
+KResult Process::wait_for_connect(Socket& socket)
 {
 {
     if (socket.is_connected())
     if (socket.is_connected())
-        return true;
+        return KSuccess;
     m_blocked_connecting_socket = socket;
     m_blocked_connecting_socket = socket;
     block(BlockedConnect);
     block(BlockedConnect);
     Scheduler::yield();
     Scheduler::yield();
     m_blocked_connecting_socket = nullptr;
     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 {
 struct SharedBuffer {

+ 2 - 2
Kernel/Process.h

@@ -236,7 +236,7 @@ public:
     void* sys$get_shared_buffer(int shared_buffer_id);
     void* sys$get_shared_buffer(int shared_buffer_id);
     int sys$release_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();
     static void initialize();
 
 
@@ -349,7 +349,7 @@ private:
     struct FileDescriptorAndFlags {
     struct FileDescriptorAndFlags {
         operator bool() const { return !!descriptor; }
         operator bool() const { return !!descriptor; }
         void clear() { descriptor = nullptr; flags = 0; }
         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;
         RetainPtr<FileDescriptor> descriptor;
         dword flags { 0 };
         dword flags { 0 };
     };
     };

+ 10 - 15
Kernel/Socket.cpp

@@ -4,15 +4,14 @@
 #include <Kernel/Process.h>
 #include <Kernel/Process.h>
 #include <LibC/errno_numbers.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;
     (void)protocol;
     switch (domain) {
     switch (domain) {
     case AF_LOCAL:
     case AF_LOCAL:
         return LocalSocket::create(type & SOCK_TYPE_MASK);
         return LocalSocket::create(type & SOCK_TYPE_MASK);
     default:
     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);
     LOCKER(m_lock);
-    if (m_type != SOCK_STREAM) {
-        error = -EOPNOTSUPP;
-        return false;
-    }
+    if (m_type != SOCK_STREAM)
+        return KResult(-EOPNOTSUPP);
     m_backlog = backlog;
     m_backlog = backlog;
     kprintf("Socket{%p} listening with backlog=%d\n", this, m_backlog);
     kprintf("Socket{%p} listening with backlog=%d\n", this, m_backlog);
-    return true;
+    return KSuccess;
 }
 }
 
 
 RetainPtr<Socket> Socket::accept()
 RetainPtr<Socket> Socket::accept()
@@ -52,13 +49,11 @@ RetainPtr<Socket> Socket::accept()
     return client;
     return client;
 }
 }
 
 
-bool Socket::queue_connection_from(Socket& peer, int& error)
+KResult Socket::queue_connection_from(Socket& peer)
 {
 {
     LOCKER(m_lock);
     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);
     m_pending.append(peer);
-    return true;
+    return KSuccess;
 }
 }

+ 6 - 5
Kernel/Socket.h

@@ -6,12 +6,13 @@
 #include <AK/HashTable.h>
 #include <AK/HashTable.h>
 #include <AK/Vector.h>
 #include <AK/Vector.h>
 #include <Kernel/UnixTypes.h>
 #include <Kernel/UnixTypes.h>
+#include <Kernel/KResult.h>
 
 
 enum class SocketRole { None, Listener, Accepted, Connected };
 enum class SocketRole { None, Listener, Accepted, Connected };
 
 
 class Socket : public Retainable<Socket> {
 class Socket : public Retainable<Socket> {
 public:
 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();
     virtual ~Socket();
 
 
     int domain() const { return m_domain; }
     int domain() const { return m_domain; }
@@ -21,10 +22,10 @@ public:
     bool can_accept() const { return !m_pending.is_empty(); }
     bool can_accept() const { return !m_pending.is_empty(); }
     RetainPtr<Socket> accept();
     RetainPtr<Socket> accept();
     bool is_connected() const { return m_connected; }
     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 get_address(sockaddr*, socklen_t*) = 0;
     virtual bool is_local() const { return false; }
     virtual bool is_local() const { return false; }
     virtual void attach_fd(SocketRole) = 0;
     virtual void attach_fd(SocketRole) = 0;
@@ -39,7 +40,7 @@ public:
 protected:
 protected:
     Socket(int domain, int type, int protocol);
     Socket(int domain, int type, int protocol);
 
 
-    bool queue_connection_from(Socket&, int& error);
+    KResult queue_connection_from(Socket&);
 
 
 private:
 private:
     Lock m_lock;
     Lock m_lock;

+ 41 - 59
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.
     // FIXME: Respect options.
-    (void) options;
-    (void) error;
+    (void)options;
     return FileDescriptor::create(move(device));
     return FileDescriptor::create(move(device));
 }
 }
 
 
 KResult VFS::utime(const String& path, Inode& base, time_t atime, time_t mtime)
 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())
     if (inode.fs().is_readonly())
         return KResult(-EROFS);
         return KResult(-EROFS);
     if (inode.metadata().uid != current->euid())
     if (inode.metadata().uid != current->euid())
         return KResult(-EACCES);
         return KResult(-EACCES);
-    error = inode.set_atime(atime);
+
+    int error = inode.set_atime(atime);
     if (error)
     if (error)
         return KResult(error);
         return KResult(error);
     error = inode.set_mtime(mtime);
     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);
     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 (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,
     // NOTE: Read permission is a bit weird, since O_RDONLY == 0,
     //       so we check if (NOT write_only OR read_and_write)
     //       so we check if (NOT write_only OR read_and_write)
     if (!(options & O_WRONLY) || (options & O_RDWR)) {
     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 ((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()) {
     if (metadata.is_device()) {
         auto it = m_devices.find(encoded_device(metadata.major_device, metadata.minor_device));
         auto it = m_devices.find(encoded_device(metadata.major_device, metadata.minor_device));
         if (it == m_devices.end()) {
         if (it == m_devices.end()) {
             kprintf("VFS::open: no such device %u,%u\n", metadata.major_device, metadata.minor_device);
             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 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)) {
     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.)
         // 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;
     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);
     FileSystemPath p(path);
     dbgprintf("VFS::create_file: '%s' in %u:%u\n", p.basename().characters(), parent_inode->fsid(), parent_inode->index());
     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);
     auto new_file = parent_inode->fs().create_inode(parent_inode->identifier(), p.basename(), mode, 0, error);
     if (!new_file)
     if (!new_file)
-        return nullptr;
+        return KResult(error);
 
 
-    error = 0;
     return FileDescriptor::create(move(new_file));
     return FileDescriptor::create(move(new_file));
 }
 }
 
 

+ 3 - 3
Kernel/VirtualFileSystem.h

@@ -62,9 +62,9 @@ public:
     bool mount_root(RetainPtr<FS>&&);
     bool mount_root(RetainPtr<FS>&&);
     bool mount(RetainPtr<FS>&&, const String& path);
     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 mkdir(const String& path, mode_t mode, Inode& base);
     KResult link(const String& old_path, const String& new_path, Inode& base);
     KResult link(const String& old_path, const String& new_path, Inode& base);
     KResult unlink(const String& path, Inode& base);
     KResult unlink(const String& path, Inode& base);