From b928cee5eb199779ae09704d61ba406ad2e16447 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Jank=C5=AF?= <jjanku@redhat.com>
Date: Tue, 30 Apr 2019 11:33:39 +0200
Subject: [PATCH 05/20] udscs-server: split initialization
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Git-commit: e6c14d0ecc168c8549bd8dfb918158076ee3db34
References: bsc#1173749

Divide creation of udscs_server into 2 steps:

1) udscs_server_new()
 - allocates new udscs_server struct and inits it

2) udscs_server_listen_to_fd(), udscs_server_listen_to_address()
 - starts accepting new connections

Remove udscs_create_server() and udscs_create_server_for_fd().

This makes the code a bit shorter and nicer.

Signed-off-by: Jakub Janků <jjanku@redhat.com>
Acked-by: Victor Toso <victortoso@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
 src/udscs.c             | 64 +++++++++++------------------------------
 src/udscs.h             | 28 +++++++++---------
 src/vdagentd/vdagentd.c | 24 ++++++----------
 3 files changed, 38 insertions(+), 78 deletions(-)

diff --git a/src/udscs.c b/src/udscs.c
index 9c600c3..bc8fa8d 100644
--- a/src/udscs.c
+++ b/src/udscs.c
@@ -175,7 +175,7 @@ static gboolean udscs_server_accept_cb(GSocketService    *service,
                                        GObject           *source_object,
                                        gpointer           user_data);
 
