luaApi: move global method/constants into lighty. namespace, add vr:stat(filename)

personal/stbuehler/wip
Stefan Bühler 14 years ago
parent 3949cb0939
commit 476698f118

@ -8,6 +8,6 @@ LI_API liAction* lua_get_action(lua_State *L, int ndx);
LI_API int lua_push_action(liServer *srv, lua_State *L, liAction *a);
/* create new action from lua function */
LI_API liAction* lua_make_action(liServer *srv, lua_State *L, int ndx);
LI_API liAction* lua_make_action(lua_State *L, int ndx);
#endif

@ -40,11 +40,14 @@ LI_API void lua_init_response_mt(lua_State *L);
LI_API liResponse* lua_get_response(lua_State *L, int ndx);
LI_API int lua_push_response(lua_State *L, liResponse *resp);
LI_API void li_lua_init_stat_mt(lua_State *L);
LI_API struct stat* li_lua_get_stat(lua_State *L, int ndx);
LI_API int li_lua_push_stat(lua_State *L, struct stat *st);
LI_API void lua_init_vrequest_mt(lua_State *L);
LI_API liVRequest* lua_get_vrequest(lua_State *L, int ndx);
LI_API int lua_push_vrequest(lua_State *L, liVRequest *vr);
/* return 1 if value is found in mt (on top of the stack), 0 if it is not found (stack balance = 0)
* table, key on stack at pos 0 and 1 (i.e. __index metho)
*/

@ -213,6 +213,7 @@ SET(LIGHTTPD_SHARED_SRC ${LIGHTTPD_SHARED_SRC}
physical_lua.c
request_lua.c
response_lua.c
stat_lua.c
virtualrequest_lua.c
)
ENDIF(WITH_LUA)

@ -52,6 +52,7 @@ lua_src= \
physical_lua.c \
request_lua.c \
response_lua.c \
stat_lua.c \
virtualrequest_lua.c

