diff --git a/include/tarantool_pthread.h b/include/tarantool_pthread.h
index e1f781dd525f458c238ca19054b185ae8c6e47a7..41094a031a8fe493fed88bdab1144d1583e30d95 100644
--- a/include/tarantool_pthread.h
+++ b/include/tarantool_pthread.h
@@ -149,5 +149,10 @@
 	tt_pthread_error(e);			\
 })
 
+#define tt_pthread_atfork(prepare, parent, child)\
+({	int e = pthread_atfork(prepare, parent, child);\
+	tt_pthread_error(e);			\
+})
+
 
 #endif /* TARANTOOL_PTHREAD_H_INCLUDED */
diff --git a/src/log_io.m b/src/log_io.m
index ac1ef27c48a1e2484dcce0a6fe899c2c6005dcae..684842164a11c8345f4cc7643a7aaf62c3a4dbce 100644
--- a/src/log_io.m
+++ b/src/log_io.m
@@ -1254,7 +1254,7 @@ wal_writer_child()
 static void
 wal_writer_init_once()
 {
-	pthread_atfork(NULL, NULL, wal_writer_child);
+	tt_pthread_atfork(NULL, NULL, wal_writer_child);
 }
 
 /**
diff --git a/src/tarantool.m b/src/tarantool.m
index 8df1136927471dae6fa4d9dcc7a6e78b57600c70..b9a397193ef586790514b3d355bc246a0fab9f0d 100644
--- a/src/tarantool.m
+++ b/src/tarantool.m
@@ -57,6 +57,7 @@
 #include <util.h>
 #include <third_party/gopt/gopt.h>
 #include <cfg/warning.h>
+#include "tarantool_pthread.h"
 
 
 static pid_t master_pid;
@@ -277,7 +278,8 @@ snapshot(void *ev, int events __attribute__((unused)))
 		 */
 		wait_for_child(p);
 		assert(p == fiber->cw.rpid);
-		return WEXITSTATUS(fiber->cw.rstatus);
+		return (WIFSIGNALED(fiber->cw.rstatus) ? EINTR :
+			WEXITSTATUS(fiber->cw.rstatus));
 	}
 
 	fiber_set_name(fiber, "dumper");
@@ -312,6 +314,31 @@ signal_free(void)
 		ev_signal_stop(&sigs[i]);
 }
 
+/** Make sure the child has a default signal disposition. */
+static void
+signal_reset()
+{
+	struct sigaction sa;
+
+	/* Reset all signals to their defaults. */
+	memset(&sa, 0, sizeof(sa));
+	sigemptyset(&sa.sa_mask);
+	sa.sa_handler = SIG_DFL;
+
+	if (sigaction(SIGUSR1, &sa, NULL) == -1 ||
+	    sigaction(SIGINT, &sa, NULL) == -1 ||
+	    sigaction(SIGTERM, &sa, NULL) == -1 ||
+	    sigaction(SIGHUP, &sa, NULL) == -1)
+		say_syserror("sigaction");
+
+	/* Unblock any signals blocked by libev. */
+	sigset_t sigset;
+	sigfillset(&sigset);
+	if (sigprocmask(SIG_UNBLOCK, &sigset, NULL) == -1)
+		say_syserror("sigprocmask");
+}
+
+
 /**
  * Adjust the process signal mask and add handlers for signals.
  */
@@ -341,6 +368,7 @@ signal_init(void)
 	ev_signal_start(&sigs[3]);
 
 	atexit(signal_free);
+	tt_pthread_atfork(NULL, NULL, signal_reset);
 }
 
 static void