Skip to content

Commit 962241d

Browse files
committed
test: implement launchTarantool for non-Linux platforms
Function launchTarantool creates a process, which is killed when the parent process is dead. Since it uses prctl, it works only on Linux - on other platforms Tarantool is not killed and ctest hangs. Let's add POSIX-compatible implementation of launchTarantool for non-Linux platforms.
1 parent 139e766 commit 962241d

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

test/Utils/System.hpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ set_parent_death_signal(pid_t ppid_before_fork, const char *child_program_name)
6262
}
6363
}
6464

65+
#ifdef __linux__
66+
6567
inline int
6668
launchTarantool(bool enable_ssl = false)
6769
{
@@ -85,6 +87,64 @@ launchTarantool(bool enable_ssl = false)
8587
exit(EXIT_FAILURE);
8688
}
8789

90+
#else
91+
92+
/**
93+
* Launches intermediate process, connected with parent by pipe.
94+
* The intermediate process lauches another process, running tarantool, and then
95+
* falls asleep on reading from pipe. When parent process is dead, the pipe
96+
* will be closed, and the intermediate process will read EOF. Right after, it
97+
* will kill its child process, which is Tarantool, and exit.
98+
* In the case, when the intermediate process fails to fork Tarantool, it kills
99+
* the parent process and terminates.
100+
*/
101+
inline int
102+
launchTarantool(bool enable_ssl = false)
103+
{
104+
pid_t ppid_before_fork = getpid();
105+
int p[2];
106+
pipe(p);
107+
pid_t pid = fork();
108+
if (pid == -1) {
109+
fprintf(stderr, "Can't launch Tarantool: fork failed! %s",
110+
strerror(errno));
111+
return -1;
112+
}
113+
/* Returning from parent. */
114+
if (pid != 0)
115+
return 0;
116+
117+
/*
118+
* It is necessary to close write end of pipe here if we want to read
119+
* EOF when the parent process is dead.
120+
*/
121+
close(p[1]);
122+
pid = fork();
123+
if (pid == -1) {
124+
/*
125+
* We've already returned OK in the parent, so let's kill it if
126+
* the intermediate process fails to fork Tarantool.
127+
*/
128+
kill(ppid_before_fork, SIGKILL);
129+
exit(EXIT_FAILURE);
130+
}
131+
if (pid == 0) {
132+
close(p[0]);
133+
const char *script = enable_ssl ? "test_cfg_ssl.lua" : "test_cfg.lua";
134+
if (execlp("tarantool", "tarantool", script, NULL) == -1) {
135+
fprintf(stderr, "Can't launch Tarantool: execlp failed! %s\n",
136+
strerror(errno));
137+
kill(getppid(), SIGKILL);
138+
}
139+
}
140+
char buf[1];
141+
read(p[0], buf, 1);
142+
kill(pid, SIGTERM);
143+
exit(0);
144+
}
145+
146+
#endif
147+
88148
inline int
89149
cleanDir() {
90150
pid_t pid = fork();

0 commit comments

Comments
 (0)