瀏覽代碼

Issue #11: daemonize after opening listen port.

The listen port should be opened before daemonizing otherwise if
opening the port fails, the user will get no feedback. The only
complication was that the listen socket needs to not be closed as part
of daemonizing.

Thanks to http://github.com/rickr for finding it.
Joel Martin 15 年之前
父節點
當前提交
31407abc25
共有 4 個文件被更改,包括 25 次插入11 次删除
  1. 12 6
      utils/websocket.c
  2. 10 4
      utils/websocket.py
  3. 2 0
      utils/wsproxy.c
  4. 1 1
      utils/wsproxy.py

+ 12 - 6
utils/websocket.c

@@ -1,5 +1,7 @@
 /*
  * WebSocket lib with support for "wss://" encryption.
+ * Copyright 2010 Joel Martin
+ * Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
  *
  * You can make a cert/key with openssl using:
  * openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
@@ -460,7 +462,7 @@ void signal_handler(sig) {
     }
 }
 
-void daemonize() {
+void daemonize(int keepfd) {
     int pid, i;
 
     umask(0);
@@ -483,7 +485,11 @@ void daemonize() {
 
     /* Close open files */
     for (i=getdtablesize(); i>=0; --i) {
-        close(i);
+        if (i != keepfd) {
+            close(i);
+        } else {
+            printf("keeping fd %d\n", keepfd);
+        }
     }
     i=open("/dev/null", O_RDWR);  // Redirect stdin
     dup(i);                       // Redirect stdout
@@ -507,10 +513,6 @@ void start_server() {
     if (! (cbuf_tmp = malloc(bufsize)) )
             { fatal("malloc()"); }
 
-    if (settings.daemon) {
-        daemonize();
-    }
-
     lsock = socket(AF_INET, SOCK_STREAM, 0);
     if (lsock < 0) { error("ERROR creating listener socket"); }
     bzero((char *) &serv_addr, sizeof(serv_addr));
@@ -532,6 +534,10 @@ void start_server() {
     }
     listen(lsock,100);
 
+    if (settings.daemon) {
+        daemonize(lsock);
+    }
+
     while (1) {
         clilen = sizeof(cli_addr);
         if (settings.listen_host && settings.listen_host[0] != '\0') {

+ 10 - 4
utils/websocket.py

@@ -2,6 +2,8 @@
 
 '''
 Python WebSocket library with support for "wss://" encryption.
+Copyright 2010 Joel Martin
+Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
 
 You can make a cert/key with openssl using:
 openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
@@ -154,7 +156,7 @@ def do_handshake(sock):
     retsock.send(response)
     return retsock
 
-def daemonize():
+def daemonize(keepfd=None):
     os.umask(0)
     os.chdir('/')
     os.setgid(os.getgid())  # relinquish elevations
@@ -175,7 +177,10 @@ def daemonize():
     if maxfd == resource.RLIM_INFINITY: maxfd = 256
     for fd in reversed(range(maxfd)):
         try:
-            os.close(fd)
+            if fd != keepfd:
+                os.close(fd)
+            else:
+                print "Keeping fd: %d" % fd
         except OSError, exc:
             if exc.errno != errno.EBADF: raise
 
@@ -187,12 +192,13 @@ def daemonize():
 
 def start_server():
 
-    if settings['daemon']: daemonize()
-
     lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     lsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     lsock.bind((settings['listen_host'], settings['listen_port']))
     lsock.listen(100)
+
+    if settings['daemon']: daemonize(keepfd=lsock.fileno())
+
     while True:
         try:
             csock = startsock = None

+ 2 - 0
utils/wsproxy.c

@@ -1,5 +1,7 @@
 /*
  * A WebSocket to TCP socket proxy with support for "wss://" encryption.
+ * Copyright 2010 Joel Martin
+ * Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
  *
  * You can make a cert/key with openssl using:
  * openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem

+ 1 - 1
utils/wsproxy.py

@@ -3,7 +3,7 @@
 '''
 A WebSocket to TCP socket proxy with support for "wss://" encryption.
 Copyright 2010 Joel Martin
-Licensed under LGPL version 3 (see LICENSE.LGPL-3)
+Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
 
 You can make a cert/key with openssl using:
 openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem