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:
parent
58feebeed2
commit
7a3ab6c517
58 changed files with 223 additions and 229 deletions
|
@ -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())
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue