}
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));
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);
#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;
}
if(!parse_options(argc, argv))
return 1;
- make_names();
+ make_names(false);
xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase);
xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase);