| 293 | } |
| 294 | |
| 295 | bool BackendIpcProcess::write_shared_payload_segments( |
| 296 | const BackendIpcPayloadSegment * segments, |
| 297 | size_t n_segments, |
| 298 | uint64_t & seq) { |
| 299 | if (!shared_payload_map_ || (!segments && n_segments > 0)) return false; |
| 300 | size_t bytes = 0; |
| 301 | for (size_t i = 0; i < n_segments; ++i) { |
| 302 | if (segments[i].bytes > 0 && !segments[i].data) return false; |
| 303 | if (!backend_ipc_checked_add_size(bytes, segments[i].bytes, bytes)) { |
| 304 | return false; |
| 305 | } |
| 306 | } |
| 307 | if (bytes > shared_payload_capacity_) return false; |
| 308 | auto * header = static_cast<BackendIpcSharedPayloadHeader *>(shared_payload_map_); |
| 309 | auto * payload = static_cast<char *>( |
| 310 | static_cast<char *>(shared_payload_map_) + backend_ipc_shared_payload_header_bytes()); |
| 311 | size_t off = 0; |
| 312 | for (size_t i = 0; i < n_segments; ++i) { |
| 313 | if (segments[i].bytes > 0) { |
| 314 | std::memcpy(payload + off, segments[i].data, segments[i].bytes); |
| 315 | off += segments[i].bytes; |
| 316 | } |
| 317 | } |
| 318 | seq = ++shared_payload_seq_; |
| 319 | // The command pipe publishes this request to another process. Publish the |
| 320 | // mapped payload header explicitly so the daemon cannot observe the prior |
| 321 | // response header after receiving the new command. |
| 322 | backend_ipc_publish_shared_payload_header( |
| 323 | header, seq, static_cast<uint64_t>(bytes)); |
| 324 | return true; |
| 325 | } |
no test coverage detected