diff --git a/src/server_socket.c b/src/server_socket.c index 58b3d234a..e4b5e3ece 100644 --- a/src/server_socket.c +++ b/src/server_socket.c @@ -299,6 +299,36 @@ one_socket_new(unsigned serial, const struct sockaddr *address, return s; } +bool +server_socket_add_fd(struct server_socket *ss, int fd, GError **error_r) +{ + assert(ss != NULL); + assert(ss->sockets_tail_r != NULL); + assert(*ss->sockets_tail_r == NULL); + assert(fd >= 0); + + struct sockaddr_storage address; + socklen_t address_length; + if (getsockname(fd, (struct sockaddr *)&address, + &address_length) < 0) { + g_set_error(error_r, server_socket_quark(), errno, + "Failed to get socket address: %s", + g_strerror(errno)); + return false; + } + + struct one_socket *s = one_socket_new(ss->next_serial, + (struct sockaddr *)&address, + address_length); + s->parent = ss; + *ss->sockets_tail_r = s; + ss->sockets_tail_r = &s->next; + + set_fd(s, fd); + + return true; +} + static struct one_socket * server_socket_add_address(struct server_socket *ss, const struct sockaddr *address, diff --git a/src/server_socket.h b/src/server_socket.h index e5777f7b3..7caa4bbf2 100644 --- a/src/server_socket.h +++ b/src/server_socket.h @@ -43,6 +43,14 @@ server_socket_open(struct server_socket *ss, GError **error_r); void server_socket_close(struct server_socket *ss); +/** + * Add a socket descriptor that is accepting connections. After this + * has been called, don't call server_socket_open(), because the + * socket is already open. + */ +bool +server_socket_add_fd(struct server_socket *ss, int fd, GError **error_r); + /** * Add a listener on a port on all interfaces. *