Add support to pass in a socket master
authorAlex Bligh <alex@alex.org.uk>
Tue, 11 Sep 2012 18:48:17 +0000 (19:48 +0100)
committerAlex Bligh <alex@alex.org.uk>
Tue, 11 Sep 2012 18:48:17 +0000 (19:48 +0100)
src/daemon.c

index 55ae2b2..3f77d27 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
@@ -263,7 +262,7 @@ void guacd_handle_connection_xml(int fd, char* xmlconfig) {
     }
 
     if (NULL == (protocol = xml_get_string(pDoc, "/params/protocol"))) {
-        guacd_log_guac_error("Could not parse XML");
+        guacd_log_guac_error("Could not find protocol element in XML");
         goto error;
     }
 
@@ -437,6 +436,7 @@ int main(int argc, char* argv[]) {
     char* pidfile = NULL;
     int opt;
     int foreground = 0;
+    int suppliedfd = -1;
     char * xmlconfig = NULL;
 
     /* General */
@@ -445,7 +445,7 @@ int main(int argc, char* argv[]) {
     xml_init();
 
     /* Parse arguments */
-    while ((opt = getopt(argc, argv, "l:b:p:x:f")) != -1) {
+    while ((opt = getopt(argc, argv, "l:b:p:x:s:f")) != -1) {
         if (opt == 'l') {
             listen_port = strdup(optarg);
         }
@@ -458,6 +458,10 @@ int main(int argc, char* argv[]) {
         else if (opt == 'p') {
             pidfile = strdup(optarg);
         }
+        else if (opt == 's') {
+            suppliedfd = atoi(optarg);
+            foreground = 2;
+        }
         else if (opt == 'x') {
             xmlconfig = strdup (optarg);
         }
@@ -467,6 +471,7 @@ int main(int argc, char* argv[]) {
                     " [-l LISTENPORT]"
                     " [-b LISTENADDRESS]"
                     " [-p PIDFILE]"
+                   " [-s SOCKETFD]"
                     " [-f]"
                     " [-x XMLCONFIG]\n", argv[0]);
 
@@ -497,20 +502,39 @@ int main(int argc, char* argv[]) {
     /* Open log as early as we can */
     openlog(NULL, LOG_PID, LOG_DAEMON);
 
+    /* Ignore SIGPIPE */
+    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+        guacd_log_info("Could not set handler for SIGPIPE to ignore. SIGPIPE may cause termination of the daemon.");
+    }
+
+    /* Ignore SIGCHLD (force automatic removal of children) */
+    if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
+        guacd_log_info("Could not set handler for SIGCHLD to ignore. Child processes may pile up in the process table.");
+    }
+
+    /* Handle the case where we have a supplied fd */
+    if (suppliedfd != -1) {
+        if (xmlconfig)
+            guacd_handle_connection_xml(suppliedfd, xmlconfig);
+        else
+            guacd_handle_connection(suppliedfd);
+        goto exit;
+    }
+
     /* Get addresses for binding */
     if ((retval = getaddrinfo(listen_address, listen_port, &hints, &addresses))) {
         guacd_log_error("Error parsing given address or port: %s",
-                gai_strerror(retval));
+                        gai_strerror(retval));
         exit(EXIT_FAILURE);
     }
-
+    
     /* Get socket */
     socket_fd = socket(AF_INET, SOCK_STREAM, 0);
     if (socket_fd < 0) {
         guacd_log_error("Error opening socket: %s", strerror(errno));
         exit(EXIT_FAILURE);
     }
-
+    
     /* Allow socket reuse */
     if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (void*) &opt_on, sizeof(opt_on))) {
         guacd_log_info("Unable to set socket options for reuse: %s", strerror(errno));
@@ -560,16 +584,6 @@ int main(int argc, char* argv[]) {
         exit(EXIT_FAILURE);
     }
 
-    /* Ignore SIGPIPE */
-    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
-        guacd_log_info("Could not set handler for SIGPIPE to ignore. SIGPIPE may cause termination of the daemon.");
-    }
-
-    /* Ignore SIGCHLD (force automatic removal of children) */
-    if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
-        guacd_log_info("Could not set handler for SIGCHLD to ignore. Child processes may pile up in the process table.");
-    }
-
     /* Log listening status */
     syslog(LOG_INFO,
             "Listening on host %s, port %s", bound_address, bound_port);
@@ -634,6 +648,7 @@ int main(int argc, char* argv[]) {
         return 3;
     }
 
+  exit:
     xml_deinit();
     return 0;