int process_subprocess_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct subprocess_data *mdata = data; struct sol_flow_node_type_process_subprocess_options *opts = (struct sol_flow_node_type_process_subprocess_options *)options; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_PROCESS_SUBPROCESS_OPTIONS_API_VERSION, -EINVAL); mdata->node = node; sol_vector_init(&mdata->write_data, sizeof(struct write_data)); if (pipe2(mdata->pipes.out, O_NONBLOCK | O_CLOEXEC) < 0) { SOL_WRN("Failed to create out pipe"); return -errno; } if (pipe2(mdata->pipes.in, O_NONBLOCK | O_CLOEXEC) < 0) { SOL_WRN("Failed to create in pipe"); goto in_err; } if (pipe2(mdata->pipes.err, O_NONBLOCK | O_CLOEXEC) < 0) { SOL_WRN("Failed to create err pipe"); goto err_err; } mdata->command = strdup(opts->command); SOL_NULL_CHECK_GOTO(mdata->command, flags_err); if (opts->start) { if (setup_watches(mdata) < 0) goto watch_err; mdata->fork_run = sol_platform_linux_fork_run(on_fork, on_fork_exit, mdata); SOL_NULL_CHECK_GOTO(mdata->fork_run, err); } return 0; err: sol_fd_del(mdata->watches.in); sol_fd_del(mdata->watches.err); watch_err: free(mdata->command); flags_err: close(mdata->pipes.err[0]); close(mdata->pipes.err[1]); err_err: close(mdata->pipes.in[0]); close(mdata->pipes.in[1]); in_err: close(mdata->pipes.out[0]); close(mdata->pipes.out[1]); return -errno; }
static void startup(void) { guint id; if (pipe2(pfd, O_CLOEXEC) < 0) { SOL_WRN("pipe()"); goto error; } if (!sol_glib_integration()) { SOL_WRN("sol_glib_integration()"); goto error; } fork_run = sol_platform_linux_fork_run(on_fork, on_child_exit, NULL); if (!fork_run) { SOL_WRN("sol_platform_linux_fork_run()"); goto error; } id = g_idle_add(on_idle, NULL); if (id == 0) { SOL_WRN("g_idle_add()"); goto error; } id = g_timeout_add(100, on_timeout, NULL); if (id == 0) { SOL_WRN("g_timeout_add()"); goto error; } id = g_unix_fd_add(pfd[0], G_IO_IN, on_fd, NULL); if (id == 0) { SOL_WRN("g_unix_fd_add()"); goto error; } sol_timeout_add(5000, on_watchdog, NULL); return; error: sol_quit_with_code(EXIT_FAILURE); return; }
static int fork_run_do(void) { if (fork_run) return 0; fork_run = sol_platform_linux_fork_run(on_fork, on_fork_exit, NULL); if (!fork_run) { sol_platform_linux_micro_inform_service_state (name, SOL_PLATFORM_SERVICE_STATE_FAILED); return -errno; } SOL_DBG("bluetooth-daemon started as pid=%" PRIu64, (uint64_t)sol_platform_linux_fork_run_get_pid(fork_run)); sol_platform_linux_micro_inform_service_state (name, SOL_PLATFORM_SERVICE_STATE_ACTIVE); return 0; }
static int dbus_start(const struct sol_platform_linux_micro_module *mod, const char *service) { if (fork_run) return 0; name = service; fork_run = sol_platform_linux_fork_run(on_fork, on_fork_exit, NULL); if (!fork_run) { sol_platform_linux_micro_inform_service_state(service, SOL_PLATFORM_SERVICE_STATE_FAILED); return -errno; } SOL_DBG("dbus-daemon started as pid=%" PRIu64, (uint64_t)sol_platform_linux_fork_run_get_pid(fork_run)); /* TODO: change to use inotify */ check_timeout = sol_timeout_add(200, on_timeout, NULL); return 0; }
int process_subprocess_start_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { struct subprocess_data *mdata = data; if (mdata->fork_run) return 0; if (setup_watches(mdata) < 0) return -1; mdata->fork_run = sol_platform_linux_fork_run(on_fork, on_fork_exit, mdata); SOL_NULL_CHECK_GOTO(mdata->fork_run, fork_err); return 0; fork_err: sol_fd_del(mdata->watches.err); mdata->watches.err = NULL; sol_fd_del(mdata->watches.in); mdata->watches.in = NULL; return -1; }