Internal write function called by __wasi_fd_write and __wasi_fd_pwrite Receives an open file state offset. Optionally sets open file state offset.
| 91 | // Receives an open file state offset. |
| 92 | // Optionally sets open file state offset. |
| 93 | static __wasi_errno_t writeAtOffset(OffsetHandling setOffset, |
| 94 | __wasi_fd_t fd, |
| 95 | const __wasi_ciovec_t* iovs, |
| 96 | size_t iovs_len, |
| 97 | __wasi_size_t* nwritten, |
| 98 | __wasi_filesize_t offset = 0) { |
| 99 | auto openFile = wasmFS.getFileTable().locked().getEntry(fd); |
| 100 | if (!openFile) { |
| 101 | return __WASI_ERRNO_BADF; |
| 102 | } |
| 103 | |
| 104 | if (iovs_len < 0 || offset < 0) { |
| 105 | return __WASI_ERRNO_INVAL; |
| 106 | } |
| 107 | |
| 108 | auto lockedOpenFile = openFile->locked(); |
| 109 | auto file = lockedOpenFile.getFile()->dynCast<DataFile>(); |
| 110 | if (!file) { |
| 111 | return __WASI_ERRNO_ISDIR; |
| 112 | } |
| 113 | |
| 114 | auto lockedFile = file->locked(); |
| 115 | |
| 116 | if (setOffset == OffsetHandling::OpenFileState) { |
| 117 | if (lockedOpenFile.getFlags() & O_APPEND) { |
| 118 | off_t size = lockedFile.getSize(); |
| 119 | if (size < 0) { |
| 120 | // Translate to WASI standard of positive return codes. |
| 121 | return -size; |
| 122 | } |
| 123 | offset = size; |
| 124 | lockedOpenFile.setPosition(offset); |
| 125 | } else { |
| 126 | offset = lockedOpenFile.getPosition(); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | // TODO: Check open file access mode for write permissions. |
| 131 | |
| 132 | size_t bytesWritten = 0; |
| 133 | for (size_t i = 0; i < iovs_len; i++) { |
| 134 | const uint8_t* buf = iovs[i].buf; |
| 135 | off_t len = iovs[i].buf_len; |
| 136 | |
| 137 | // Check if buf_len specifies a positive length buffer but buf is a |
| 138 | // null pointer |
| 139 | if (!buf && len > 0) { |
| 140 | return __WASI_ERRNO_INVAL; |
| 141 | } |
| 142 | |
| 143 | // Check if the sum of the buf_len values overflows an off_t (63 bits). |
| 144 | if (addWillOverFlow(offset, (__wasi_filesize_t)bytesWritten)) { |
| 145 | return __WASI_ERRNO_FBIG; |
| 146 | } |
| 147 | |
| 148 | auto result = lockedFile.write(buf, len, offset + bytesWritten); |
| 149 | if (result < 0) { |
| 150 | // This individual write failed. Report the error unless we've already |
no test coverage detected