Преглед изворни кода

BSignal: simplify, use BUnixSignal on Linux

ambrop7 пре 15 година
родитељ
комит
e343031ae3
11 измењених фајлова са 88 додато и 289 уклоњено
  1. 3 8
      client/client.c
  2. 3 10
      examples/bprocess_example.c
  3. 3 10
      examples/dhcpclient_test.c
  4. 3 10
      examples/ipc_client.c
  5. 3 10
      examples/ipc_server.c
  6. 3 8
      flooder/flooder.c
  7. 3 8
      ncd/ncd.c
  8. 3 8
      server/server.c
  9. 56 180
      system/BSignal.c
  10. 5 29
      system/BSignal.h
  11. 3 8
      tun2socks/tun2socks.c

+ 3 - 8
client/client.c

@@ -417,15 +417,10 @@ int main (int argc, char *argv[])
     }
     
     // setup signal handler
-    if (!BSignal_Init()) {
+    if (!BSignal_Init(&ss, signal_handler, NULL)) {
         BLog(BLOG_ERROR, "BSignal_Init failed");
         goto fail1b;
     }
-    BSignal_Capture();
-    if (!BSignal_SetHandler(&ss, signal_handler, NULL)) {
-        BLog(BLOG_ERROR, "BSignal_SetHandler failed");
-        goto fail1b;
-    }
     
     if (options.ssl) {
         // init NSPR
@@ -561,7 +556,7 @@ fail2:
         ASSERT_FORCE(PR_Cleanup() == PR_SUCCESS)
         PL_ArenaFinish();
     }
-    BSignal_RemoveHandler();
+    BSignal_Finish();
 fail1b:
     BReactor_Free(&ss);
 fail1:
@@ -667,7 +662,7 @@ void terminate (void)
     }
     
     // remove signal handler
-    BSignal_RemoveHandler();
+    BSignal_Finish();
     
     // exit reactor
     BReactor_Quit(&ss, 1);

+ 3 - 10
examples/bprocess_example.c

@@ -61,18 +61,11 @@ int main (int argc, char **argv)
         goto fail1;
     }
     
-    if (!BSignal_Init()) {
+    if (!BSignal_Init(&reactor, signal_handler, NULL)) {
         DEBUG("BSignal_Init failed");
         goto fail2;
     }
     
-    BSignal_Capture();
-    
-    if (!BSignal_SetHandler(&reactor, signal_handler, NULL)) {
-        DEBUG("BSignal_SetHandler failed");
-        goto fail2;
-    }
-    
     if (!BProcessManager_Init(&manager, &reactor)) {
         DEBUG("BProcessManager_Init failed");
         goto fail3;
@@ -98,7 +91,7 @@ int main (int argc, char **argv)
 fail4:
     BProcessManager_Free(&manager);
 fail3:
-    BSignal_RemoveHandler();
+    BSignal_Finish();
 fail2:
     BReactor_Free(&reactor);
 fail1:
@@ -114,7 +107,7 @@ void terminate (int ret)
     
     BProcessManager_Free(&manager);
     
-    BSignal_RemoveHandler();
+    BSignal_Finish();
     
     BReactor_Quit(&reactor, ret);
 }

+ 3 - 10
examples/dhcpclient_test.c

@@ -59,18 +59,11 @@ int main (int argc, char **argv)
         goto fail1;
     }
     
