From f5294414004c258236a9d31ae3d3ee00ccb26717 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Mon, 13 Feb 2012 20:58:57 +0100
Subject: [PATCH] server_socket: add method _add_fd()

---
 src/server_socket.c | 30 ++++++++++++++++++++++++++++++
 src/server_socket.h |  8 ++++++++
 2 files changed, 38 insertions(+)

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.
  *