@ -48,6 +48,7 @@ int lua_push_action(liServer *srv, lua_State *L, liAction *a) {
typedef struct lua_action_param lua_action_param;
struct lua_action_param {
int func_ref;
lua_State *L;
};
typedef struct lua_action_ctx lua_action_ctx;
@ -59,11 +60,12 @@ static liHandlerResult lua_action_func(liVRequest *vr, gpointer param, gpointer
lua_action_param *par = param;
lua_action_ctx *ctx = *context;
liServer *srv = vr->wrk->srv;
lua_State *L = srv->L;
lua_State *L = par->L;
gboolean dolock = (L == srv->L);
liHandlerResult res = LI_HANDLER_GO_ON;
int errfunc;
li_lua_lock(srv);
if (dolock) li_lua_lock(srv);
lua_rawgeti(L, LUA_REGISTRYINDEX, par->func_ref);
lua_pushvalue(L, -1);
@ -110,20 +112,21 @@ static liHandlerResult lua_action_func(liVRequest *vr, gpointer param, gpointer
lua_setfield(L, -2, "_G");
lua_pop(L, 2);
li_lua_unlock(srv);
if (dolock) li_lua_unlock(srv);
return res;
}
static liHandlerResult lua_action_cleanup(liVRequest *vr, gpointer param, gpointer context) {
lua_action_param *par = param;
lua_action_ctx *ctx = context;
liServer *srv = vr->wrk->srv;
lua_State *L = srv->L;
UNUSED(param);
lua_State *L = par->L;
gboolean dolock = (L == srv->L);
li_lua_lock(srv);
if (dolock) li_lua_lock(srv);
luaL_unref(L, LUA_REGISTRYINDEX, ctx->g_ref);
li_lua_unlock(srv);
if (dolock) li_lua_unlock(srv);
g_slice_free(lua_action_ctx, ctx);
@ -132,22 +135,22 @@ static liHandlerResult lua_action_cleanup(liVRequest *vr, gpointer param, gpoint
static void lua_action_free(liServer *srv, gpointer param) {
lua_action_param *par = param;
lua_State *L = srv->L;
lua_State *L = par->L;
gboolean dolock = (L == srv->L);
li_lua_lock(srv);
if (dolock) li_lua_lock(srv);
luaL_unref(L, LUA_REGISTRYINDEX, par->func_ref);
li_lua_unlock(srv);
if (dolock) li_lua_unlock(srv);
g_slice_free(lua_action_param, par);
}
liAction* lua_make_action(liServer *srv, lua_State *L, int ndx) {
liAction* lua_make_action(lua_State *L, int ndx) {
lua_action_param *par = g_slice_new0(lua_action_param);
g_assert(L == srv->L);
lua_pushvalue(L, ndx); /* +1 */
par->func_ref = luaL_ref(L, LUA_REGISTRYINDEX); /* -1 */
par->L = L;
/* new environment for function */
lua_pushvalue(L, ndx); /* +1 */

@ -226,7 +226,7 @@ gboolean li_config_lua_load(liServer *srv, const gchar *filename, liAction **pac
act = lua_get_action(L, -1);
if (NULL == act && lua_isfunction(L, -1)) {
act = lua_make_action(srv, L, -1);
act = lua_make_action(L, -1);
} else {
li_action_acquire(act);
}

@ -146,27 +146,35 @@ void li_lua_init(liServer *srv, lua_State *L) {
lua_init_response_mt(L);
lua_init_vrequest_mt(L);
li_lua_init_stat_mt(L);
/* prefer closure, but just in case */
lua_pushlightuserdata(L, srv);
lua_setfield(L, LUA_REGISTRYINDEX, "lighty.srv");
lua_newtable(L); /* lighty. */
lua_pushlightuserdata(L, srv);
lua_pushcclosure(L, li_lua_error, 1);
lua_setfield(L, LUA_GLOBALSINDEX, "print");
lua_pushvalue(L, -1); /* overwrite global print too */
lua_setfield(L, LUA_GLOBALSINDEX, "print");
lua_setfield(L, -2, "print");
lua_pushlightuserdata(L, srv);
lua_pushcclosure(L, li_lua_warning, 1);
lua_setfield(L, LUA_GLOBALSINDEX, "warning");
lua_setfield(L, -2, "warning");
lua_pushlightuserdata(L, srv);
lua_pushcclosure(L, li_lua_info, 1);
lua_setfield(L, LUA_GLOBALSINDEX, "info");
lua_setfield(L, -2, "info");
lua_pushlightuserdata(L, srv);
lua_pushcclosure(L, li_lua_debug, 1);
lua_setfield(L, LUA_GLOBALSINDEX, "debug");
lua_setfield(L, -2, "debug");
lua_push_constants(L, -2);
lua_push_constants(L, LUA_GLOBALSINDEX);
lua_setfield(L, LUA_GLOBALSINDEX, "lighty");
li_lua_store_globals(L);
}

@ -0,0 +1,232 @@
#include <lighttpd/core_lua.h>
#include <lualib.h>
#include <lauxlib.h>
/* struct stat */
#define LUA_STAT "struct stat"
struct stat* li_lua_get_stat(lua_State *L, int ndx) {
if (!lua_isuserdata(L, ndx)) return NULL;
if (!lua_getmetatable(L, ndx)) return NULL;
luaL_getmetatable(L, LUA_STAT);
if (lua_isnil(L, -1) || lua_isnil(L, -2) || !lua_equal(L, -1, -2)) {
lua_pop(L, 2);
return NULL;
}
lua_pop(L, 2);
return (struct stat*) lua_touserdata(L, ndx);
}
typedef int (*lua_stat_Attrib)(struct stat *st, lua_State *L);
static int lua_stat_attr_read_is_file(struct stat *st, lua_State *L) {
lua_pushboolean(L, S_ISREG(st->st_mode));
return 1;
}
static int lua_stat_attr_read_is_dir(struct stat *st, lua_State *L) {
lua_pushboolean(L, S_ISREG(st->st_mode));
return 1;
}
static int lua_stat_attr_read_is_char(struct stat *st, lua_State *L) {
lua_pushboolean(L, S_ISCHR(st->st_mode));
return 1;
}
static int lua_stat_attr_read_is_block(struct stat *st, lua_State *L) {
lua_pushboolean(L, S_ISBLK(st->st_mode));
return 1;
}
static int lua_stat_attr_read_is_socket(struct stat *st, lua_State *L) {
lua_pushboolean(L, S_ISSOCK(st->st_mode));
return 1;
}
static int lua_stat_attr_read_is_link(struct stat *st, lua_State *L) {
lua_pushboolean(L, S_ISLNK(st->st_mode));
return 1;
}
static int lua_stat_attr_read_is_fifo(struct stat *st, lua_State *L) {
lua_pushboolean(L, S_ISFIFO(st->st_mode));
return 1;
}
static int lua_stat_attr_read_mode(struct stat *st, lua_State *L) {
lua_pushinteger(L, st->st_mode);
return 1;
}
static int lua_stat_attr_read_mtime(struct stat *st, lua_State *L) {
lua_pushinteger(L, st->st_mtime);
return 1;
}
static int lua_stat_attr_read_ctime(struct stat *st, lua_State *L) {
lua_pushinteger(L, st->st_ctime);
return 1;
}
static int lua_stat_attr_read_atime(struct stat *st, lua_State *L) {
lua_pushinteger(L, st->st_atime);
return 1;
}
static int lua_stat_attr_read_uid(struct stat *st, lua_State *L) {
lua_pushinteger(L, st->st_uid);
return 1;
}
static int lua_stat_attr_read_gid(struct stat *st, lua_State *L) {
lua_pushinteger(L, st->st_gid);
return 1;
}
static int lua_stat_attr_read_size(struct stat *st, lua_State *L) {
lua_pushinteger(L, st->st_size);
return 1;
}
static int lua_stat_attr_read_ino(struct stat *st, lua_State *L) {
lua_pushinteger(L, st->st_ino);
return 1;
}
static int lua_stat_attr_read_dev(struct stat *st, lua_State *L) {
lua_pushinteger(L, st->st_dev);
return 1;
}
#define AR(m) { #m, lua_stat_attr_read_##m, NULL }
#define AW(m) { #m, NULL, lua_stat_attr_write_##m }
#define ARW(m) { #m, lua_stat_attr_read_##m, lua_stat_attr_write_##m }
static const struct {
const char* key;
lua_stat_Attrib read_attr, write_attr;
} stat_attribs[] = {
AR(is_file),
AR(is_dir),
AR(is_char),
AR(is_block),
AR(is_socket),
AR(is_link),
AR(is_fifo),
AR(mode),
AR(mtime),
{ "ctime", lua_stat_attr_read_ctime, NULL }, /* avoid poisoned ctime */
AR(atime),
AR(uid),
AR(gid),
AR(size),
AR(ino),
AR(dev),
{ NULL, NULL, NULL }
};
static int lua_stat_index(lua_State *L) {
struct stat *st;
const char *key;
int i;
if (lua_gettop(L) != 2) {
lua_pushstring(L, "incorrect number of arguments");
lua_error(L);
}
if (li_lua_metatable_index(L)) return 1;
st = li_lua_get_stat(L, 1);
if (!st) return 0;
if (lua_isnumber(L, 2)) return 0;
if (!lua_isstring(L, 2)) return 0;
key = lua_tostring(L, 2);
for (i = 0; stat_attribs[i].key ; i++) {
if (0 == strcmp(key, stat_attribs[i].key)) {
if (stat_attribs[i].read_attr)
return stat_attribs[i].read_attr(st, L);
break;
}
}
lua_pushstring(L, "cannot read attribute ");
lua_pushstring(L, key);
lua_pushstring(L, " in struct stat");
lua_concat(L, 3);
lua_error(L);
return 0;
}
static int lua_stat_newindex(lua_State *L) {
struct stat *st;
const char *key;
int i;
if (lua_gettop(L) != 3) {
lua_pushstring(L, "incorrect number of arguments");
lua_error(L);
}
st = li_lua_get_stat(L, 1);
if (!st) return 0;
if (lua_isnumber(L, 2)) return 0;
if (!lua_isstring(L, 2)) return 0;
key = lua_tostring(L, 2);
for (i = 0; stat_attribs[i].key ; i++) {
if (0 == strcmp(key, stat_attribs[i].key)) {
if (stat_attribs[i].write_attr)
return stat_attribs[i].write_attr(st, L);
break;
}
}
lua_pushstring(L, "cannot write attribute ");
lua_pushstring(L, key);
lua_pushstring(L, "in struct stat");
lua_concat(L, 3);
lua_error(L);
return 0;
}
static const luaL_Reg stat_mt[] = {
{ "__index", lua_stat_index },
{ "__newindex", lua_stat_newindex },
{ NULL, NULL }
};
static void init_stat_mt(lua_State *L) {
luaL_register(L, NULL, stat_mt);
}
void li_lua_init_stat_mt(lua_State *L) {
if (luaL_newmetatable(L, LUA_STAT)) {
init_stat_mt(L);
}
lua_pop(L, 1);
}
int li_lua_push_stat(lua_State *L, struct stat *st) {
struct stat *pst;
pst = (struct stat*) lua_newuserdata(L, sizeof(struct stat));
*pst = *st;
if (luaL_newmetatable(L, LUA_STAT)) {
init_stat_mt(L);
}
lua_setmetatable(L, -2);
return 1;
}

@ -130,7 +130,7 @@ liValue* li_value_from_lua(liServer *srv, lua_State *L) {
return NULL;
case LUA_TFUNCTION: {
liAction *a = lua_make_action(srv, L, -1);
liAction *a = lua_make_action(L, -1);
lua_pop(L, 1);
return li_value_new_action(srv, a);
}

@ -201,6 +201,50 @@ static int lua_vrequest_debug(lua_State *L) {
return 0;
}
static int lua_vrequest_stat(lua_State *L) {
liVRequest *vr;
GString *path;
const char *filename;
size_t filename_len;
liHandlerResult res;
int err = 0;
struct stat st;
if (lua_gettop(L) != 2) {
lua_pushstring(L, "vr:stat(filename): incorrect number of arguments");
lua_error(L);
}
vr = lua_get_vrequest(L, 1);
if (!vr || !lua_isstring(L, 2)) {
lua_pushstring(L, "vr:stat(filename): wrong argument types");
lua_error(L);
}
filename = lua_tolstring(L, 2, &filename_len);
path = g_string_new_len(filename, filename_len);
res = li_stat_cache_get(vr, path, &st, &err, NULL);
switch (res) {
case LI_HANDLER_GO_ON:
return li_lua_push_stat(L, &st);
case LI_HANDLER_WAIT_FOR_EVENT:
lua_pushinteger(L, res);
return 1;
case LI_HANDLER_ERROR:
lua_pushinteger(L, res);
lua_pushinteger(L, err);
lua_pushstring(L, g_strerror(err));
return 3;
case LI_HANDLER_COMEBACK:
VR_ERROR(vr, "%s", "Unexpected return value from li_stat_cache_get: LI_HANDLER_COMEBACK");
lua_pushinteger(L, LI_HANDLER_ERROR);
return 1;
}
return 0;
}
static int lua_vrequest_handle_direct(lua_State *L) {
liVRequest *vr;
vr = lua_get_vrequest(L, 1);
@ -219,6 +263,8 @@ static const luaL_Reg vrequest_mt[] = {
{ "info", lua_vrequest_info },
{ "debug", lua_vrequest_debug },
{ "stat", lua_vrequest_stat },
{ "handle_direct", lua_vrequest_handle_direct },
{ NULL, NULL }

@ -1,5 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# encoding: utf-8
"""
@ -71,6 +71,7 @@ def build(bld):
physical_lua.c
request_lua.c
response_lua.c
stat_lua.c
virtualrequest_lua.c
'''

Loading…
Cancel
Save