diff --git a/src/logger.c b/src/logger.c
index 2defb239..8fbd3448 100644
--- a/src/logger.c
+++ b/src/logger.c
@@ -37,7 +37,7 @@ static HANDLE loghandle = NULL;
 #endif
 static const char *logident = NULL;
 bool logcontrol = false;
-
+int umbilical = 0;
 
 static void real_logger(int level, int priority, const char *message) {
 	char timestr[32] = "";
@@ -79,6 +79,11 @@ static void real_logger(int level, int priority, const char *message) {
 			case LOGMODE_NULL:
 				break;
 		}
+
+		if(umbilical) {
+			write(umbilical, message, strlen(message));
+			write(umbilical, "\n", 1);
+		}
 	}
 
 	if(logcontrol) {
diff --git a/src/logger.h b/src/logger.h
index 8f690290..252497bf 100644
--- a/src/logger.h
+++ b/src/logger.h
@@ -69,6 +69,7 @@ enum {
 
 extern debug_t debug_level;
 extern bool logcontrol;
+extern int umbilical;
 extern void openlogger(const char *, logmode_t);
 extern void reopenlogger(void);
 extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4)));
diff --git a/src/tincctl.c b/src/tincctl.c
index 46bf5bd5..c6d4aac5 100644
--- a/src/tincctl.c
+++ b/src/tincctl.c
@@ -853,6 +853,13 @@ static int cmd_start(int argc, char *argv[]) {
 	}
 	return status;
 #else
+	int pfd[2] = {-1, -1};
+	if(pipe(pfd)) {
+		fprintf(stderr, "Could not create umbilical pipe: %s\n", strerror(errno));
+		free(nargv);
+		return 1;
+	}
+
 	pid_t pid = fork();
 	if(pid == -1) {
 		fprintf(stderr, "Could not fork: %s\n", strerror(errno));
@@ -860,8 +867,15 @@ static int cmd_start(int argc, char *argv[]) {
 		return 1;
 	}
 
-	if(!pid)
+	if(!pid) {
+		close(pfd[0]);
+		char buf[100] = "";
+		snprintf(buf, sizeof buf, "%d", pfd[1]);
+		setenv("TINC_UMBILICAL", buf, true);
 		exit(execvp(c, nargv));
+	} else {
+		close(pfd[1]);
+	}
 
 	free(nargv);
 
@@ -869,12 +883,33 @@ static int cmd_start(int argc, char *argv[]) {
 #ifdef SIGINT
 	signal(SIGINT, SIG_IGN);
 #endif
+
+	// Pass all log messages from the umbilical to stderr.
+	// A nul-byte right before closure means tincd started succesfully.
+	bool failure = true;
+	char buf[1024];
+	ssize_t len;
+
+	while((len = read(pfd[0], buf, sizeof buf)) > 0) {
+		failure = buf[len - 1];
+		if(!failure)
+			len--;
+		write(2, buf, len);
+	}
+
+	if(len)
+		failure = true;
+
+	close(pfd[0]);
+
+	// Make sure the child process is really gone.
 	result = waitpid(pid, &status, 0);
+
 #ifdef SIGINT
 	signal(SIGINT, SIG_DFL);
 #endif
 
-	if(result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) {
+	if(failure || result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) {
 		fprintf(stderr, "Error starting %s\n", c);
 		return 1;
 	}
diff --git a/src/tincd.c b/src/tincd.c
index fb2a1557..b62c8c19 100644
--- a/src/tincd.c
+++ b/src/tincd.c
@@ -363,6 +363,14 @@ int main(int argc, char **argv) {
 		logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
 		return 1;
 	}
+#else
+	// Check if we got an umbilical fd from the process that started us
+	char *umbstr = getenv("TINC_UMBILICAL");
+	if(umbstr) {
+		umbilical = atoi(umbstr);
+		if(fcntl(umbilical, F_GETFL) < 0)
+			umbilical = 0;
+	}
 #endif
 
 	openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR);
@@ -466,6 +474,12 @@ int main2(int argc, char **argv) {
 
 	logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready");
 
+	if(umbilical) { // snip!
+		write(umbilical, "", 1);
+		close(umbilical);
+		umbilical = 0;
+	}
+
 	try_outgoing_connections();
 
 	status = main_loop();