int service_mgmt_start(struct service_base *service)
{
pthread_mutex_lock(&(sg_service_mgmt.data_lock)); // lock
if (service->running) {
pthread_mutex_unlock(&(sg_service_mgmt.data_lock)); // unlock
return 0;
}
if (service->prepare_handler) {
int ret = service->prepare_handler(service);
if (ret != 0) {
RM_LOGE("service: %s prepare failed! code = %d", service->name, ret);
}
}
RM_LOGI("service: %s prepare finished", service->name);
int pid = fork();
if (pid < 0) {
perror("fork error:");
pthread_mutex_unlock(&(sg_service_mgmt.data_lock)); // unlock
return -1;
}
if (pid > 0) { /* parent */
service->pid = pid;
service->running = 1;
RM_LOGI("fork success");
if (!strstr(service->name, "bluetoothctl")) {
waitpid(service->pid, NULL, 0);
service->pid = 0;
service->running = 0;
}
pthread_mutex_unlock(&(sg_service_mgmt.data_lock)); // unlock
return 0;
}
/* child */
pthread_mutex_unlock(&(sg_service_mgmt.data_lock)); // unlock
// TODO: change output
if (!strstr(service->name, "dnsmasq")) {
int stdout_fd = open("/dev/null", O_WRONLY);
int stderr_fd = open("/dev/null", O_WRONLY);
dup2(stdout_fd, STDOUT_FILENO);
dup2(stderr_fd, STDERR_FILENO);
close(stdout_fd);
close(stderr_fd);
}
execvp(service->argv[0], service->argv);
exit(127);
}