| 2822 | } |
| 2823 | |
| 2824 | int cbm_daemon_ipc_accept(cbm_daemon_ipc_listener_t *listener, uint32_t timeout_ms, |
| 2825 | cbm_daemon_ipc_connection_t **connection_out) { |
| 2826 | if (connection_out) { |
| 2827 | *connection_out = NULL; |
| 2828 | } |
| 2829 | if (!listener || listener->fd < 0 || listener->owner_pid != getpid() || !connection_out) { |
| 2830 | return -1; |
| 2831 | } |
| 2832 | uint64_t deadline_ms = ipc_deadline_after(timeout_ms); |
| 2833 | for (;;) { |
| 2834 | int ready = poll_until(listener->fd, POLLIN, deadline_ms); |
| 2835 | if (ready != 1) { |
| 2836 | return ready; |
| 2837 | } |
| 2838 | int fd = accept(listener->fd, NULL, NULL); |
| 2839 | if (fd < 0) { |
| 2840 | if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) { |
| 2841 | continue; |
| 2842 | } |
| 2843 | return -1; |
| 2844 | } |
| 2845 | if (!fd_set_cloexec(fd) || !fd_set_nonblocking(fd) || !socket_disable_sigpipe(fd) || |
| 2846 | !socket_peer_is_current_user(fd)) { |
| 2847 | (void)close(fd); |
| 2848 | return -1; |
| 2849 | } |
| 2850 | cbm_daemon_ipc_connection_t *connection = malloc(sizeof(*connection)); |
| 2851 | if (!connection) { |
| 2852 | (void)close(fd); |
| 2853 | return -1; |
| 2854 | } |
| 2855 | connection->fd = fd; |
| 2856 | atomic_init(&connection->poisoned, false); |
| 2857 | *connection_out = connection; |
| 2858 | return 1; |
| 2859 | } |
| 2860 | } |
| 2861 | |
| 2862 | int cbm_daemon_ipc_endpoint_probe(const cbm_daemon_ipc_endpoint_t *endpoint, uint32_t timeout_ms) { |
| 2863 | if (!endpoint_runtime_still_valid(endpoint)) { |