int subprocloc(int timeout, FILE *fd[2], subproc_callback callback, void *data, const char *cmd, const char *args[]) { struct log_buffer log; log_buffer_init(&log, LL_DBG); if (log.f) { fprintf(log.f, "Running subprocess: %s", cmd); for (const char **p = args; *p; p++) fprintf(log.f, " %s", *p); fclose(log.f); DBG("%s", log.char_buffer); free(log.char_buffer); } // Prepare pipes for stdout and stderr int p_err[2], p_out[2]; pipe2(p_err, O_NONBLOCK); pipe2(p_out, O_NONBLOCK); // Fork pid_t pid = fork(); if (pid == -1) DIE("Failed to fork command %s: %s", cmd, strerror(errno)); else if (pid == 0) run_child(cmd, args, callback, data, p_out, p_err); ASSERT(close(p_out[1]) != -1); ASSERT(close(p_err[1]) != -1); struct pollfd pfds[] = { { .fd = p_out[0], .events = POLLIN }, { .fd = p_err[0], .events = POLLIN }
static int lua_run_generic(lua_State *L, bool utils) { // Flush the lua output (it seems to buffered separately) do_flush(L, "stdout"); do_flush(L, "stderr"); // Extract the parameters. There's a lot of them. luaL_checktype(L, 1, LUA_TFUNCTION); int pf_cback_type = lua_type(L, 2); if (pf_cback_type != LUA_TNIL && pf_cback_type != LUA_TFUNCTION) return luaL_error(L, "The 2nd argument of run_command must be either function or nil"); if (!lua_isnil(L, 3) && !lua_isstring(L, 3)) return luaL_error(L, "The 3rd argument of run_command is a string input or nil"); int term_timeout = luaL_checkinteger(L, 4); int kill_timeout = luaL_checkinteger(L, 5); const char *cmd = luaL_checkstring(L, 6); struct log_buffer log; log_buffer_init(&log, LL_DBG); // The rest of the args are args for the command ‒ get them into an array const size_t arg_count = (size_t)lua_gettop(L) - 6; const char *args[arg_count + 1]; for (int i = 6; i < lua_gettop(L); i ++) { args[i - 6] = luaL_checkstring(L, i + 1); if (log.f) fprintf(log.f, "%s ", args[i - 6]); } args[arg_count] = NULL; if (log.f) { fclose(log.f); if (utils) { DBG("Util command: %s %s", cmd, log.char_buffer); } else DBG("Command: %s %s", cmd, log.char_buffer); free(log.char_buffer); } // Data for the callbacks. It will get freed there. struct lua_command_data *data = malloc(sizeof *data); data->L = L; data->terminated_callback = register_value(L, 1); data->postfork_callback = lua_isnil(L, 2) ? NULL : register_value(L, 2); struct events *events = extract_registry(L, "events"); ASSERT(events); size_t input_size = 0; const char *input = NULL; if (lua_isstring(L, 3)) input = lua_tolstring(L, 3, &input_size); struct wait_id id; if (utils) id = run_util_a(events, command_terminated, command_postfork, data, input_size, input, term_timeout, kill_timeout, cmd, args); else id = run_command_a(events, command_terminated, command_postfork, data, input_size, input, term_timeout, kill_timeout, cmd, args); push_wid(L, &id); // Return 1 value ‒ the wait_id return 1; }
void log_init(void) { regcomp(&pat_prio, "^<([0-9]*)>(.*)", REG_EXTENDED); regcomp(&pat_tstamp, "^\[[ 0]*([0-9]*).([0-9]*)] (.*)", REG_EXTENDED); if (log_buffer_init(log_size)) { ERROR("Failed to allocate log memory\n"); exit(-1); } syslog_open(); klog_open(); openlog("sysinit", LOG_CONS, LOG_DAEMON); }
void log_init(int _log_size) { if (_log_size > 0) log_size = _log_size; regcomp(&pat_prio, "^<([0-9]*)>(.*)", REG_EXTENDED); regcomp(&pat_tstamp, "^\[[ 0]*([0-9]*).([0-9]*)] (.*)", REG_EXTENDED); if (log_buffer_init(log_size)) { fprintf(stderr, "Failed to allocate log memory\n"); exit(-1); } syslog_open(); klog_open(); openlog("sysinit", LOG_CONS, LOG_DAEMON); }