/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
-#include "lib-signals.h"
#include "str.h"
#include "llist.h"
#include "array.h"
#endif
#include "connection.h"
#include "test-common.h"
+#include "test-subprocess.h"
#include "smtp-server.h"
#include "smtp-client.h"
#include "smtp-client-connection.h"
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/wait.h>
-#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#define CLIENT_PROGRESS_TIMEOUT 30
+#define SERVER_KILL_TIMEOUT_SECS 20
#define MAX_PARALLEL_PENDING 200
static bool debug = FALSE;
static struct ip_addr bind_ip;
static in_port_t bind_port = 0;
static int fd_listen = -1;
-static pid_t server_pid = (pid_t)-1;
+
+static void main_deinit(void);
/*
* Test files
* Tests
*/
+struct test_server_data {
+ const struct smtp_server_settings *set;
+};
+
static void test_open_server_fd(void)
{
if (fd_listen != -1)
net_set_nonblock(fd_listen, TRUE);
}
-static void test_server_kill_forced(void)
-{
- if (server_pid != (pid_t)-1) {
- (void)kill(server_pid, SIGKILL);
- (void)waitpid(server_pid, NULL, 0);
- }
- server_pid = (pid_t)-1;
-}
-
-static void test_run_server(struct smtp_server_settings *server_set)
+static int test_run_server(struct test_server_data *data)
{
+ const struct smtp_server_settings *server_set = data->set;
struct ioloop *ioloop;
i_set_failure_prefix("SERVER: ");
i_close_fd(&fd_listen);
test_files_deinit();
+ main_deinit();
+ return 0;
}
static void
io_loop_run(ioloop);
test_client_deinit();
io_loop_destroy(&ioloop);
+
+ if (debug)
+ i_debug("Terminated");
}
static void
void (*client_init)(enum smtp_protocol protocol,
const struct smtp_client_settings *client_set))
{
+ struct test_server_data data;
+
if (test_ssl_mode == TEST_SSL_MODE_STARTTLS)
server_set->capabilities |= SMTP_CAPABILITY_STARTTLS;
failure = NULL;
- test_open_server_fd();
-
- test_files_init();
-
- lib_signals_ioloop_detach();
- if ((server_pid = fork()) == (pid_t)-1)
- i_fatal("fork() failed: %m");
- if (server_pid == 0) {
- server_pid = (pid_t)-1;
- hostpid_init();
- lib_signals_deinit();
+ i_zero(&data);
+ data.set = server_set;
- /* child: server */
- test_run_server(server_set);
+ test_files_init();
- lib_deinit();
- exit(1);
- }
+ /* Fork server */
+ test_open_server_fd();
+ test_subprocess_fork(test_run_server, &data, FALSE);
i_close_fd(&fd_listen);
- lib_signals_ioloop_attach();
-
- /* parent: client */
+ /* Run client */
test_run_client(protocol, client_set, client_init);
i_unset_failure_prefix();
bind_port = 0;
- test_server_kill_forced();
+ test_subprocess_kill_all(SERVER_KILL_TIMEOUT_SECS);
test_files_deinit();
}
* Main
*/
-volatile sig_atomic_t terminating = 0;
-
-static void test_signal_handler(const siginfo_t *si, void *context ATTR_UNUSED)
-{
- int signo = si->si_signo;
-
- if (terminating != 0)
- raise(signo);
- terminating = 1;
-
- /* make sure we don't leave any pesky children alive */
- test_server_kill_forced();
-
- (void)signal(signo, SIG_DFL);
- raise(signo);
-}
-
-static void test_atexit(void)
-{
- test_server_kill_forced();
-}
-
static void main_init(void)
{
- lib_signals_init();
#ifdef HAVE_OPENSSL
ssl_iostream_openssl_init();
#endif
-
- atexit(test_atexit);
- lib_signals_ignore(SIGPIPE, TRUE);
- lib_signals_set_handler(SIGTERM, 0, test_signal_handler, NULL);
- lib_signals_set_handler(SIGQUIT, 0, test_signal_handler, NULL);
- lib_signals_set_handler(SIGINT, 0, test_signal_handler, NULL);
- lib_signals_set_handler(SIGSEGV, 0, test_signal_handler, NULL);
- lib_signals_set_handler(SIGABRT, 0, test_signal_handler, NULL);
}
static void main_deinit(void)
#ifdef HAVE_OPENSSL
ssl_iostream_openssl_deinit();
#endif
- lib_signals_deinit();
}
int main(int argc, char *argv[])
}
}
+ test_subprocesses_init(debug);
+
/* listen on localhost */
i_zero(&bind_ip);
bind_ip.family = AF_INET;
ret = test_run(test_functions);
+ test_subprocesses_deinit();
main_deinit();
lib_deinit();