Example #1
0
static DBusHandlerResult
signal_handler(lua_State *S, DBusMessage *msg)
{
	lua_State *T;
	const char *path = dbus_message_get_path(msg);
	const char *interface = dbus_message_get_interface(msg);
	const char *member = dbus_message_get_member(msg);

	lem_debug("received signal\n  %s\n  %s\n  %s(%s)",
	          path, interface, member,
	          dbus_message_get_signature(msg));

	/* NOTE: this magic string representation of an
	 * incoming signal must match the one in the Lua code */
	lua_pushfstring(S, "%s\n%s\n%s",
	                path      ? path      : "",
	                interface ? interface : "",
	                member    ? member    : "");

	lua_rawget(S, LEM_DBUS_SIGNAL_TABLE);
	if (lua_type(S, -1) != LUA_TFUNCTION) {
		lua_settop(S, LEM_DBUS_TOP);
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	/* create new thread */
	T = lem_newthread();
	lua_xmove(S, T, 1);

	lem_queue(T, lem_dbus_push_arguments(T, msg));

	return DBUS_HANDLER_RESULT_HANDLED;
}
Example #2
0
File: lem.c Project: esmil/lem
static int
queue_file(int argc, char *argv[], int fidx)
{
	lua_State *T = lem_newthread();
	const char *filename;
	int i;

	if (fidx < argc)
		filename = argv[fidx];
	else
		filename = LEM_LDIR "lem/repl.lua";

	switch (luaL_loadfile(T, filename)) {
	case LUA_OK: /* success */
		break;

	case LUA_ERRMEM:
		oom();

	default:
		lem_log_error("lem: %s", lua_tostring(T, 1));
		return -1;
	}

	lua_createtable(T, argc, 0);
	for (i = 0; i < argc; i++) {
		lua_pushstring(T, argv[i]);
		lua_rawseti(T, -2, i - fidx);
	}
	lua_setglobal(T, "arg");

	lem_queue(T, 0);
	return 0;
}
Example #3
0
File: core.c Project: ifzz/lem
static void
signal_child_handler(EV_P_ struct ev_child *w, int revents)
{
	lua_State *S;
	int status;
	int pid = w->pid;
	int rpid = w->rpid;

	(void)revents;

	S = lem_newthread();
	lua_pushlightuserdata(S, &sigmap);
	lua_rawget(S, LUA_REGISTRYINDEX);
	if (lua_type(S, 1) != LUA_TFUNCTION) {
		lem_forgetthread(S);
		return;
	}
	lua_pushinteger(S, SIGCHLD);

	status = w->rstatus;
	lua_createtable(S, 0, 5);

	lua_pushinteger(S, pid);
	lua_setfield(S, -2, "pid");
	lua_pushinteger(S, rpid);
	lua_setfield(S, -2, "rpid");

	if (WIFEXITED(status)) {
		lua_pushinteger(S, WEXITSTATUS(status));
		lua_setfield(S, -2, "status");
		lua_pushstring(S, "exited");
	} else if (WIFSIGNALED(status)) {
		lua_pushinteger(S, WTERMSIG(status));
		lua_setfield(S, -2, "signal");
#ifdef WCOREDUMP
		lua_pushboolean(S, WCOREDUMP(status));
		lua_setfield(S, -2, "coredumped");
#endif
		lua_pushstring(S, "signaled");
	} else if (WIFSTOPPED(status)) {
		lua_pushinteger(S, WSTOPSIG(status));
		lua_setfield(S, -2, "signal");
		lua_pushstring(S, "stopped");
	} else if (WIFCONTINUED(status)) {
		lua_pushstring(S, "continued");
	} else {
		assert(0); /* XXX do something more graceful */
	}
	lua_setfield(S, -2, "type");

	lem_queue(S, 2);
}
Example #4
0
static DBusHandlerResult
method_call_handler(lua_State *S, DBusMessage *msg)
{
	lua_State *T;
	struct message_object *m;
	const char *path = dbus_message_get_path(msg);
	const char *interface = dbus_message_get_interface(msg);
	const char *member = dbus_message_get_member(msg);

	lem_debug("received call\n  %s\n  %s\n  %s(%s)",
	          path, interface, member,
		  dbus_message_get_signature(msg));

	lua_pushstring(S, path ? path : "");
	lua_rawget(S, LEM_DBUS_OBJECT_TABLE);
	if (lua_type(S, -1) != LUA_TTABLE) {
		lua_settop(S, LEM_DBUS_TOP);
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	lua_pushfstring(S, "%s.%s",
	                interface ? interface : "",
	                member    ? member    : "");
	lua_rawget(S, -2);
	if (lua_type(S, -1) != LUA_TFUNCTION) {
		lua_settop(S, LEM_DBUS_TOP);
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	/* create new thread */
	T = lem_newthread();
	lua_pushvalue(S, LEM_DBUS_BUS_OBJECT);
	lua_xmove(S, T, 2);
	lua_settop(S, LEM_DBUS_TOP);

	/* push the send_reply function */
	m = lua_newuserdata(T, sizeof(struct message_object));
	m->msg = msg;
	dbus_message_ref(msg);

	/* set metatable */
	lua_pushvalue(S, LEM_DBUS_MESSAGE_META);
	lua_xmove(S, T, 1);
	lua_setmetatable(T, -2);

	lua_pushcclosure(T, message_reply, 2);

	lem_queue(T, lem_dbus_push_arguments(T, msg) + 1);

	return DBUS_HANDLER_RESULT_HANDLED;
}
Example #5
0
File: utils.c Project: esmil/lem
static int
utils_spawn(lua_State *T)
{
	lua_State *S;
	int nargs;

	luaL_checktype(T, 1, LUA_TFUNCTION);

	S = lem_newthread();
	nargs = lua_gettop(T);

	lua_xmove(T, S, nargs);

	lem_queue(S, nargs - 1);

	lua_pushboolean(T, 1);
	return 1;
}
Example #6
0
File: core.c Project: ifzz/lem
static void
signal_os_handler(EV_P_ struct ev_signal *w, int revents)
{
	lua_State *S;

	(void)revents;

	S = lem_newthread();
	lua_pushlightuserdata(S, &sigmap);
	lua_rawget(S, LUA_REGISTRYINDEX);
	if (lua_type(S, 1) != LUA_TFUNCTION) {
		lem_forgetthread(S);
		return;
	}

	lua_pushinteger(S, w->signum);
	lem_queue(S, 1);
}
Example #7
0
File: server.c Project: esmil/lem
static void
server_autospawn_cb(EV_P_ struct ev_io *w, int revents)
{
	lua_State *T = w->data;
	int sock;
	lua_State *S;

	(void)revents;

	/* dequeue the incoming connection */
#ifdef SOCK_CLOEXEC
	sock = accept4(w->fd, NULL, NULL, SOCK_CLOEXEC | SOCK_NONBLOCK);
#else
	sock = accept(w->fd, NULL, NULL);
#endif
	if (sock < 0) {
		switch (errno) {
		case EAGAIN: case EINTR: case ECONNABORTED:
		case ENETDOWN: case EPROTO: case ENOPROTOOPT:
		case EHOSTDOWN:
#ifdef ENONET
		case ENONET:
#endif
		case EHOSTUNREACH: case EOPNOTSUPP: case ENETUNREACH:
			return;
		}
		lua_pushnil(T);
		lua_pushfstring(T, "error accepting connection: %s",
		                strerror(errno));
		goto error;
	}
#ifndef SOCK_CLOEXEC
	/* set FD_CLOEXEC and make the socket non-blocking */
	if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1 ||
			fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
		close(sock);
		lua_pushnil(T);
		lua_pushfstring(T, "error setting socket flags: %s",
		                strerror(errno));
		goto error;
	}
#endif
	S = lem_newthread();

	/* copy handler function */
	lua_pushvalue(T, 2);
	/* create stream */
	stream_new(T, sock, 3);
	/* move function and stream to new thread */
	lua_xmove(T, S, 2);

	lem_queue(S, 1);
	return;

error:
	ev_io_stop(EV_A_ w);
	close(w->fd);
	w->fd = -1;
	w->data = NULL;
	lem_queue(T, 2);
}
Example #8
0
File: lem.c Project: halfd/lem
static void
runqueue_pop(EV_P_ struct ev_idle *w, int revents)
{
	struct lem_runqueue_slot *slot;
	lua_State *T;
	int nargs;

	(void)revents;

	if (rq.first == rq.last) { /* queue is empty */
		lem_debug("runqueue is empty, collecting..");
#if 0
		if (lua_gc(L, LUA_GCSTEP, 0)) {
			lem_debug("done collecting");
			ev_idle_stop(EV_A_ w);
		}
#else
		ev_idle_stop(EV_A_ w);
		lua_gc(L, LUA_GCCOLLECT, 0);
#endif
		return;
	}

	lem_debug("running thread...");

	slot = &rq.queue[rq.first];
	T = slot->T;
	nargs = slot->nargs;

	rq.first++;
	rq.first &= rq.mask;

	/* run Lua thread */
#if LUA_VERSION_NUM >= 502
	switch (lua_resume(T, NULL, nargs)) {
#else
	switch (lua_resume(T, nargs)) {
#endif
	case LUA_OK: /* thread finished successfully */
		lem_debug("thread finished successfully");
		lem_forgetthread(T);
		return;

	case LUA_YIELD: /* thread yielded */
		lem_debug("thread yielded");
		return;

	case LUA_ERRERR: /* error running error handler */
		lem_debug("thread errored while running error handler");
#if LUA_VERSION_NUM >= 502
	case LUA_ERRGCMM:
		lem_debug("error in __gc metamethod");
#endif
	case LUA_ERRRUN: /* runtime error */
		lem_debug("thread errored");
		thread_error(T);
		break;

	case LUA_ERRMEM: /* out of memory */
		oom();

	default: /* this shouldn't happen */
		lem_debug("lua_resume: unknown error");
		lua_pushliteral(L, "unknown error");
		break;
	}
	lem_exit(EXIT_FAILURE);
}

#include "pool.c"

static int
queue_file(int argc, char *argv[], int fidx)
{
	lua_State *T = lem_newthread();
	const char *filename;
	int i;

	if (fidx < argc)
		filename = argv[fidx];
	else
		filename = LEM_LDIR "lem/repl.lua";

	switch (luaL_loadfile(T, filename)) {
	case LUA_OK: /* success */
		break;

	case LUA_ERRMEM:
		oom();

	default:
		lem_log_error("lem: %s", lua_tostring(T, 1));
		return -1;
	}

	lua_createtable(T, argc, 0);
	for (i = 0; i < argc; i++) {
		lua_pushstring(T, argv[i]);
		lua_rawseti(T, -2, i - fidx);
	}
	lua_setglobal(T, "arg");

	lem_queue(T, 0);
	return 0;
}