static int proc_wait(lua_State *L) { apr_status_t status; apr_exit_why_e why; apr_wait_how_e how; lua_apr_proc *process; int code; process = proc_check(L, 1); how = lua_toboolean(L, 2) ? APR_WAIT : APR_NOWAIT; status = apr_proc_wait(&process->handle, &code, &why, how); if (APR_STATUS_IS_CHILD_NOTDONE(status)) return (lua_pushboolean(L, 0), 1); else if (!APR_STATUS_IS_CHILD_DONE(status)) return push_error_status(L, status); else lua_pushboolean(L, 1); switch (why) { default: case APR_PROC_EXIT: lua_pushliteral(L, "exit"); break; case APR_PROC_SIGNAL: lua_pushliteral(L, "signal"); break; case APR_PROC_SIGNAL_CORE: lua_pushliteral(L, "signal/core"); break; } lua_pushinteger(L, code); return 3; }
/* * proc_probe * probe the proc event and send to fms * * Input * emp event source module pointer * * Return val * return the nvlist which contain the event. * NULL if failed */ struct list_head * proc_probe(evtsrc_module_t *emp) { int ret; char *cfg_file; struct list_head *fault; fault = nvlist_head_alloc(); if ( fault == NULL ) { fprintf(stderr, "PROC: alloc list_head error\n"); return NULL; } cfg_file = strdup(PROC_CONFIG_FILE); if ( config_init(cfg_file) ) { fprintf(stderr, "PROC: unable to initialize configure\n"); return NULL; } ret = proc_check(fault); if ( ret ) return NULL; else return fault; }
static int proc_tostring(lua_State *L) { lua_apr_proc *process; process = proc_check(L, 1); lua_pushfstring(L, "%s (%p)", lua_apr_proc_type.friendlyname, process); return 1; }
static int proc_detach_set(lua_State *L) { apr_status_t status; apr_int32_t detach; lua_apr_proc *process; process = proc_check(L, 1); detach = lua_toboolean(L, 2); status = apr_procattr_detach_set(process->attr, detach); return push_status(L, status); }
static int proc_dir_set(lua_State *L) { apr_status_t status; const char *path; lua_apr_proc *process; process = proc_check(L, 1); path = luaL_checkstring(L, 2); status = apr_procattr_dir_set(process->attr, path); return push_status(L, status); }
static int proc_addrspace_set(lua_State *L) { apr_int32_t separate; apr_status_t status; lua_apr_proc *process; process = proc_check(L, 1); separate = lua_toboolean(L, 2); status = apr_procattr_addrspace_set(process->attr, separate); return push_status(L, status); }
static int proc_group_set(lua_State *L) { apr_status_t status; const char *groupname; lua_apr_proc *process; process = proc_check(L, 1); groupname = luaL_checkstring(L, 2); status = apr_procattr_group_set(process->attr, groupname); return push_status(L, status); }
static int proc_error_check_set(lua_State *L) { apr_status_t status; apr_int32_t error_check; lua_apr_proc *process; process = proc_check(L, 1); error_check = lua_toboolean(L, 2); status = apr_procattr_error_check_set(process->attr, error_check); return push_status(L, status); }
// This is the first function that gets run in user mode (ring 3). // It acts as PIOS's "root process", // of which all other processes are descendants. void user() { cprintf("in user()\n"); assert(read_esp() > (uint32_t) &user_stack[0]); assert(read_esp() < (uint32_t) &user_stack[sizeof(user_stack)]); // Check the system call and process scheduling code. cprintf("proc_check"); proc_check(); // Check that we're in user mode and can handle traps from there. trap_check_user(); done(); }
static int proc_user_set(lua_State *L) { const char *username, *password; apr_status_t status; lua_apr_proc *process; process = proc_check(L, 1); username = luaL_checkstring(L, 2); # if APR_PROCATTR_USER_SET_REQUIRES_PASSWORD password = luaL_checkstring(L, 3); # else password = luaL_optstring(L, 3, NULL); # endif status = apr_procattr_user_set(process->attr, username, password); return push_status(L, status); }
static int set_pipe(lua_State *L, const char *ck, const char *pk, lua_apr_setpipe_f cb) { lua_apr_proc *process; apr_file_t *child, *parent = NULL; /* Validate and collect arguments. */ lua_settop(L, 3); /* process, child_pipe, parent_pipe */ process = proc_check(L, 1); child = file_check(L, 2, 1)->handle; if (!lua_isnil(L, 3)) parent = file_check(L, 3, 1)->handle; /* Make sure pipe(s) aren't garbage collected while process is alive! */ object_env_private(L, 1); /* process, child_pipe, parent_pipe, environment */ lua_insert(L, 1); /* environment, process, child_pipe, parent_pipe */ lua_setfield(L, 1, pk); /* environment, process, child_pipe */ lua_setfield(L, 1, ck); /* environment, process */ return push_status(L, cb(process->attr, child, parent)); }
static int proc_kill(lua_State *L) { const char *options[] = { "never", "always", "timeout", "wait", "once", NULL, }; const apr_kill_conditions_e values[] = { APR_KILL_NEVER, APR_KILL_ALWAYS, APR_KILL_AFTER_TIMEOUT, APR_JUST_WAIT, APR_KILL_ONLY_ONCE, }; apr_status_t status; lua_apr_proc *process; int option; process = proc_check(L, 1); option = values[luaL_checkoption(L, 2, NULL, options)]; status = apr_proc_kill(&process->handle, option); return push_status(L, status); }
static int proc_exec(lua_State *L) { apr_status_t status; lua_apr_proc *process; const char *p, **args; int i, nargs = 0; lua_settop(L, 2); process = proc_check(L, 1); if (!lua_isnoneornil(L, 2)) { luaL_checktype(L, 2, LUA_TTABLE); nargs = lua_objlen(L, 2); } /* Allocate and initialize the array of arguments. */ args = apr_palloc(process->memory_pool, sizeof args[0] * (nargs + 2)); if (args == NULL) return push_error_memory(L); args[0] = apr_filepath_name_get(process->path); args[nargs+1] = NULL; /* Copy the arguments? */ if (nargs > 0) { for (i = 0; i <= nargs; i++) { lua_pushinteger(L, i); lua_gettable(L, 2); p = lua_tostring(L, -1); if (p != NULL) /* argument */ args[i] = apr_pstrdup(process->memory_pool, p); else if (i != 0) /* invalid value */ luaL_argcheck(L, 0, 2, lua_pushfstring(L, "invalid value at index %d", i)); lua_pop(L, 1); } } /* Create the child process using the given command line arguments. */ status = apr_proc_create(&process->handle, process->path, args, process->env, process->attr, process->memory_pool); return push_status(L, status); }
static int proc_gc(lua_State *L) { lua_apr_proc *process = proc_check(L, 1); if (object_collectable((lua_apr_refobj*)process)) { lua_settop(L, 1); lua_getfenv(L, 1); if (lua_type(L, -1) == LUA_TTABLE) { close_pipe(L, "in_child"); close_pipe(L, "in_parent"); close_pipe(L, "out_child"); close_pipe(L, "out_parent"); close_pipe(L, "err_child"); close_pipe(L, "err_parent"); } if (process->memory_pool != NULL) { apr_pool_destroy(process->memory_pool); process->memory_pool = NULL; } } release_object((lua_apr_refobj*)process); return 0; }
static int proc_env_set(lua_State *L) { const char *format, *message, *name, *value; size_t i, count; char **env; lua_apr_proc *process; /* validate input, calculate size of environment array */ process = proc_check(L, 1); luaL_checktype(L, 2, LUA_TTABLE); for (count = 0, lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1), count++) { if (lua_type(L, -2) != LUA_TSTRING) { format = "expected string key, got %s"; message = lua_pushfstring(L, format, luaL_typename(L, -2)); luaL_argerror(L, 2, message); } if (!lua_isstring(L, -1)) { format = "expected string value for key " LUA_QS ", got %s"; message = lua_pushfstring(L, format, lua_tostring(L, -2), luaL_typename(L, -1)); luaL_argerror(L, 2, message); } } /* convert Lua table to array of environment variables */ env = apr_palloc(process->memory_pool, sizeof env[0] * (count+1)); if (!env) return push_error_memory(L); for (i = 0, lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1), i++) { name = lua_tostring(L, -2); value = lua_tostring(L, -1); env[i] = apr_pstrcat(process->memory_pool, name, "=", value, NULL); if (!env[i]) return push_error_memory(L); } env[i] = NULL; process->env = (const char**)env; lua_pushboolean(L, 1); return 1; }
static int proc_cmdtype_set(lua_State *L) { const char *options[] = { "shellcmd", "shellcmd/env", "program", "program/env", "program/env/path", NULL }; const apr_cmdtype_e types[] = { APR_SHELLCMD, APR_SHELLCMD_ENV, APR_PROGRAM, APR_PROGRAM_ENV, APR_PROGRAM_PATH }; lua_apr_proc *process; apr_cmdtype_e type; apr_status_t status; process = proc_check(L, 1); type = types[luaL_checkoption(L, 2, NULL, options)]; status = apr_procattr_cmdtype_set(process->attr, type); return push_status(L, status); }
static int proc_io_set(lua_State *L) { const char *options[] = { "none", "full-block", "full-nonblock", "parent-block", "child-block", NULL }; const apr_int32_t values[] = { APR_NO_PIPE, APR_FULL_BLOCK, APR_FULL_NONBLOCK, APR_PARENT_BLOCK, APR_CHILD_BLOCK }; apr_status_t status; lua_apr_proc *process; apr_int32_t input, output, error; process = proc_check(L, 1); input = values[luaL_checkoption(L, 2, "none", options)]; output = values[luaL_checkoption(L, 3, "none", options)]; error = values[luaL_checkoption(L, 4, "none", options)]; status = apr_procattr_io_set(process->attr, input, output, error); return push_status(L, status); }
static int proc_err_get(lua_State *L) { lua_apr_proc *process = proc_check(L, 1); return get_pipe(L, process->handle.err, "err_parent"); }