Use a pipe() to synchronize the server initialization

As the signals are intercepted by debuggers.
This commit is contained in:
Thiago Marcos P. Santos
2015-06-18 15:48:39 +03:00
parent 22acc2f14c
commit ac4179e7de
3 changed files with 29 additions and 5 deletions

View File

@@ -4,27 +4,51 @@
#include <csignal>
#include <unistd.h>
namespace mbgl {
namespace test {
pid_t startServer(const char *executable) {
const std::string parent_pid = std::to_string(getpid());
int pipefd[2];
if (pipe(pipefd)) {
throw std::runtime_error("Cannot create server pipe");
}
pid_t pid = fork();
if (pid < 0) {
throw std::runtime_error("Cannot create server process");
} else if (pid == 0) {
close(STDIN_FILENO);
if (dup(pipefd[1])) {
Log::Error(Event::Setup, "Failed to start server: %s", strerror(errno));
}
close(pipefd[0]);
close(pipefd[1]);
char *args[] = { const_cast<char *>(executable),
const_cast<char *>(parent_pid.c_str()),
nullptr };
int ret = execv(executable, args);
// This call should not return. In case execve failed, we exit anyway.
if (ret < 0) {
Log::Error(Event::Setup, "failed to start server: %s", strerror(errno));
Log::Error(Event::Setup, "Failed to start server: %s", strerror(errno));
}
exit(0);
} else {
// Wait until the server process sends SIGCONT.
raise(SIGSTOP);
char buffer[8];
// Wait until the server process sends something on the pipe.
if (!read(pipefd[0], buffer, sizeof(buffer))) {
throw std::runtime_error("Error reading a message from the server");
}
close(pipefd[0]);
close(pipefd[1]);
}
return pid;
}

View File

@@ -14,6 +14,6 @@ var server = app.listen(2900, function () {
if (process.argv[2]) {
// Allow the test to continue running.
process.kill(+process.argv[2], 'SIGCONT');
process.stdin.write("Go!\n");
}
});

View File

@@ -103,6 +103,6 @@ var server = app.listen(3000, function () {
if (process.argv[2]) {
// Allow the test to continue running.
process.kill(+process.argv[2], 'SIGCONT');
process.stdin.write("Go!\n");
}
});