Skip to content

Commit b115980

Browse files
authored
Merge pull request #1187 from no92/writev
sysdeps/managarm: implement writev
2 parents 3462fa7 + cd43dad commit b115980

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

sysdeps/managarm/generic/file.cpp

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <asm/ioctls.h>
22
#include <dirent.h>
33
#include <errno.h>
4+
#include <frg/small_vector.hpp>
45
#include <stdio.h>
56
#include <sys/eventfd.h>
67
#include <sys/inotify.h>
@@ -847,7 +848,7 @@ int sys_socketpair(int domain, int type_and_flags, int proto, int *fds) {
847848
}
848849

849850
int sys_msg_send(int sockfd, const struct msghdr *hdr, int flags, ssize_t *length) {
850-
frg::vector<HelSgItem, MemoryAllocator> sglist{getSysdepsAllocator()};
851+
frg::small_vector<HelSgItem, 8, MemoryAllocator> sglist{getSysdepsAllocator()};
851852
auto handle = getHandleForFd(sockfd);
852853
if (!handle)
853854
return EBADF;
@@ -1743,6 +1744,64 @@ int sys_write(int fd, const void *data, size_t size, ssize_t *bytes_written) {
17431744
}
17441745
}
17451746

1747+
int sys_writev(int fd, const struct iovec *iovs, int iovc, ssize_t *bytes_written) {
1748+
frg::small_vector<HelSgItem, 8, MemoryAllocator> sglist{getSysdepsAllocator()};
1749+
1750+
size_t overall_size = 0;
1751+
for(int i = 0; i < iovc; i++) {
1752+
HelSgItem item{
1753+
.buffer = iovs[i].iov_base,
1754+
.length = iovs[i].iov_len,
1755+
};
1756+
sglist.push_back(item);
1757+
overall_size += iovs[i].iov_len;
1758+
}
1759+
1760+
SignalGuard sguard;
1761+
1762+
auto handle = getHandleForFd(fd);
1763+
if (!handle)
1764+
return EBADF;
1765+
1766+
managarm::fs::CntRequest<MemoryAllocator> req(getSysdepsAllocator());
1767+
req.set_req_type(managarm::fs::CntReqType::WRITE);
1768+
req.set_fd(fd);
1769+
req.set_size(overall_size);
1770+
1771+
auto [offer, send_req, imbue_creds, send_data, recv_resp] = exchangeMsgsSync(
1772+
handle,
1773+
helix_ng::offer(
1774+
helix_ng::sendBragiHeadOnly(req, getSysdepsAllocator()),
1775+
helix_ng::imbueCredentials(),
1776+
helix_ng::sendBufferSg(sglist.data(), iovc),
1777+
helix_ng::recvInline())
1778+
);
1779+
HEL_CHECK(offer.error());
1780+
HEL_CHECK(send_req.error());
1781+
HEL_CHECK(imbue_creds.error());
1782+
HEL_CHECK(send_data.error());
1783+
HEL_CHECK(recv_resp.error());
1784+
1785+
managarm::fs::SvrResponse<MemoryAllocator> resp(getSysdepsAllocator());
1786+
resp.ParseFromArray(recv_resp.data(), recv_resp.length());
1787+
1788+
if(resp.error() == managarm::fs::Errors::ILLEGAL_OPERATION_TARGET) {
1789+
return EINVAL; // FD does not support writes.
1790+
}else if(resp.error() == managarm::fs::Errors::NO_SPACE_LEFT) {
1791+
return ENOSPC;
1792+
}else if(resp.error() == managarm::fs::Errors::WOULD_BLOCK) {
1793+
return EAGAIN;
1794+
}else if(resp.error() == managarm::fs::Errors::NOT_CONNECTED) {
1795+
return ENOTCONN;
1796+
}else{
1797+
__ensure(resp.error() == managarm::fs::Errors::SUCCESS);
1798+
if(bytes_written)
1799+
*bytes_written = resp.size();
1800+
1801+
return 0;
1802+
}
1803+
}
1804+
17461805
int sys_pread(int fd, void *buf, size_t n, off_t off, ssize_t *bytes_read) {
17471806
SignalGuard sguard;
17481807

0 commit comments

Comments
 (0)