summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
7f96ef0)
We do this by creating an umbilical between the CLI and the daemon. The
daemon pipes log messages to the CLI until it starts the main loop. The
daemon then cuts the umbilical. The CLI copies all the received log
messages to stderr, and the last byte indicates whether the daemon
started succesfully or not, so the CLI can exit with a useful exit code.
#endif
static const char *logident = NULL;
bool logcontrol = false;
#endif
static const char *logident = NULL;
bool logcontrol = false;
static void real_logger(int level, int priority, const char *message) {
char timestr[32] = "";
static void real_logger(int level, int priority, const char *message) {
char timestr[32] = "";
case LOGMODE_NULL:
break;
}
case LOGMODE_NULL:
break;
}
+
+ if(umbilical) {
+ write(umbilical, message, strlen(message));
+ write(umbilical, "\n", 1);
+ }
extern debug_t debug_level;
extern bool logcontrol;
extern debug_t debug_level;
extern bool logcontrol;
extern void openlogger(const char *, logmode_t);
extern void reopenlogger(void);
extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4)));
extern void openlogger(const char *, logmode_t);
extern void reopenlogger(void);
extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4)));
+ 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));
pid_t pid = fork();
if(pid == -1) {
fprintf(stderr, "Could not fork: %s\n", strerror(errno));
+ if(!pid) {
+ close(pfd[0]);
+ char buf[100] = "";
+ snprintf(buf, sizeof buf, "%d", pfd[1]);
+ setenv("TINC_UMBILICAL", buf, true);
+ } else {
+ close(pfd[1]);
+ }
#ifdef SIGINT
signal(SIGINT, SIG_IGN);
#endif
#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);
result = waitpid(pid, &status, 0);
#ifdef SIGINT
signal(SIGINT, SIG_DFL);
#endif
#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;
}
fprintf(stderr, "Error starting %s\n", c);
return 1;
}
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
return 1;
}
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);
#endif
openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR);
logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready");
logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready");
+ if(umbilical) { // snip!
+ write(umbilical, "", 1);
+ close(umbilical);
+ umbilical = 0;
+ }
+
try_outgoing_connections();
status = main_loop();
try_outgoing_connections();
status = main_loop();