-    if (!BSignal_Init()) {
+    if (!BSignal_Init(&reactor, signal_handler, NULL)) {
         DEBUG("BSignal_Init failed");
         goto fail2;
     }
     
-    BSignal_Capture();
-    
-    if (!BSignal_SetHandler(&reactor, signal_handler, NULL)) {
-        DEBUG("BSignal_SetHandler failed");
-        goto fail2;
-    }
-    
     if (!BDHCPClient_Init(&dhcp, ifname, &reactor, dhcp_handler, NULL)) {
         DEBUG("BDHCPClient_Init failed");
         goto fail3;
@@ -87,7 +80,7 @@ int main (int argc, char **argv)
     return ret;
     
 fail3:
-    BSignal_RemoveHandler();
+    BSignal_Finish();
 fail2:
     BReactor_Free(&reactor);
 fail1:
@@ -101,7 +94,7 @@ void terminate (int ret)
 {
     BDHCPClient_Free(&dhcp);
     
-    BSignal_RemoveHandler();
+    BSignal_Finish();
     
     BReactor_Quit(&reactor, ret);
 }

+ 3 - 10
examples/ipc_client.c

@@ -84,18 +84,11 @@ int main (int argc, char **argv)
         goto fail1;
     }
     
-    if (!BSignal_Init()) {
+    if (!BSignal_Init(&reactor, signal_handler, NULL)) {
         DEBUG("BSignal_Init failed");
         goto fail2;
     }
     
-    BSignal_Capture();
-    
-    if (!BSignal_SetHandler(&reactor, signal_handler, NULL)) {
-        DEBUG("BSignal_SetHandler failed");
-        goto fail2;
-    }
-    
     PacketPassInterface_Init(&recv_if, 0, ipc_recv_handler_send, NULL, BReactor_PendingGroup(&reactor));
     
     if (!BIPC_InitConnect(&ipc, path, SEND_MTU, &recv_if, ipc_handler, NULL, &reactor)) {
@@ -120,7 +113,7 @@ int main (int argc, char **argv)
     
 fail3:
     PacketPassInterface_Free(&recv_if);
-    BSignal_RemoveHandler();
+    BSignal_Finish();
 fail2:
     BReactor_Free(&reactor);
 fail1:
@@ -136,7 +129,7 @@ void terminate (int ret)
     
     PacketPassInterface_Free(&recv_if);
     
-    BSignal_RemoveHandler();
+    BSignal_Finish();
     
     BReactor_Quit(&reactor, ret);
     

+ 3 - 10
examples/ipc_server.c

@@ -77,18 +77,11 @@ int main (int argc, char **argv)
         goto fail1;
     }
     
-    if (!BSignal_Init()) {
+    if (!BSignal_Init(&reactor, signal_handler, NULL)) {
         DEBUG("BSignal_Init failed");
         goto fail2;
     }
     
-    BSignal_Capture();
-    
-    if (!BSignal_SetHandler(&reactor, signal_handler, NULL)) {
-        DEBUG("BSignal_SetHandler failed");
-        goto fail2;
-    }
-    
     if (!BIPCServer_Init(&server, path, server_handler, NULL, &reactor)) {
         DEBUG("BIPCServer_Init failed");
         goto fail3;
@@ -107,7 +100,7 @@ int main (int argc, char **argv)
     return ret;
     
 fail3:
-    BSignal_RemoveHandler();
+    BSignal_Finish();
 fail2:
     BReactor_Free(&reactor);
 fail1:
@@ -128,7 +121,7 @@ void signal_handler (void *user)
     
     BIPCServer_Free(&server);
     
-    BSignal_RemoveHandler();
+    BSignal_Finish();
     
     BReactor_Quit(&reactor, 1);
 }

+ 3 - 8
flooder/flooder.c

@@ -231,15 +231,10 @@ int main (int argc, char *argv[])
     }
     
     // setup signal handler
-    if (!BSignal_Init()) {
+    if (!BSignal_Init(&ss, signal_handler, NULL)) {
         BLog(BLOG_ERROR, "BSignal_Init failed");
         goto fail1a;
     }
-    BSignal_Capture();
-    if (!BSignal_SetHandler(&ss, signal_handler, NULL)) {
-        BLog(BLOG_ERROR, "BSignal_SetHandler failed");
-        goto fail1a;
-    }
     
     if (options.ssl) {
         // init NSPR
@@ -308,7 +303,7 @@ fail2:
         ASSERT_FORCE(PR_Cleanup() == PR_SUCCESS)
         PL_ArenaFinish();
     }
-    BSignal_RemoveHandler();
+    BSignal_Finish();
 fail1a:
     BReactor_Free(&ss);
 fail1:
@@ -377,7 +372,7 @@ void terminate (void)
     }
     
     // remove signal handler
-    BSignal_RemoveHandler();
+    BSignal_Finish();
     
     // kill dead variable
     DEAD_KILL(dead);

+ 3 - 8
ncd/ncd.c

@@ -251,15 +251,10 @@ int main (int argc, char **argv)
     }
     
     // setup signal handler
-    if (!BSignal_Init()) {
+    if (!BSignal_Init(&ss, signal_handler, NULL)) {
         BLog(BLOG_ERROR, "BSignal_Init failed");
         goto fail2;
     }
-    BSignal_Capture();
-    if (!BSignal_SetHandler(&ss, signal_handler, NULL)) {
-        BLog(BLOG_ERROR, "BSignal_SetHandler failed");
-        goto fail2;
-    }
     
     // read config file
     uint8_t *file;
@@ -297,7 +292,7 @@ int main (int argc, char **argv)
 fail5:
     NCDConfig_free_interfaces(configuration);
 fail3:
-    BSignal_RemoveHandler();
+    BSignal_Finish();
 fail2:
     BReactor_Free(&ss);
 fail1:
@@ -337,7 +332,7 @@ void terminate (void)
     NCDConfig_free_interfaces(configuration);
     
     // remove signal handler
-    BSignal_RemoveHandler();
+    BSignal_Finish();
     
     // exit reactor
     BReactor_Quit(&ss, 1);

+ 3 - 8
server/server.c

@@ -412,15 +412,10 @@ int main (int argc, char *argv[])
     }
     
     // setup signal handler
-    if (!BSignal_Init()) {
+    if (!BSignal_Init(&ss, signal_handler, NULL)) {
         BLog(BLOG_ERROR, "BSignal_Init failed");
         goto fail2a;
     }
-    BSignal_Capture();
-    if (!BSignal_SetHandler(&ss, signal_handler, NULL)) {
-        BLog(BLOG_ERROR, "BSignal_SetHandler failed");
-        goto fail2a;
-    }
     
     if (options.ssl) {
         // initialize NSPR
@@ -517,7 +512,7 @@ fail3:
         ASSERT_FORCE(PR_Cleanup() == PR_SUCCESS)
         PL_ArenaFinish();
     }
-    BSignal_RemoveHandler();
+    BSignal_Finish();
 fail2a:
     BReactor_Free(&ss);
 fail2:
@@ -627,7 +622,7 @@ void terminate (void)
     }
     
     // remove signal handler
-    BSignal_RemoveHandler();
+    BSignal_Finish();
     
     // free relay predicate
     if (options.relay_predicate) {

+ 56 - 180
system/BSignal.c

@@ -24,10 +24,7 @@
 #include <windows.h>
 #else
 #include <signal.h>
-#include <sys/signalfd.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
+#include <system/BUnixSignal.h>
 #endif
 
 #include <misc/debug.h>
@@ -37,25 +34,19 @@
 
 #include <generated/blog_channel_BSignal.h>
 
-#define EMPTY_SIGSET(_set) sigemptyset(&_set);
-#define FILL_SIGSET(_set) sigemptyset(&_set); sigaddset(&_set, SIGTERM); sigaddset(&_set, SIGINT);
-
 struct {
     int initialized;
-    int capturing;
+    int finished;
+    BReactor *reactor;
     BSignal_handler handler;
-    void *handler_user;
-    BReactor *handler_reactor;
+    void *user;
     #ifdef BADVPN_USE_WINAPI
     CRITICAL_SECTION handler_mutex; // mutex to make sure only one handler is working at a time
-    CRITICAL_SECTION state_mutex; // mutex for capturing and signal_pending
-    int signal_pending;
     HANDLE signal_sem1;
     HANDLE signal_sem2;
     BHandle bhandle;
     #else
-    int signal_fd;
-    BFileDescriptor bfd;
+    BUnixSignal signal;
     #endif
 } bsignal_global = {
     .initialized = 0,
@@ -66,34 +57,25 @@ struct {
 static void signal_handle_handler (void *user)
 {
     ASSERT(bsignal_global.initialized)
-    ASSERT(bsignal_global.capturing)
-    ASSERT(bsignal_global.handler)
+    ASSERT(!bsignal_global.finished)
     
-    ASSERT(bsignal_global.signal_pending)
-    bsignal_global.signal_pending = 0;
     ASSERT_FORCE(ReleaseSemaphore(bsignal_global.signal_sem2, 1, NULL))
     
     BLog(BLOG_DEBUG, "Dispatching signal");
-    bsignal_global.handler(bsignal_global.handler_user);
+    
+    // call handler
+    bsignal_global.handler(bsignal_global.user);
+    return;
 }
 
-static BOOL ctrl_handler (DWORD type)
+static BOOL WINAPI ctrl_handler (DWORD type)
 {
-    ASSERT(bsignal_global.initialized)
+    // don't check bsignal_global.initialized to avoid a race
     
     EnterCriticalSection(&bsignal_global.handler_mutex);
     
-    EnterCriticalSection(&bsignal_global.state_mutex);
-    if (bsignal_global.capturing) {
-        ASSERT(!bsignal_global.signal_pending)
-        bsignal_global.signal_pending = 1;
-        ASSERT_FORCE(ReleaseSemaphore(bsignal_global.signal_sem1, 1, NULL))
-        LeaveCriticalSection(&bsignal_global.state_mutex);
-        
-        ASSERT_FORCE(WaitForSingleObject(bsignal_global.signal_sem2, INFINITE) == WAIT_OBJECT_0)
-    } else {
-        LeaveCriticalSection(&bsignal_global.state_mutex);
-    }
+    ASSERT_FORCE(ReleaseSemaphore(bsignal_global.signal_sem1, 1, NULL))
+    ASSERT_FORCE(WaitForSingleObject(bsignal_global.signal_sem2, INFINITE) == WAIT_OBJECT_0)
     
     LeaveCriticalSection(&bsignal_global.handler_mutex);
     
@@ -102,44 +84,35 @@ static BOOL ctrl_handler (DWORD type)
 
 #else
 
-static void signal_fd_handler (void *user, int events)
+static void unix_signal_handler (void *user, struct BUnixSignal_siginfo siginfo)
 {
+    ASSERT(siginfo.signo == SIGTERM || siginfo.signo == SIGINT)
     ASSERT(bsignal_global.initialized)
-    ASSERT(bsignal_global.capturing)
-    ASSERT(bsignal_global.handler)
-    
-    struct signalfd_siginfo siginfo;
-    int bytes = read(bsignal_global.signal_fd, &siginfo, sizeof(siginfo));
-    if (bytes < 0) {
-        int error = errno;
-        if (error == EAGAIN || error == EWOULDBLOCK) {
-            return;
-        }
-        ASSERT_FORCE(0)
-    }
-    ASSERT_FORCE(bytes == sizeof(siginfo))
+    ASSERT(!bsignal_global.finished)
     
     BLog(BLOG_DEBUG, "Dispatching signal");
     
     // call handler
-    bsignal_global.handler(bsignal_global.handler_user);
+    bsignal_global.handler(bsignal_global.user);
     return;
 }
 
 #endif
 
-int BSignal_Init (void)
+int BSignal_Init (BReactor *reactor, BSignal_handler handler, void *user) 
 {
     ASSERT(!bsignal_global.initialized)
     
+    // init arguments
+    bsignal_global.reactor = reactor;
+    bsignal_global.handler = handler;
+    bsignal_global.user = user;
+    
     BLog(BLOG_DEBUG, "BSignal initializing");
     
     #ifdef BADVPN_USE_WINAPI
     
     InitializeCriticalSection(&bsignal_global.handler_mutex);
-    InitializeCriticalSection(&bsignal_global.state_mutex);
-    
-    bsignal_global.signal_pending = 0;
     
     if (!(bsignal_global.signal_sem1 = CreateSemaphore(NULL, 0, 1, NULL))) {
         BLog(BLOG_ERROR, "CreateSemaphore failed");
@@ -151,168 +124,71 @@ int BSignal_Init (void)
         goto fail2;
     }
     
+    // init BHandle
     BHandle_Init(&bsignal_global.bhandle, bsignal_global.signal_sem1, signal_handle_handler, NULL);
+    if (!BReactor_AddHandle(bsignal_global.reactor, &bsignal_global.bhandle)) {
+        BLog(BLOG_ERROR, "BReactor_AddHandle failed");
+        goto fail3;
+    }
+    BReactor_EnableHandle(bsignal_global.reactor, &bsignal_global.bhandle);
+    
+    // configure ctrl handler
+    if (!SetConsoleCtrlHandler(ctrl_handler, TRUE)) {
+        BLog(BLOG_ERROR, "SetConsoleCtrlHandler failed");
+        goto fail4;
+    }
     
     #else
     
-    // create signalfd fd
-    sigset_t emptyset;
-    FILL_SIGSET(emptyset)
-    if ((bsignal_global.signal_fd = signalfd(-1, &emptyset, 0)) < 0) {
-        BLog(BLOG_ERROR, "signalfd failed");
-        goto fail0;
-    }
+    sigset_t sset;
+    ASSERT_FORCE(sigemptyset(&sset) == 0)
+    ASSERT_FORCE(sigaddset(&sset, SIGTERM) == 0)
+    ASSERT_FORCE(sigaddset(&sset, SIGINT) == 0)
     
-    // set non-blocking
-    if (fcntl(bsignal_global.signal_fd, F_SETFL, O_NONBLOCK) < 0) {
-        DEBUG("cannot set non-blocking");
-        goto fail1;
+    // init BUnixSignal
+    if (!BUnixSignal_Init(&bsignal_global.signal, bsignal_global.reactor, sset, unix_signal_handler, NULL)) {
+        BLog(BLOG_ERROR, "BUnixSignal_Init failed");
+        goto fail0;
     }
     
-    // init BFileDescriptor
-    BFileDescriptor_Init(&bsignal_global.bfd, bsignal_global.signal_fd, signal_fd_handler, NULL);
-    
     #endif
     
-    bsignal_global.capturing = 0;
     bsignal_global.initialized = 1;
+    bsignal_global.finished = 0;
     
     return 1;
     
     #ifdef BADVPN_USE_WINAPI
+fail4:
+    BReactor_RemoveHandle(bsignal_global.reactor, &bsignal_global.bhandle);
+fail3:
+    ASSERT_FORCE(CloseHandle(bsignal_global.signal_sem2))
 fail2:
     ASSERT_FORCE(CloseHandle(bsignal_global.signal_sem1))
 fail1:
-    DeleteCriticalSection(&bsignal_global.state_mutex);
     DeleteCriticalSection(&bsignal_global.handler_mutex);
-    #else
-fail1:
-    ASSERT_FORCE(close(bsignal_global.signal_fd) == 0)
     #endif
     
 fail0:
     return 0;
 }
 
-void BSignal_Capture (void)
-{
-    ASSERT(bsignal_global.initialized)
-    ASSERT(!bsignal_global.capturing)
-    
-    BLog(BLOG_DEBUG, "BSignal capturing");
-    
-    #ifdef BADVPN_USE_WINAPI
-    
-    ASSERT(!bsignal_global.signal_pending)
-    
-    EnterCriticalSection(&bsignal_global.state_mutex);
-    bsignal_global.capturing = 1;
-    LeaveCriticalSection(&bsignal_global.state_mutex);
-    ASSERT_FORCE(SetConsoleCtrlHandler((PHANDLER_ROUTINE)ctrl_handler, TRUE))
-    
-    #else
-    
-    sigset_t signals;
-    FILL_SIGSET(signals)
-    ASSERT_FORCE(sigprocmask(SIG_BLOCK, &signals, NULL) == 0)
-    
-    bsignal_global.capturing = 1;
-    
-    #endif
-    
-    bsignal_global.handler = NULL;
-}
-
-void BSignal_Uncapture (void)
-{
-    ASSERT(bsignal_global.initialized)
-    ASSERT(bsignal_global.capturing)
-    ASSERT(!bsignal_global.handler)
-    
-    BLog(BLOG_DEBUG, "BSignal uncapturing");
-    
-    #ifdef BADVPN_USE_WINAPI
-    
-    ASSERT_FORCE(SetConsoleCtrlHandler(NULL, FALSE))
-    EnterCriticalSection(&bsignal_global.state_mutex);
-    
-    if (bsignal_global.signal_pending) {
-        bsignal_global.signal_pending = 0;
-        // consume sem1 which the handler incremented to prevent
-        // the event loop from reacting to the signal
-        ASSERT_FORCE(WaitForSingleObject(bsignal_global.signal_sem1, INFINITE) == WAIT_OBJECT_0)
-        // allow the handler to return
-        // no need to wait for it; it only waits on sem2, which nothing else
-        // needs until it returns
-        ASSERT_FORCE(ReleaseSemaphore(bsignal_global.signal_sem2, 1, NULL))
-    }
-    
-    #else
-    
-    sigset_t signals;
-    FILL_SIGSET(signals)
-    ASSERT_FORCE(sigprocmask(SIG_UNBLOCK, &signals, NULL) == 0)
-    
-    #endif
-    
-    bsignal_global.capturing = 0;
-    
-    #ifdef BADVPN_USE_WINAPI
-    
-    LeaveCriticalSection(&bsignal_global.state_mutex);
-    
-    #endif
-}
-
-int BSignal_SetHandler (BReactor *reactor, BSignal_handler handler, void *user)
-{
-    ASSERT(bsignal_global.initialized)
-    ASSERT(bsignal_global.capturing)
-    ASSERT(!bsignal_global.handler)
-    ASSERT(handler)
-    
-    #ifdef BADVPN_USE_WINAPI
-    
-    if (!BReactor_AddHandle(reactor, &bsignal_global.bhandle)) {
-        BLog(BLOG_ERROR, "BReactor_AddHandle failed");
-        return 0;
-    }
-    
-    BReactor_EnableHandle(reactor, &bsignal_global.bhandle);
-    
-    #else
-    
-    if (!BReactor_AddFileDescriptor(reactor, &bsignal_global.bfd)) {
-        BLog(BLOG_ERROR, "BReactor_AddFileDescriptor failed");
-        return 0;
-    }
-    
-    BReactor_SetFileDescriptorEvents(reactor, &bsignal_global.bfd, BREACTOR_READ);
-    
-    #endif
-    
-    bsignal_global.handler = handler;
-    bsignal_global.handler_user = user;
-    bsignal_global.handler_reactor = reactor;
-    
-    return 1;
-}
-
-void BSignal_RemoveHandler (void)
+void BSignal_Finish (void)
 {
     ASSERT(bsignal_global.initialized)
-    ASSERT(bsignal_global.capturing)
-    ASSERT(bsignal_global.handler)
+    ASSERT(!bsignal_global.finished)
     
     #ifdef BADVPN_USE_WINAPI
     
-    BReactor_RemoveHandle(bsignal_global.handler_reactor, &bsignal_global.bhandle);
+    // free BHandle
+    BReactor_RemoveHandle(bsignal_global.reactor, &bsignal_global.bhandle);
     
     #else
     
-    BReactor_RemoveFileDescriptor(bsignal_global.handler_reactor, &bsignal_global.bfd);
+    // free BUnixSignal
+    BUnixSignal_Free(&bsignal_global.signal, 0);
     
     #endif
     
-    bsignal_global.handler = NULL;
+    bsignal_global.finished = 1;
 }

+ 5 - 29
system/BSignal.h

@@ -37,41 +37,17 @@ typedef void (*BSignal_handler) (void *user);
  * The object is created in not capturing state.
  * {@link BLog_Init} must have been done.
  *
- * @return 1 on success, 0 on failure
- */
-int BSignal_Init (void) WARN_UNUSED;
-
-/**
- * Starts capturing signals.
- * The object must be in not capturing state.
- * The object enters capturing state.
- */
-void BSignal_Capture (void);
-
-/**
- * Stops capturing signals.
- * The object must be in capturing state.
- * A signal handler must not be configured.
- * The object enters not capturing state.
- */
-void BSignal_Uncapture (void);
-
-/**
- * Configures a reactor and a handler for signals.
- * The object must be in capturing state.
- * A handler must not be already configured.
- *
  * @param reactor {@link BReactor} from which the handler will be called
  * @param handler callback function invoked from the reactor
  * @param user value passed to callback function
- * @return 1 on success, 0 on failure.
+ * @return 1 on success, 0 on failure
  */
-int BSignal_SetHandler (BReactor *reactor, BSignal_handler handler, void *user) WARN_UNUSED;
+int BSignal_Init (BReactor *reactor, BSignal_handler handler, void *user) WARN_UNUSED;
 
 /**
- * Deconfigures a signal reactor and handler.
- * A handler must be configured.
+ * Finishes signal handling.
+ * {@link BSignal_Init} must not be called again.
  */
-void BSignal_RemoveHandler (void);
+void BSignal_Finish (void);
 
 #endif

+ 3 - 8
tun2socks/tun2socks.c

@@ -268,15 +268,10 @@ int main (int argc, char **argv)
     quitting = 0;
     
     // setup signal handler
-    if (!BSignal_Init()) {
+    if (!BSignal_Init(&ss, signal_handler, NULL)) {
         BLog(BLOG_ERROR, "BSignal_Init failed");
         goto fail2;
     }
-    BSignal_Capture();
-    if (!BSignal_SetHandler(&ss, signal_handler, NULL)) {
-        BLog(BLOG_ERROR, "BSignal_SetHandler failed");
-        goto fail2;
-    }
     
     // init TUN device
     if (!BTap_Init(&device, &ss, options.tundev, device_error_handler, NULL, 1)) {
@@ -334,7 +329,7 @@ fail4:
     PacketPassInterface_Free(&device_read_interface);
     BTap_Free(&device);
 fail3:
-    BSignal_RemoveHandler();
+    BSignal_Finish();
 fail2:
     BReactor_Free(&ss);
 fail1:
@@ -407,7 +402,7 @@ void terminate (void)
     BTap_Free(&device);
     
     // remove signal handler
-    BSignal_RemoveHandler();
+    BSignal_Finish();
     
     // set quitting
     quitting = 1;