Skip to content

Commit

Permalink
sysdeps/managarm: implement writev
Browse files Browse the repository at this point in the history
  • Loading branch information
no92 committed Nov 15, 2024
1 parent c906cb5 commit 728f087
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions sysdeps/managarm/generic/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1743,6 +1743,64 @@ int sys_write(int fd, const void *data, size_t size, ssize_t *bytes_written) {
}
}

int sys_writev(int fd, const struct iovec *iovs, int iovc, ssize_t *bytes_written) {
frg::vector<HelSgItem, MemoryAllocator> sglist{getSysdepsAllocator()};

size_t overall_size = 0;
for(int i = 0; i < iovc; i++) {
HelSgItem item{
.buffer = iovs[i].iov_base,
.length = iovs[i].iov_len,
};
sglist.push_back(item);
overall_size += iovs[i].iov_len;
}

SignalGuard sguard;

auto handle = getHandleForFd(fd);
if (!handle)
return EBADF;

managarm::fs::CntRequest<MemoryAllocator> req(getSysdepsAllocator());
req.set_req_type(managarm::fs::CntReqType::WRITE);
req.set_fd(fd);
req.set_size(overall_size);

auto [offer, send_req, imbue_creds, send_data, recv_resp] = exchangeMsgsSync(
handle,
helix_ng::offer(
helix_ng::sendBragiHeadOnly(req, getSysdepsAllocator()),
helix_ng::imbueCredentials(),
helix_ng::sendBufferSg(sglist.data(), iovc),
helix_ng::recvInline())
);
HEL_CHECK(offer.error());
HEL_CHECK(send_req.error());
HEL_CHECK(imbue_creds.error());
HEL_CHECK(send_data.error());
HEL_CHECK(recv_resp.error());

managarm::fs::SvrResponse<MemoryAllocator> resp(getSysdepsAllocator());
resp.ParseFromArray(recv_resp.data(), recv_resp.length());

if(resp.error() == managarm::fs::Errors::ILLEGAL_OPERATION_TARGET) {
return EINVAL; // FD does not support writes.
}else if(resp.error() == managarm::fs::Errors::NO_SPACE_LEFT) {
return ENOSPC;
}else if(resp.error() == managarm::fs::Errors::WOULD_BLOCK) {
return EAGAIN;
}else if(resp.error() == managarm::fs::Errors::NOT_CONNECTED) {
return ENOTCONN;
}else{
__ensure(resp.error() == managarm::fs::Errors::SUCCESS);
if(bytes_written)
*bytes_written = resp.size();

return 0;
}
}

int sys_pread(int fd, void *buf, size_t n, off_t off, ssize_t *bytes_read) {
SignalGuard sguard;

Expand Down

0 comments on commit 728f087

Please sign in to comment.