[asterisk-commits] mnicholson: branch mnicholson/asttest r247163 - in /team/mnicholson/asttest/a...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Feb 17 09:06:08 CST 2010
Author: mnicholson
Date: Wed Feb 17 09:06:03 2010
New Revision: 247163
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=247163
Log:
Added generic library to spawn processes.
Added:
team/mnicholson/asttest/asttest/include/asttest/lua/proclib.h (with props)
team/mnicholson/asttest/asttest/lua/proclib.c (with props)
team/mnicholson/asttest/asttest/lua/proclib.lua (with props)
Modified:
team/mnicholson/asttest/asttest/Makefile
team/mnicholson/asttest/asttest/lib/lua.c
Modified: team/mnicholson/asttest/asttest/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/mnicholson/asttest/asttest/Makefile?view=diff&rev=247163&r1=247162&r2=247163
==============================================================================
--- team/mnicholson/asttest/asttest/Makefile (original)
+++ team/mnicholson/asttest/asttest/Makefile Wed Feb 17 09:06:03 2010
@@ -39,7 +39,7 @@
CFLAGS:=-g -c -D_GNU_SOURCE -Wall -I/usr/include/lua5.1 -Iinclude -Ilua
L_MODULES:=$(LUAFILESYSTEM_OBJS) $(LUASOCKET_OBJS) $(LUAPOSIX_OBJS)
L_LIBS:=$(LUAPOSIX_LIBS)
-L_OBJS:=lua/testlib.o lua/astlib.o
+L_OBJS:=lua/testlib.o lua/astlib.o lua/proclib.o
T_LIBS:=-llua5.1
AST_INSTALL_DIR = $(PWD)/asterisk
@@ -102,6 +102,7 @@
lua/testlib.o: lua/testlib.c lua/testlib_lua.h include/asttest/lua/testlib.h
lua/astlib.o: lua/astlib.c lua/astlib_lua.h include/asttest/lua/astlib.h
+lua/proclib.o: lua/proclib.c lua/proclib_lua.h include/asttest/lua/proclib.h
$(LUAFILESYSTEM_OBJS): lua/$(LUAFILESYSTEM) lua/lfs-patched.stamp
$(MAKE) -C lua/$(LUAFILESYSTEM)
Added: team/mnicholson/asttest/asttest/include/asttest/lua/proclib.h
URL: http://svnview.digium.com/svn/asterisk/team/mnicholson/asttest/asttest/include/asttest/lua/proclib.h?view=auto&rev=247163
==============================================================================
--- team/mnicholson/asttest/asttest/include/asttest/lua/proclib.h (added)
+++ team/mnicholson/asttest/asttest/include/asttest/lua/proclib.h Wed Feb 17 09:06:03 2010
@@ -1,0 +1,26 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2008, Digium, Inc.
+ *
+ * Matthew Nicholson <mnicholson at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef ASTTEST_LUA_PROCLIB_H
+#define ASTTEST_LUA_PROCLIB_H
+
+#include <lua.h>
+
+int luaopen_proclib(lua_State *L);
+
+#endif
Propchange: team/mnicholson/asttest/asttest/include/asttest/lua/proclib.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/mnicholson/asttest/asttest/include/asttest/lua/proclib.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/mnicholson/asttest/asttest/include/asttest/lua/proclib.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/mnicholson/asttest/asttest/lib/lua.c
URL: http://svnview.digium.com/svn/asterisk/team/mnicholson/asttest/asttest/lib/lua.c?view=diff&rev=247163&r1=247162&r2=247163
==============================================================================
--- team/mnicholson/asttest/asttest/lib/lua.c (original)
+++ team/mnicholson/asttest/asttest/lib/lua.c Wed Feb 17 09:06:03 2010
@@ -25,6 +25,7 @@
#include "asttest/lua/astlib.h"
#include "asttest/lua/testlib.h"
+#include "asttest/lua/proclib.h"
#include LUAFILESYSTEM_HEADER
#include LUASOCKET_HEADER
@@ -64,6 +65,12 @@
goto e_print_error;
}
+ /* load the proc lib */
+ lua_pushcfunction(L, luaopen_proclib);
+ if (lua_pcall(L, 0, 0, 0)) {
+ goto e_print_error;
+ }
+
/* load the asterisk lib */
lua_pushcfunction(L, luaopen_astlib);
lua_pushstring(L, ts->asterisk_path);
Added: team/mnicholson/asttest/asttest/lua/proclib.c
URL: http://svnview.digium.com/svn/asterisk/team/mnicholson/asttest/asttest/lua/proclib.c?view=auto&rev=247163
==============================================================================
--- team/mnicholson/asttest/asttest/lua/proclib.c (added)
+++ team/mnicholson/asttest/asttest/lua/proclib.c Wed Feb 17 09:06:03 2010
@@ -1,0 +1,318 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2008, Digium, Inc.
+ *
+ * Matthew Nicholson <mnicholson at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#include "proclib_lua.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/*!
+ * \brief [lua_CFunction proc.exec] Start a process.
+ * \param L the lua state to use
+ *
+ * This function forks and execs the given process.
+ */
+static int exec_proc(lua_State *L) {
+ pid_t pid;
+ pid_t *p;
+ int args = lua_gettop(L);
+ const char **argv;
+ const char *name = luaL_checkstring(L, 1);
+ size_t argc;
+ int i, fd;
+
+ /* build the argument list */
+ argc = args + 1; /* the number of args plus 1 for the terminating NULL */
+ if (!(argv = malloc(argc * sizeof(char *)))) {
+ lua_pushliteral(L, "error allocating memory while spawning process");
+ goto e_return;
+ }
+
+ argv[0] = name;
+ argv[args] = NULL;
+
+ for (i = 2; i <= args; i++) {
+ argv[i - 1] = lua_tostring(L, i);
+ }
+
+ /* start the process */
+ pid = fork();
+ if (pid == 0) {
+ /* open dev null and use it for stdin, stdout, and stderr */
+ /* XXX in the future, we should create pipes for stdin, stdout,
+ * and stderr so that our lua scrips can interact with them */
+ fd = open("/dev/null", O_RDWR);
+ /* XXX check for error?!! */
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+
+ execvp(name, (char * const *) argv);
+ exit(1);
+ } else if (pid == -1) {
+ lua_pushliteral(L, "error spawning process (fork error): ");
+ lua_pushstring(L, strerror(errno));
+ lua_concat(L, 2);
+ goto e_free_argv;
+ }
+
+ free(argv);
+
+ lua_newtable(L);
+ luaL_getmetatable(L, "proclib_proc");
+ lua_setmetatable(L, -2);
+
+ /* store the pid */
+ lua_pushliteral(L, "pid");
+ p = lua_newuserdata(L, sizeof(pid_t));
+ *p = pid;
+ luaL_getmetatable(L, "proclib_pid");
+ lua_setmetatable(L, -2);
+ lua_rawset(L, -3);
+
+ return 1;
+
+e_free_argv:
+ free(argv);
+
+e_return:
+ /* error string should already be on the stack */
+ return lua_error(L);
+}
+
+/*!
+ * \brief [lua_CFunction pid:__gc] Kill the process with the given pid.
+ * \param L the lua state to use
+ *
+ * This is the gc function for the pid userdata. This function will send a
+ * TERM signal to the process and then run waitpid.
+ */
+static int pid_gc(lua_State *L) {
+ pid_t *p = luaL_checkudata(L, 1, "proclib_pid");
+ if (kill(*p, SIGTERM)) {
+ return 0;
+ }
+#if 0 /* XXX maybe we should also do SIGKILL here? */
+ sleep(1);
+ kill(*p, SIGKILL);
+#endif
+ waitpid(*p, NULL, 0);
+ return 0;
+}
+
+/*!
+ * \brief [lua_CFunction proc:wait] Wait for the process to end.
+ * \param L the lua state to use
+ *
+ * This function calls waitpid on the running process.
+ *
+ * \return a tuple containg the exit code, nil and the signal that caused the
+ * process to exit, or nil and a string describing the error ("error" or "core"
+ * currently).
+ */
+static int wait_proc(lua_State *L) {
+ pid_t pid;
+ int status;
+
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ /* get the pid of this process */
+ lua_getfield(L, 1, "pid");
+ if (lua_isnil(L, -1)) {
+ /* no process found */
+ lua_pushnil(L);
+ lua_pushliteral(L, "error");
+ return 2;
+ }
+ pid = *(pid_t *) lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ if (waitpid(pid, &status, 0) == -1) {
+ /* waitpid failed */
+ lua_pushnil(L);
+ lua_pushliteral(L, "error");
+ return 2;
+ }
+
+ if (WIFEXITED(status)) {
+ lua_pushinteger(L, WEXITSTATUS(status));
+ lua_pushnil(L);
+ } else if (WIFSIGNALED(status)) {
+ lua_pushnil(L);
+ if (WCOREDUMP(status))
+ lua_pushliteral(L, "core");
+ else
+ lua_pushinteger(L, WTERMSIG(status));
+ } else {
+ lua_pushliteral(L, "unknown error running waitpid");
+ return lua_error(L);
+ }
+
+ /* unset the pid */
+ lua_pushliteral(L, "pid");
+ lua_pushnil(L);
+ lua_rawset(L, 1);
+
+ return 2;
+}
+
+/*!
+ * \brief [lua_CFunction proc:kill] Kill the process with SIGKILL.
+ * \param L the lua state to use
+ *
+ * This function sends SIGKILL then calls proc:wait() and returns the
+ * result.
+ *
+ * \return same as wait_proc() and in the case of "error" an additional error
+ * description and errno may be returned
+ */
+static int kill_proc(lua_State *L) {
+ pid_t pid;
+
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ /* get the pid of this process */
+ lua_getfield(L, 1, "pid");
+ if (lua_isnil(L, -1)) {
+ /* no process found */
+ lua_pushnil(L);
+ lua_pushliteral(L, "error");
+ return 2;
+ }
+ pid = *(pid_t *) lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ if (kill(pid, SIGKILL)) {
+ lua_pushnil(L);
+ lua_pushliteral(L, "error");
+ lua_pushstring(L, strerror(errno));
+ lua_pushinteger(L, errno);
+ return 4;
+ }
+
+ lua_pushcfunction(L, wait_proc);
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 2);
+ return 2;
+}
+
+/*!
+ * \brief [lua_CFunction proc:term] Terminate process with SIGTERM.
+ * \param L the lua state to use
+ *
+ * This function sends SIGTERM then calls proc:wait() and returns the result.
+ *
+ * \return same as wait_proc() and in the case of "error" an additional error
+ * description and errno may be returned
+ */
+static int terminate_proc(lua_State *L) {
+ pid_t pid;
+
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ /* get the pid of this process */
+ lua_getfield(L, 1, "pid");
+ if (lua_isnil(L, -1)) {
+ /* no process found */
+ lua_pushnil(L);
+ lua_pushliteral(L, "error");
+ return 2;
+ }
+ pid = *(pid_t *) lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ if (kill(pid, SIGTERM)) {
+ lua_pushnil(L);
+ lua_pushliteral(L, "error");
+ lua_pushstring(L, strerror(errno));
+ lua_pushinteger(L, errno);
+ return 4;
+ }
+
+ lua_pushcfunction(L, wait_proc);
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 2);
+ return 2;
+}
+
+static luaL_Reg proclib[] = {
+ {"exec", exec_proc},
+ {NULL, NULL},
+};
+
+static luaL_Reg proc_pid[] = {
+ {"__gc", pid_gc},
+ {NULL, NULL},
+};
+
+static luaL_Reg proc_table[] = {
+ {"wait", wait_proc},
+ {"term", terminate_proc},
+ {"kill", kill_proc},
+ {NULL, NULL},
+};
+
+int luaopen_proclib(lua_State *L) {
+ /* register our functions */
+ luaL_register(L, "proc", proclib);
+ lua_pop(L, 1);
+
+ /* set up the pid metatable */
+ luaL_newmetatable(L, "proclib_pid");
+ luaL_register(L, NULL, proc_pid);
+ lua_pop(L, 1);
+
+ /* set up the 'proc' metatable */
+ luaL_newmetatable(L, "proclib_proc");
+
+ /* set the __index value to itself */
+ lua_pushstring(L, "__index");
+ lua_pushvalue(L, -2);
+ lua_settable(L, -3);
+
+ luaL_register(L, NULL, proc_table);
+ lua_pop(L, 1);
+
+ /* load the lua portion of the lib */
+ if (luaL_loadbuffer(L, proclib_lua, sizeof(proclib_lua), "proclib"))
+ goto e_lua_error;
+ lua_pushstring(L, "proc");
+ if (lua_pcall(L, 1, 1, 0))
+ goto e_lua_error;
+
+ return 1;
+
+e_lua_error:
+ /* format the error message a little */
+ lua_pushstring(L, "error loading the proc library: ");
+ lua_insert(L, -2);
+ lua_concat(L, 2);
+ return lua_error(L);
+}
+
Propchange: team/mnicholson/asttest/asttest/lua/proclib.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/mnicholson/asttest/asttest/lua/proclib.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/mnicholson/asttest/asttest/lua/proclib.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/mnicholson/asttest/asttest/lua/proclib.lua
URL: http://svnview.digium.com/svn/asterisk/team/mnicholson/asttest/asttest/lua/proclib.lua?view=auto&rev=247163
==============================================================================
--- team/mnicholson/asttest/asttest/lua/proclib.lua (added)
+++ team/mnicholson/asttest/asttest/lua/proclib.lua Wed Feb 17 09:06:03 2010
@@ -1,0 +1,25 @@
+--
+-- Asterisk -- An open source telephony toolkit.
+--
+-- Copyright (C) 1999 - 2008, Digium, Inc.
+--
+-- Matthew Nicholson <mnicholson at digium.com>
+--
+-- See http://www.asterisk.org for more information about
+-- the Asterisk project. Please do not directly contact
+-- any of the maintainers of this project for assistance;
+-- the project provides a web site, mailing lists and IRC
+-- channels for your use.
+--
+-- This program is free software, distributed under the terms of
+-- the GNU General Public License Version 2. See the LICENSE file
+-- at the top of the source tree.
+--
+
+module(..., package.seeall)
+
+function exec_and_wait(name, ...)
+ p = exec(name, unpack(arg))
+ return p:wait()
+end
+
Propchange: team/mnicholson/asttest/asttest/lua/proclib.lua
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/mnicholson/asttest/asttest/lua/proclib.lua
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/mnicholson/asttest/asttest/lua/proclib.lua
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list