diff --git a/gw/bearerbox.c b/gw/bearerbox.c
index 4325cdf..ffb04b3 100644
--- a/gw/bearerbox.c
+++ b/gw/bearerbox.c
@@ -791,10 +791,12 @@ int main(int argc, char **argv)
     cfg_destroy(cfg);
     octstr_destroy(cfg_filename);
     dlr_shutdown();
-    gwlib_shutdown();
 
-    if (restart == 1)
-        execvp(argv[0],argv);
+    /* now really restart */
+    if (restart)
+        restart_box(argv);
+
+    gwlib_shutdown();
 
     return 0;
 }
diff --git a/gw/shared.c b/gw/shared.c
index 42dd607..b7bb9df 100644
--- a/gw/shared.c
+++ b/gw/shared.c
@@ -60,6 +60,7 @@
  * Lars Wirzenius
  */
 
+#include <errno.h>
 #include <libxml/xmlversion.h>
 
 #include "gwlib/gwlib.h"
@@ -274,3 +275,21 @@ error:
     return NULL;
 }
 
+int restart_box(char **argv)
+{
+    int rc;
+
+    if (!(rc = fork())) {
+        /*
+         * Sleep a while in order to get father
+         * process time to cleanup things
+         */
+        gwthread_sleep(1.0);
+        if (execvp(argv[0],argv) == -1)
+            error(errno, "Unable to start new process.");
+    } else if (rc == -1)
+        error(errno, "Could not restart, exiting...");
+
+    return rc == -1 ? -1 : 0;
+}
+
diff --git a/gw/shared.h b/gw/shared.h
index 855b32c..8665aaf 100644
--- a/gw/shared.h
+++ b/gw/shared.h
@@ -130,6 +130,11 @@ int deliver_to_bearerbox(Msg *msg);
 Octstr *parse_date(Octstr *date);
 
 
+/*
+ * Restarts process with a given params
+ */
+int restart_box(char **argv);
+
 #endif
 
 
diff --git a/gw/smsbox.c b/gw/smsbox.c
index 2968061..e7f11db 100644
--- a/gw/smsbox.c
+++ b/gw/smsbox.c
@@ -242,9 +242,12 @@ static void read_messages_from_bearerbox(void)
     while (program_status != shutting_down) {
         /* block infinite for reading messages */
         ret = read_from_bearerbox(&msg, INFINITE_TIME);
-        if (ret == -1)
+        if (ret == -1) {
+            error(0, "Bearerbox is gone, restarting");
+            program_status = shutting_down;
+            restart = 1;
             break;
-        else if (ret == 1) /* timeout */
+        } else if (ret == 1) /* timeout */
             continue;
         else if (msg == NULL) /* just to be sure, may not happens */
             break;
@@ -3618,15 +3621,13 @@ int main(int argc, char **argv)
      * Otherwise we will fail while trying to connect to bearerbox!
      */
     if (restart) {
-        gwthread_sleep(5.0);
+        gwthread_sleep(10.0);
+        /* now really restart */
+        restart_box(argv);
     }
 
     gwlib_shutdown();
 
-    /* now really restart */
-    if (restart)
-        execvp(argv[0], argv);
-
     return 0;
 }
 
diff --git a/gw/wapbox.c b/gw/wapbox.c
index 9688886..988bf43 100644
--- a/gw/wapbox.c
+++ b/gw/wapbox.c
@@ -775,9 +775,12 @@ int main(int argc, char **argv)
 
         /* block infinite for reading messages */
         ret = read_from_bearerbox(&msg, INFINITE_TIME);
-        if (ret == -1)
+        if (ret == -1) {
+            error(0, "Bearerbox is gone, restarting");
+            program_status = shutting_down;
+            restart = 1;
             break;
-        else if (ret == 1) /* timeout */
+        } else if (ret == 1) /* timeout */
             continue;
         else if (msg == NULL) /* just to be sure, may not happens */
             break;
@@ -861,15 +864,13 @@ int main(int argc, char **argv)
      * Otherwise we will fail while trying to connect to bearerbox!
      */
     if (restart) {
-        gwthread_sleep(5.0);
+        gwthread_sleep(10.0);
+        /* now really restart */
+        restart_box(argv);
     }
 
     gwlib_shutdown();
 
-    /* now really restart */
-    if (restart)
-        execvp(argv[0], argv);
-
     return 0;
 }
 
diff --git a/gwlib/gwlib.c b/gwlib/gwlib.c
index c74c009..b3e8448 100644
--- a/gwlib/gwlib.c
+++ b/gwlib/gwlib.c
@@ -107,3 +107,9 @@ void gwlib_shutdown(void)
     gwmem_shutdown();
     init = 0;
 }
+
+int gwlib_initialized(void)
+{
+    return init;
+}
+
diff --git a/gwlib/gwlib.h b/gwlib/gwlib.h
index 7830371..3f4f2e5 100644
--- a/gwlib/gwlib.h
+++ b/gwlib/gwlib.h
@@ -107,6 +107,7 @@
 void gwlib_assert_init(void);
 void gwlib_init(void);
 void gwlib_shutdown(void);
+int gwlib_initialized(void);
 
 #ifdef NO_GWASSERT
 #define gwlib_assert_init() ((void) 0)
diff --git a/gwlib/utils.c b/gwlib/utils.c
index 35fc8c3..c5a774a 100644
--- a/gwlib/utils.c
+++ b/gwlib/utils.c
@@ -103,6 +103,8 @@
 
 /* pid of child process when parachute is used */
 static pid_t child_pid = -1;
+/* pid of pid file owner */
+static pid_t pidfile_owner_pid = -1;
 /* saved child signal handlers */
 static struct sigaction child_actions[32];
 /* just a flag that child signal handlers are stored */
@@ -350,7 +352,7 @@ static void write_pid_file(void)
     if (!file)
         panic(errno, "Could not open file-stream `%s'", pid_file);
 
-    fprintf(file, "%ld\n", (long) getpid());
+    fprintf(file, "%ld\n", (long) (pidfile_owner_pid = getpid()));
     fclose(file);
 }
 
@@ -359,12 +361,21 @@ static void remove_pid_file(void)
     if (!pid_file)
         return;
 
-    /* ensure we don't called from child process */
-    if (child_pid == 0)
+    /* ensure that only pidfile owner can remove it */
+    if (pidfile_owner_pid != getpid())
         return;
 
-    if (-1 == unlink(pid_file))
+    if (-1 == unlink(pid_file)) {
+        int initdone = gwlib_initialized();
+        /* we are called at exit so gwlib may be shutdown already, init again */
+        if (!initdone) {
+            gwlib_init();
+            log_set_syslog("kannel", 0);
+        }
         error(errno, "Could not unlink pid-file `%s'", pid_file);
+        if (!initdone)
+            gwlib_shutdown();
+    }
 }
 
 
