|
1 | 1 | #include <asm/ioctls.h> |
2 | 2 | #include <dirent.h> |
3 | 3 | #include <errno.h> |
| 4 | +#include <frg/small_vector.hpp> |
4 | 5 | #include <stdio.h> |
5 | 6 | #include <sys/eventfd.h> |
6 | 7 | #include <sys/inotify.h> |
@@ -847,7 +848,7 @@ int sys_socketpair(int domain, int type_and_flags, int proto, int *fds) { |
847 | 848 | } |
848 | 849 |
|
849 | 850 | 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()}; |
851 | 852 | auto handle = getHandleForFd(sockfd); |
852 | 853 | if (!handle) |
853 | 854 | return EBADF; |
@@ -1743,6 +1744,64 @@ int sys_write(int fd, const void *data, size_t size, ssize_t *bytes_written) { |
1743 | 1744 | } |
1744 | 1745 | } |
1745 | 1746 |
|
| 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 | + |
1746 | 1805 | int sys_pread(int fd, void *buf, size_t n, off_t off, ssize_t *bytes_read) { |
1747 | 1806 | SignalGuard sguard; |
1748 | 1807 |
|
|
0 commit comments