android/ipc-tester: Run daemon in separate process

This patch adds new process waiting to run daemon when needed.
This commit is contained in:
Jakub Tyszkowski 2014-01-20 10:36:01 +01:00 committed by Szymon Janc
parent 8cc27935d3
commit e82c8804f3

View File

@ -21,8 +21,14 @@
*
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <libgen.h>
#include <glib.h>
#include "lib/bluetooth.h"
@ -33,13 +39,19 @@
#include "src/shared/hciemu.h"
#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
#define EMULATOR_SIGNAL "emulator_started"
struct test_data {
struct mgmt *mgmt;
uint16_t mgmt_index;
struct hciemu *hciemu;
enum hciemu_type hciemu_type;
pid_t bluetoothd_pid;
};
static char exec_dir[PATH_MAX + 1];
static void read_info_callback(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@ -170,14 +182,123 @@ static void test_post_teardown(const void *data)
}
}
static void bluetoothd_start(int hci_index)
{
char prg_name[PATH_MAX + 1];
char index[8];
char *prg_argv[4];
snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
snprintf(index, sizeof(index), "%d", hci_index);
prg_argv[0] = prg_name;
prg_argv[1] = "-i";
prg_argv[2] = index;
prg_argv[3] = NULL;
if (!tester_use_debug())
fclose(stderr);
execve(prg_argv[0], prg_argv, NULL);
}
static void emulator(int pipe, int hci_index)
{
static const char SYSTEM_SOCKET_PATH[] = "\0android_system";
char buf[1024];
struct sockaddr_un addr;
struct timeval tv;
int fd;
ssize_t len;
fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (fd < 0)
goto failed;
tv.tv_sec = WAIT_FOR_SIGNAL_TIME;
tv.tv_usec = 0;
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
perror("Failed to bind system socket");
goto failed;
}
len = write(pipe, EMULATOR_SIGNAL, sizeof(EMULATOR_SIGNAL));
if (len != sizeof(EMULATOR_SIGNAL))
goto failed;
memset(buf, 0, sizeof(buf));
len = read(fd, buf, sizeof(buf));
if (len <= 0 || (strcmp(buf, "ctl.start=bluetoothd")))
goto failed;
close(pipe);
close(fd);
bluetoothd_start(hci_index);
failed:
close(pipe);
close(fd);
}
static void setup(const void *data)
{
struct test_data *test_data = tester_get_data();
int signal_fd[2];
char buf[1024];
pid_t pid;
int len;
if (pipe(signal_fd))
goto failed;
pid = fork();
if (pid < 0) {
close(signal_fd[0]);
close(signal_fd[1]);
goto failed;
}
if (pid == 0) {
if (!tester_use_debug())
fclose(stderr);
close(signal_fd[0]);
emulator(signal_fd[1], test_data->mgmt_index);
exit(0);
}
close(signal_fd[1]);
test_data->bluetoothd_pid = pid;
len = read(signal_fd[0], buf, sizeof(buf));
if (len <= 0 || (strcmp(buf, EMULATOR_SIGNAL))) {
close(signal_fd[0]);
goto failed;
}
return;
failed:
tester_setup_failed();
test_post_teardown(data);
}
static void teardown(const void *data)
{
struct test_data *test_data = tester_get_data();
if (test_data->bluetoothd_pid)
waitpid(test_data->bluetoothd_pid, NULL, 0);
tester_teardown_complete();
}
@ -199,6 +320,8 @@ static void ipc_send_tc(const void *data)
int main(int argc, char *argv[])
{
snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
tester_init(&argc, &argv);
test_generic("Test Dummy", NULL, setup, ipc_send_tc, teardown);