mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:28:11 +00:00
Kernel: Port more code to KResult and KResultOr<T>.
This commit is contained in:
parent
3079ef01ce
commit
028afabf6b
15 changed files with 155 additions and 198 deletions
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -126,14 +126,10 @@ void init_ksyms()
|
||||||
|
|
||||||
void load_ksyms()
|
void load_ksyms()
|
||||||
{
|
{
|
||||||
int error;
|
auto result = VFS::the().open("/kernel.map", 0, 0, *VFS::the().root_inode());
|
||||||
auto descriptor = VFS::the().open("/kernel.map", error, 0, 0, *VFS::the().root_inode());
|
ASSERT(!result.is_error());
|
||||||
if (!descriptor) {
|
auto descriptor = result.value();
|
||||||
kprintf("Failed to open /kernel.map\n");
|
auto buffer = descriptor->read_entire_file(*current);
|
||||||
} else {
|
ASSERT(buffer);
|
||||||
auto buffer = descriptor->read_entire_file(*current);
|
load_ksyms_from_data(buffer);
|
||||||
ASSERT(buffer);
|
|
||||||
load_ksyms_from_data(buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)) {
|
if (address_size != sizeof(sockaddr_un))
|
||||||
error = -EINVAL;
|
return KResult(-EINVAL);
|
||||||
return false;
|
if (address->sa_family != AF_LOCAL)
|
||||||
}
|
return KResult(-EINVAL);
|
||||||
if (address->sa_family != AF_LOCAL) {
|
|
||||||
error = -EINVAL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
auto result = VFS::the().open(safe_address, O_CREAT | O_EXCL, S_IFSOCK | 0666, current->cwd_inode());
|
||||||
if (!m_file) {
|
if (result.is_error()) {
|
||||||
if (error == -EEXIST)
|
if (result.error() == -EEXIST)
|
||||||
error = -EADDRINUSE;
|
return KResult(-EADDRINUSE);
|
||||||
return false;
|
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)) {
|
if (address_size != sizeof(sockaddr_un))
|
||||||
error = -EINVAL;
|
return KResult(-EINVAL);
|
||||||
return false;
|
if (address->sa_family != AF_LOCAL)
|
||||||
}
|
return KResult(-EINVAL);
|
||||||
if (address->sa_family != AF_LOCAL) {
|
|
||||||
error = -EINVAL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
auto descriptor_or_error = VFS::the().open(safe_address, 0, 0, current->cwd_inode());
|
||||||
if (!m_file) {
|
if (descriptor_or_error.is_error())
|
||||||
error = -ECONNREFUSED;
|
return KResult(-ECONNREFUSED);
|
||||||
return false;
|
m_file = move(descriptor_or_error.value());
|
||||||
}
|
|
||||||
ASSERT(m_file->inode());
|
ASSERT(m_file->inode());
|
||||||
if (!m_file->inode()->socket()) {
|
if (!m_file->inode()->socket())
|
||||||
error = -ECONNREFUSED;
|
return KResult(-ECONNREFUSED);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_address = local_address;
|
m_address = local_address;
|
||||||
|
|
||||||
auto peer = m_file->inode()->socket();
|
auto peer = m_file->inode()->socket();
|
||||||
#ifdef DEBUG_LOCAL_SOCKET
|
auto result = peer->queue_connection_from(*this);
|
||||||
kprintf("Queueing up connection\n");
|
if (result.is_error())
|
||||||
#endif
|
return result;
|
||||||
if (!peer->queue_connection_from(*this, error))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef DEBUG_LOCAL_SOCKET
|
return current->wait_for_connect(*this);
|
||||||
kprintf("Waiting for connect...\n");
|
|
||||||
#endif
|
|
||||||
if (!current->wait_for_connect(*this, error))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef DEBUG_LOCAL_SOCKET
|
|
||||||
kprintf("CONNECTED!\n");
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalSocket::attach_fd(SocketRole role)
|
void LocalSocket::attach_fd(SocketRole role)
|
||||||
|
|
|
@ -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 KResult bind(const sockaddr*, socklen_t) override;
|
||||||
virtual bool connect(const sockaddr*, socklen_t, int& error) 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;
|
||||||
|
|
|
@ -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()) {
|
if (m_freelist.is_empty())
|
||||||
error = -EBUSY;
|
return KResult(-EBUSY);
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
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)
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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 result = VFS::the().open(path, 0, 0, cwd_inode());
|
||||||
auto descriptor = VFS::the().open(path, error, 0, 0, cwd_inode());
|
if (result.is_error())
|
||||||
if (!descriptor) {
|
return result.error();
|
||||||
ASSERT(error != 0);
|
auto descriptor = result.value();
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(O_RDONLY).value());
|
||||||
m_fds[0].set(device_to_use_as_tty.open(error, O_RDONLY));
|
m_fds[1].set(*device_to_use_as_tty.open(O_WRONLY).value());
|
||||||
m_fds[1].set(device_to_use_as_tty.open(error, O_WRONLY));
|
m_fds[2].set(*device_to_use_as_tty.open(O_WRONLY).value());
|
||||||
m_fds[2].set(device_to_use_as_tty.open(error, O_WRONLY));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 result = VFS::the().open(path, O_RDONLY | O_NOFOLLOW_NOERROR, 0, cwd_inode());
|
||||||
auto descriptor = VFS::the().open(path, error, O_RDONLY | O_NOFOLLOW_NOERROR, 0, cwd_inode());
|
if (result.is_error())
|
||||||
if (!descriptor)
|
return result.error();
|
||||||
return 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());
|
auto result = VFS::the().open(path, options, mode & ~umask(), cwd_inode());
|
||||||
if (!descriptor)
|
if (result.is_error())
|
||||||
return 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 result = Socket::create(domain, type, protocol);
|
||||||
auto socket = Socket::create(domain, type, protocol, error);
|
if (result.is_error())
|
||||||
if (!socket)
|
return result.error();
|
||||||
return error;
|
auto descriptor = FileDescriptor::create(*result.value());
|
||||||
auto descriptor = FileDescriptor::create(move(socket));
|
|
||||||
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;
|
return socket.bind(address, address_length);
|
||||||
if (!socket.bind(address, address_length, error))
|
|
||||||
return error;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
auto result = socket.listen(backlog);
|
||||||
if (!socket.listen(backlog, error))
|
if (result.is_error())
|
||||||
return 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;
|
auto result = socket.connect(address, address_size);
|
||||||
if (!socket.connect(address, address_size, error))
|
if (result.is_error())
|
||||||
return 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()) {
|
if (!socket.is_connected())
|
||||||
error = -ECONNREFUSED;
|
return KResult(-ECONNREFUSED);
|
||||||
return false;
|
return KSuccess;
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SharedBuffer {
|
struct SharedBuffer {
|
||||||
|
|
|
@ -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 };
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 KResult(-EAFNOSUPPORT);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
if (m_type != SOCK_STREAM)
|
||||||
error = -EOPNOTSUPP;
|
return KResult(-EOPNOTSUPP);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
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) {
|
if (m_pending.size() >= m_backlog)
|
||||||
error = -ECONNREFUSED;
|
return KResult(-ECONNREFUSED);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_pending.append(peer);
|
m_pending.append(peer);
|
||||||
return true;
|
return KSuccess;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 KResult bind(const sockaddr*, socklen_t) = 0;
|
||||||
virtual bool connect(const sockaddr*, socklen_t, int& error) = 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;
|
||||||
|
|
|
@ -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)options;
|
||||||
(void) error;
|
|
||||||
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_or_error = VFS::the().open(move(path), 0, 0, base);
|
||||||
auto descriptor = VFS::the().open(move(path), error, 0, 0, base);
|
if (descriptor_or_error.is_error())
|
||||||
if (!descriptor)
|
return descriptor_or_error.error();
|
||||||
return KResult(error);
|
auto& inode = *descriptor_or_error.value()->inode();
|
||||||
auto& inode = *descriptor->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_or_error = resolve_path_to_inode(path, base, nullptr, options);
|
||||||
auto inode = get_inode(inode_id);
|
|
||||||
if (options & O_CREAT) {
|
if (options & O_CREAT) {
|
||||||
if (!inode)
|
if (inode_or_error.is_error())
|
||||||
return create(path, error, options, mode, base);
|
return create(path, options, mode, base);
|
||||||
else if (options & O_EXCL) {
|
if (options & O_EXCL)
|
||||||
error = -EEXIST;
|
return KResult(-EEXIST);
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!inode)
|
if (inode_or_error.is_error())
|
||||||
return nullptr;
|
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)) {
|
if (!metadata.may_read(*current))
|
||||||
error = -EACCES;
|
return KResult(-EACCES);
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((options & O_WRONLY) || (options & O_RDWR)) {
|
if ((options & O_WRONLY) || (options & O_RDWR)) {
|
||||||
if (!metadata.may_write(*current)) {
|
if (!metadata.may_write(*current))
|
||||||
error = -EACCES;
|
return KResult(-EACCES);
|
||||||
return nullptr;
|
if (metadata.is_directory())
|
||||||
}
|
return KResult(-EISDIR);
|
||||||
if (metadata.is_directory()) {
|
|
||||||
error = -EISDIR;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 KResult(-ENODEV);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
auto descriptor = (*it).value->open(error, options);
|
auto descriptor = (*it).value->open(options);
|
||||||
descriptor->set_original_inode(Badge<VFS>(), move(inode));
|
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;
|
(void)options;
|
||||||
error = -EWHYTHO;
|
|
||||||
|
|
||||||
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);
|
auto existing_file_or_error = resolve_path_to_inode(path, base, &parent_inode);
|
||||||
if (existing_file) {
|
if (!existing_file_or_error.is_error())
|
||||||
error = -EEXIST;
|
return KResult(-EEXIST);
|
||||||
return nullptr;
|
if (!parent_inode)
|
||||||
}
|
return KResult(-ENOENT);
|
||||||
if (!parent_inode) {
|
if (existing_file_or_error.error() != -ENOENT)
|
||||||
error = -ENOENT;
|
return existing_file_or_error.error();
|
||||||
return nullptr;
|
if (!parent_inode->metadata().may_write(*current))
|
||||||
}
|
return KResult(-EACCES);
|
||||||
if (error != -ENOENT) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (!parent_inode->metadata().may_write(*current)) {
|
|
||||||
error = -EACCES;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
KResultOr<Retained<FileDescriptor>> open(RetainPtr<Device>&&, int options);
|
||||||
RetainPtr<FileDescriptor> open(const String& path, int& error, int options, mode_t mode, Inode& base);
|
KResultOr<Retained<FileDescriptor>> open(const String& path, 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>> 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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue