[svn-commits] mnicholson: branch mnicholson/asttest r247163 - in /team/mnicholson/asttest/a...

SVN commits to the Digium repositories svn-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 svn-commits mailing list