| 2786 | } |
| 2787 | |
| 2788 | int cbm_daemon_ipc_accept(cbm_daemon_ipc_listener_t *listener, uint32_t timeout_ms, |
| 2789 | cbm_daemon_ipc_connection_t **connection_out) { |
| 2790 | if (connection_out) { |
| 2791 | *connection_out = NULL; |
| 2792 | } |
| 2793 | if (!listener || listener->fd < 0 || listener->owner_pid != getpid() || !connection_out) { |
| 2794 | return -1; |
| 2795 | } |
| 2796 | uint64_t deadline_ms = ipc_deadline_after(timeout_ms); |
| 2797 | for (;;) { |
| 2798 | int ready = poll_until(listener->fd, POLLIN, deadline_ms); |
| 2799 | if (ready != 1) { |
| 2800 | return ready; |
| 2801 | } |
| 2802 | int fd = accept(listener->fd, NULL, NULL); |
| 2803 | if (fd < 0) { |
| 2804 | if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) { |
| 2805 | continue; |
| 2806 | } |
| 2807 | return -1; |
| 2808 | } |
| 2809 | if (!fd_set_cloexec(fd) || !fd_set_nonblocking(fd) || !socket_disable_sigpipe(fd) || |
| 2810 | !socket_peer_is_current_user(fd)) { |
| 2811 | (void)close(fd); |
| 2812 | return -1; |
| 2813 | } |
| 2814 | cbm_daemon_ipc_connection_t *connection = malloc(sizeof(*connection)); |
| 2815 | if (!connection) { |
| 2816 | (void)close(fd); |
| 2817 | return -1; |
| 2818 | } |
| 2819 | connection->fd = fd; |
| 2820 | atomic_init(&connection->poisoned, false); |
| 2821 | *connection_out = connection; |
| 2822 | return 1; |
| 2823 | } |
| 2824 | } |
| 2825 | |
| 2826 | int cbm_daemon_ipc_endpoint_probe(const cbm_daemon_ipc_endpoint_t *endpoint, uint32_t timeout_ms) { |
| 2827 | if (!endpoint_runtime_still_valid(endpoint)) { |