-static struct udscs_server *udscs_server_new(
+struct udscs_server *udscs_server_new(
     udscs_connect_callback connect_callback,
     udscs_read_callback read_callback,
     VDAgentConnErrorCb error_cb,
@@ -196,66 +196,34 @@ static struct udscs_server *udscs_server_new(
     return server;
 }
 
-struct udscs_server *udscs_create_server_for_fd(int fd,
-    udscs_connect_callback connect_callback,
-    udscs_read_callback read_callback,
-    VDAgentConnErrorCb error_cb,
-    int debug)
+void udscs_server_listen_to_socket(struct udscs_server *server,
+                                   gint                 fd,
+                                   GError             **err)
 {
-    struct udscs_server *server;
     GSocket *socket;
-    GError *err = NULL;
-
-    server = udscs_server_new(connect_callback, read_callback,
-                              error_cb, debug);
 
-    socket = g_socket_new_from_fd(fd, &err);
-    if (err) {
-        goto error;
+    socket = g_socket_new_from_fd(fd, err);
+    if (socket == NULL) {
+        return;
     }
     g_socket_listener_add_socket(G_SOCKET_LISTENER(server->service),
-                                 socket, NULL, &err);
+                                 socket, NULL, err);
     g_object_unref(socket);
-    if (err) {
-        goto error;
-    }
-
-    return server;
-error:
-    syslog(LOG_ERR, "%s: %s", __func__, err->message);
-    g_error_free(err);
-    udscs_destroy_server(server);
-    return NULL;
 }
 
-struct udscs_server *udscs_create_server(const char *socketname,
-    udscs_connect_callback connect_callback,
-    udscs_read_callback read_callback,
-    VDAgentConnErrorCb error_cb,
-    int debug)
+void udscs_server_listen_to_address(struct udscs_server *server,
+                                    const gchar         *addr,
+                                    GError             **err)
 {
-    struct udscs_server *server;
-    GSocketAddress *socket_addr;
-    GError *err = NULL;
-
-    server = udscs_server_new(connect_callback, read_callback,
-                              error_cb, debug);
+    GSocketAddress *sock_addr;
 
-    socket_addr = g_unix_socket_address_new(socketname);
+    sock_addr = g_unix_socket_address_new(addr);
     g_socket_listener_add_address(G_SOCKET_LISTENER(server->service),
-                                  socket_addr,
+                                  sock_addr,
                                   G_SOCKET_TYPE_STREAM,
                                   G_SOCKET_PROTOCOL_DEFAULT,
-                                  NULL, NULL, &err);
-    g_object_unref(socket_addr);
-    if (err) {
-        syslog(LOG_ERR, "%s: %s", __func__, err->message);
-        g_error_free(err);
-        udscs_destroy_server(server);
-        return NULL;
-    }
-
-    return server;
+                                  NULL, NULL, err);
+    g_object_unref(sock_addr);
 }
 
 void udscs_server_destroy_connection(struct udscs_server *server,
diff --git a/src/udscs.h b/src/udscs.h
index 382da06..b3c1e41 100644
--- a/src/udscs.h
+++ b/src/udscs.h
@@ -89,31 +89,29 @@ struct udscs_server;
  */
 typedef void (*udscs_connect_callback)(struct udscs_connection *conn);
 
-/* Create a server for the given file descriptor. This allows us to use
- * pre-configured sockets for use with systemd socket activation, etc.
- *
- * See udscs_create_server() for more information
- */
-struct udscs_server *udscs_create_server_for_fd(int fd,
-    udscs_connect_callback connect_callback,
-    udscs_read_callback read_callback,
-    VDAgentConnErrorCb error_cb,
-    int debug);
-
-/* Create the unix domain socket specified by socketname and
- * start listening on it.
- * Only sockets bound to a pathname are supported.
+/* Initialize a new udscs_server struct.
  *
  * If debug is true then the events on this socket and related individual
  * connections will be traced.
  * This includes the incoming and outgoing message names.
  */
-struct udscs_server *udscs_create_server(const char *socketname,
+struct udscs_server *udscs_server_new(
     udscs_connect_callback connect_callback,
     udscs_read_callback read_callback,
     VDAgentConnErrorCb error_cb,
     int debug);
 
+/* Start listening on a pre-configured socket specified by the given @fd.
+ * This can be used with systemd socket activation, etc. */
+void udscs_server_listen_to_socket(struct udscs_server *server,
+                                   gint                 fd,
+                                   GError             **err);
+
+/* Create a new socket, bind it to @address and start listening on it. */
+void udscs_server_listen_to_address(struct udscs_server *server,
+                                    const gchar         *addr,
+                                    GError             **err);
+
 void udscs_server_destroy_connection(struct udscs_server *server,
                                      UdscsConnection     *conn);
 
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index d6a22b8..cfdf820 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -1152,6 +1152,8 @@ int main(int argc, char *argv[])
     openlog("spice-vdagentd", do_daemonize ? 0 : LOG_PERROR, LOG_USER);
 
     /* Setup communication with vdagent process(es) */
+    server = udscs_server_new(agent_connect, agent_read_complete,
+                              agent_disconnect, debug);
 #ifdef WITH_SYSTEMD_SOCKET_ACTIVATION
     int n_fds;
     /* try to retrieve pre-configured sockets from systemd */
@@ -1160,28 +1162,20 @@ int main(int argc, char *argv[])
         syslog(LOG_CRIT, "Received too many sockets from systemd (%i)", n_fds);
         return 1;
     } else if (n_fds == 1) {
-        server = udscs_create_server_for_fd(SD_LISTEN_FDS_START, agent_connect,
-                                            agent_read_complete,
-                                            agent_disconnect,
-                                            debug);
+        udscs_server_listen_to_socket(server, SD_LISTEN_FDS_START, &err);
         own_socket = FALSE;
     } else
     /* systemd socket activation not enabled, create our own */
 #endif /* WITH_SYSTEMD_SOCKET_ACTIVATION */
     {
-        server = udscs_create_server(vdagentd_socket, agent_connect,
-                                     agent_read_complete, agent_disconnect,
-                                     debug);
+        udscs_server_listen_to_address(server, vdagentd_socket, &err);
     }
 
-    if (!server) {
-        if (errno == EADDRINUSE) {
-            syslog(LOG_CRIT, "Fatal the server socket %s exists already. Delete it?",
-                   vdagentd_socket);
-        } else {
-            syslog(LOG_CRIT, "Fatal could not create the server socket %s",
-                   vdagentd_socket);
-        }
+    if (err) {
+        syslog(LOG_CRIT, "Fatal could not create the server socket %s: %s",
+                         vdagentd_socket, err->message);
+        g_error_free(err);
+        udscs_destroy_server(server);
         return 1;
     }
 
-- 
2.29.0

