1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 03:27:34 +00:00

Kernel: Make File::write() and File::read() return KResultOr<size_t>

Instead of returning a ssize_t where negative values mean error,
we now return KResultOr<size_t> and use the error state to report
errors exclusively.
This commit is contained in:
Andreas Kling 2020-08-04 18:02:23 +02:00
parent 58feebeed2
commit 7a3ab6c517
58 changed files with 223 additions and 229 deletions

View file

@ -418,7 +418,10 @@ KResultOr<NonnullRefPtr<FileDescription>> Process::find_elf_interpreter_for_exec
return KResult(-ENOEXEC);
memset(first_page, 0, sizeof(first_page));
nread = interpreter_description->read((u8*)&first_page, sizeof(first_page));
auto nread_or_error = interpreter_description->read((u8*)&first_page, sizeof(first_page));
if (nread_or_error.is_error())
return KResult(-ENOEXEC);
nread = nread_or_error.value();
if (nread < (int)sizeof(Elf32_Ehdr))
return KResult(-ENOEXEC);
@ -482,10 +485,12 @@ int Process::exec(String path, Vector<String> arguments, Vector<String> environm
// Read the first page of the program into memory so we can validate the binfmt of it
char first_page[PAGE_SIZE];
int nread = description->read((u8*)&first_page, sizeof(first_page));
auto nread_or_error = description->read((u8*)&first_page, sizeof(first_page));
if (nread_or_error.is_error())
return -ENOEXEC;
// 1) #! interpreted file
auto shebang_result = find_shebang_interpreter_for_executable(first_page, nread);
auto shebang_result = find_shebang_interpreter_for_executable(first_page, nread_or_error.value());
if (!shebang_result.is_error()) {
Vector<String> new_arguments(shebang_result.value());
@ -498,7 +503,7 @@ int Process::exec(String path, Vector<String> arguments, Vector<String> environm
}
// #2) ELF32 for i386
auto elf_result = find_elf_interpreter_for_executable(path, first_page, nread, metadata.size);
auto elf_result = find_elf_interpreter_for_executable(path, first_page, nread_or_error.value(), metadata.size);
RefPtr<FileDescription> interpreter_description;
// We're getting either an interpreter, an error, or KSuccess (i.e. no interpreter but file checks out)
if (!elf_result.is_error())

View file

@ -56,8 +56,10 @@ ssize_t Process::sys$read(int fd, Userspace<u8*> buffer, ssize_t size)
return -EAGAIN;
}
}
// FIXME: We should have a read() that takes a Userspace<u8*>
return description->read(buffer.unsafe_userspace_ptr(), size);
auto result = description->read(buffer.unsafe_userspace_ptr(), size);
if (result.is_error())
return result.error();
return result.value();
}
}

View file

@ -211,7 +211,10 @@ ssize_t Process::sys$sendto(const Syscall::SC_sendto_params* user_params)
if (socket.is_shut_down_for_writing())
return -EPIPE;
SmapDisabler disabler;
return socket.sendto(*description, params.data.data, params.data.size, flags, addr, addr_length);
auto result = socket.sendto(*description, params.data.data, params.data.size, flags, addr, addr_length);
if (result.is_error())
return result.error();
return result.value();
}
ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params)
@ -251,11 +254,13 @@ ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params)
if (flags & MSG_DONTWAIT)
description->set_blocking(false);
auto nrecv = socket.recvfrom(*description, params.buffer.data, params.buffer.size, flags, addr, addr_length);
auto result = socket.recvfrom(*description, params.buffer.data, params.buffer.size, flags, addr, addr_length);
if (flags & MSG_DONTWAIT)
description->set_blocking(original_blocking);
return nrecv;
if (result.is_error())
return result.error();
return result.value();
}
template<bool sockname, typename Params>

View file

@ -74,51 +74,38 @@ ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count)
ssize_t Process::do_write(FileDescription& description, const u8* data, int data_size)
{
ssize_t nwritten = 0;
ssize_t total_nwritten = 0;
if (!description.is_blocking()) {
if (!description.can_write())
return -EAGAIN;
}
if (description.should_append()) {
#ifdef IO_DEBUG
dbg() << "seeking to end (O_APPEND)";
#endif
if (description.should_append())
description.seek(0, SEEK_END);
}
while (nwritten < data_size) {
#ifdef IO_DEBUG
dbg() << "while " << nwritten << " < " << size;
#endif
while (total_nwritten < data_size) {
if (!description.can_write()) {
if (!description.is_blocking()) {
// Short write: We can no longer write to this non-blocking description.
ASSERT(nwritten > 0);
return nwritten;
ASSERT(total_nwritten > 0);
return total_nwritten;
}
#ifdef IO_DEBUG
dbg() << "block write on " << description.absolute_path();
#endif
if (Thread::current()->block<Thread::WriteBlocker>(nullptr, description).was_interrupted()) {
if (nwritten == 0)
if (total_nwritten == 0)
return -EINTR;
}
}
ssize_t rc = description.write(data + nwritten, data_size - nwritten);
#ifdef IO_DEBUG
dbg() << " -> write returned " << rc;
#endif
if (rc < 0) {
if (nwritten)
return nwritten;
return rc;
auto nwritten_or_error = description.write(data + total_nwritten, data_size - total_nwritten);
if (nwritten_or_error.is_error()) {
if (total_nwritten)
return total_nwritten;
return nwritten_or_error.error();
}
if (rc == 0)
if (nwritten_or_error.value() == 0)
break;
nwritten += rc;
total_nwritten += nwritten_or_error.value();
}
return nwritten;
return total_nwritten;
}
ssize_t Process::sys$write(int fd, const u8* data, ssize_t size)