| 833 | } |
| 834 | |
| 835 | static int connection_write_full(cbm_daemon_ipc_connection_t *connection, const void *buffer, |
| 836 | size_t length, uint64_t deadline_ms) { |
| 837 | if (!connection || atomic_load_explicit(&connection->poisoned, memory_order_acquire)) { |
| 838 | return -1; |
| 839 | } |
| 840 | size_t offset = 0; |
| 841 | while (offset < length) { |
| 842 | int ready = poll_until(connection->fd, POLLOUT, deadline_ms); |
| 843 | if (ready != 1) { |
| 844 | atomic_store_explicit(&connection->poisoned, true, memory_order_release); |
| 845 | return ready; |
| 846 | } |
| 847 | #ifdef MSG_NOSIGNAL |
| 848 | ssize_t sent = |
| 849 | send(connection->fd, (const uint8_t *)buffer + offset, length - offset, MSG_NOSIGNAL); |
| 850 | #else |
| 851 | ssize_t sent = send(connection->fd, (const uint8_t *)buffer + offset, length - offset, 0); |
| 852 | #endif |
| 853 | if (sent > 0) { |
| 854 | offset += (size_t)sent; |
| 855 | continue; |
| 856 | } |
| 857 | if (sent == 0) { |
| 858 | atomic_store_explicit(&connection->poisoned, true, memory_order_release); |
| 859 | return -1; |
| 860 | } |
| 861 | if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) { |
| 862 | atomic_store_explicit(&connection->poisoned, true, memory_order_release); |
| 863 | return -1; |
| 864 | } |
| 865 | } |
| 866 | return 1; |
| 867 | } |
| 868 | |
| 869 | cbm_daemon_ipc_endpoint_t *cbm_daemon_ipc_endpoint_new(const char *instance_key, |
| 870 | const char *runtime_parent) { |
no test coverage detected