From 151b2b266e1dae3679584f38b954e4357cf1e5cc Mon Sep 17 00:00:00 2001
From: Wim Taymans <wtaymans@redhat.com>
Date: Wed, 19 Jun 2019 10:49:28 +0200
Subject: [PATCH] connection: add do_close flag to connect_fd

Make pw_remote_connect_fd() not automatically close the provided
fd but let the caller take care of that. This allows us to reuse
the fd in pipewiresrc.

Fixes #155
---
 src/modules/module-protocol-native.c              | 7 ++++---
 src/modules/module-protocol-native/local-socket.c | 2 +-
 src/pipewire/protocol.h                           | 4 ++--
 src/pipewire/remote.c                             | 8 ++++----
 src/pipewire/remote.h                             | 3 ++-
 5 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c
index 131657f6..0e7b7e27 100644
--- a/src/modules/module-protocol-native.c
+++ b/src/modules/module-protocol-native.c
@@ -619,7 +619,7 @@ static const struct pw_protocol_native_connection_events conn_events = {
 	.need_flush = on_need_flush,
 };
 
-static int impl_connect_fd(struct pw_protocol_client *client, int fd)
+static int impl_connect_fd(struct pw_protocol_client *client, int fd, bool do_close)
 {
 	struct client *impl = SPA_CONTAINER_OF(client, struct client, this);
 	struct pw_remote *remote = client->remote;
@@ -638,14 +638,15 @@ static int impl_connect_fd(struct pw_protocol_client *client, int fd)
         impl->source = pw_loop_add_io(remote->core->main_loop,
                                       fd,
                                       SPA_IO_IN | SPA_IO_HUP | SPA_IO_ERR,
-                                      true, on_remote_data, impl);
+                                      do_close, on_remote_data, impl);
 	if (impl->source == NULL)
 		goto error_close;
 
 	return 0;
 
       error_close:
-        close(fd);
+	if (do_close)
+	        close(fd);
         return -ENOMEM;
 }
 
diff --git a/src/modules/module-protocol-native/local-socket.c b/src/modules/module-protocol-native/local-socket.c
index 5ab5a210..0e68eea9 100644
--- a/src/modules/module-protocol-native/local-socket.c
+++ b/src/modules/module-protocol-native/local-socket.c
@@ -84,7 +84,7 @@ int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client,
                 goto error_close;
 	}
 
-	res = pw_protocol_client_connect_fd(client, fd);
+	res = pw_protocol_client_connect_fd(client, fd, true);
 
 	done_callback(data, res);
 
diff --git a/src/pipewire/protocol.h b/src/pipewire/protocol.h
index 2b6592d1..4a0845fb 100644
--- a/src/pipewire/protocol.h
+++ b/src/pipewire/protocol.h
@@ -44,14 +44,14 @@ struct pw_protocol_client {
 	int (*connect) (struct pw_protocol_client *client,
 			void (*done_callback) (void *data, int result),
 			void *data);
-	int (*connect_fd) (struct pw_protocol_client *client, int fd);
+	int (*connect_fd) (struct pw_protocol_client *client, int fd, bool close);
 	int (*steal_fd) (struct pw_protocol_client *client);
 	void (*disconnect) (struct pw_protocol_client *client);
 	void (*destroy) (struct pw_protocol_client *client);
 };
 
 #define pw_protocol_client_connect(c,cb,d)	((c)->connect(c,cb,d))
-#define pw_protocol_client_connect_fd(c,fd)	((c)->connect_fd(c,fd))
+#define pw_protocol_client_connect_fd(c,fd,cl)	((c)->connect_fd(c,fd,cl))
 #define pw_protocol_client_steal_fd(c)		((c)->steal_fd(c))
 #define pw_protocol_client_disconnect(c)	((c)->disconnect(c))
 #define pw_protocol_client_destroy(c)		((c)->destroy(c))
diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c
index f63a973a..472b2684 100644
--- a/src/pipewire/remote.c
+++ b/src/pipewire/remote.c
@@ -305,7 +305,7 @@ void pw_remote_destroy(struct pw_remote *remote)
 	spa_list_consume(stream, &remote->stream_list, link)
 		pw_stream_destroy(stream);
 
-	pw_protocol_client_destroy (remote->conn);
+	pw_protocol_client_destroy(remote->conn);
 
 	spa_list_remove(&remote->link);
 
@@ -413,7 +413,7 @@ int pw_remote_connect(struct pw_remote *remote)
 
 	pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTING, NULL);
 
-	if ((res = pw_protocol_client_connect (remote->conn, done_connect, remote)) < 0) {
+	if ((res = pw_protocol_client_connect(remote->conn, done_connect, remote)) < 0) {
 		pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR,
 				"connect failed %s", spa_strerror(res));
 		return res;
@@ -428,7 +428,7 @@ int pw_remote_connect_fd(struct pw_remote *remote, int fd)
 
 	pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTING, NULL);
 
-	if ((res = pw_protocol_client_connect_fd (remote->conn, fd)) < 0) {
+	if ((res = pw_protocol_client_connect_fd(remote->conn, fd, false)) < 0) {
 		pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR,
 				"connect_fd failed %s", spa_strerror(res));
 		return res;
@@ -462,7 +462,7 @@ int pw_remote_disconnect(struct pw_remote *remote)
 		pw_proxy_destroy(proxy);
 	remote->core_proxy = NULL;
 
-	pw_protocol_client_disconnect (remote->conn);
+	pw_protocol_client_disconnect(remote->conn);
 
 	pw_map_clear(&remote->objects);
 	pw_map_clear(&remote->types);
diff --git a/src/pipewire/remote.h b/src/pipewire/remote.h
index df0c496c..2974a04a 100644
--- a/src/pipewire/remote.h
+++ b/src/pipewire/remote.h
@@ -177,7 +177,8 @@ void pw_remote_add_listener(struct pw_remote *remote,
 int pw_remote_connect(struct pw_remote *remote);
 
 /** Connect to a remote PipeWire on the given socket \memberof pw_remote
- * \param fd the connected socket to use
+ * \param fd the connected socket to use, the socket will not be closed
+ *	automatically on disconnect or error.
  * \return 0 on success, < 0 on error */
 int pw_remote_connect_fd(struct pw_remote *remote, int fd);
 
