From 113c97d07a0658e18e615ad5ad52432baaaafb21 Mon Sep 17 00:00:00 2001 From: NADAL Jean-Baptiste Date: Sat, 18 Mar 2017 22:38:18 +0100 Subject: [PATCH] Bump libubox version 2016.11.29 --- .../package/libubox/libubox.mk | 2 +- src/3P/libubox/.gitignore | 1 + src/3P/libubox/blob.h | 4 +- src/3P/libubox/blobmsg.h | 2 +- src/3P/libubox/blobmsg_json.c | 2 +- src/3P/libubox/jshn.c | 2 +- src/3P/libubox/kvlist.h | 10 + src/3P/libubox/lua/CMakeLists.txt | 44 ++ src/3P/libubox/lua/uloop.c | 441 ++++++++++++++++++ src/3P/libubox/uloop.c | 1 + 10 files changed, 503 insertions(+), 6 deletions(-) create mode 100644 src/3P/libubox/lua/CMakeLists.txt create mode 100644 src/3P/libubox/lua/uloop.c diff --git a/bsp/buildroot_external/package/libubox/libubox.mk b/bsp/buildroot_external/package/libubox/libubox.mk index 865afa0b..b0a849cc 100644 --- a/bsp/buildroot_external/package/libubox/libubox.mk +++ b/bsp/buildroot_external/package/libubox/libubox.mk @@ -4,7 +4,7 @@ # ################################################################################ -LIBUBOX_VERSION:= 2016.07.29 +LIBUBOX_VERSION:= 2016-11-29 LIBUBOX_SITE = $(TOPDIR)/../../src/3P/libubox/builders/cmake LIBUBOX_SITE_METHOD = local diff --git a/src/3P/libubox/.gitignore b/src/3P/libubox/.gitignore index 0c59f966..5ffd2358 100644 --- a/src/3P/libubox/.gitignore +++ b/src/3P/libubox/.gitignore @@ -8,3 +8,4 @@ CMakeFiles install_manifest.txt jshn *-example +tests.* diff --git a/src/3P/libubox/blob.h b/src/3P/libubox/blob.h index ab077eab..307523d0 100644 --- a/src/3P/libubox/blob.h +++ b/src/3P/libubox/blob.h @@ -240,7 +240,7 @@ blob_put_u64(struct blob_buf *buf, int id, uint64_t val) #define blob_put_int64 blob_put_u64 #define __blob_for_each_attr(pos, attr, rem) \ - for (pos = (void *) attr; \ + for (pos = (struct blob_attr *) attr; \ rem > 0 && (blob_pad_len(pos) <= rem) && \ (blob_pad_len(pos) >= sizeof(struct blob_attr)); \ rem -= blob_pad_len(pos), pos = blob_next(pos)) @@ -248,7 +248,7 @@ blob_put_u64(struct blob_buf *buf, int id, uint64_t val) #define blob_for_each_attr(pos, attr, rem) \ for (rem = attr ? blob_len(attr) : 0, \ - pos = attr ? blob_data(attr) : 0; \ + pos = (struct blob_attr *) (attr ? blob_data(attr) : NULL); \ rem > 0 && (blob_pad_len(pos) <= rem) && \ (blob_pad_len(pos) >= sizeof(struct blob_attr)); \ rem -= blob_pad_len(pos), pos = blob_next(pos)) diff --git a/src/3P/libubox/blobmsg.h b/src/3P/libubox/blobmsg.h index 84997a67..861a4e8d 100644 --- a/src/3P/libubox/blobmsg.h +++ b/src/3P/libubox/blobmsg.h @@ -233,7 +233,7 @@ int blobmsg_printf(struct blob_buf *buf, const char *name, const char *format, . #define blobmsg_for_each_attr(pos, attr, rem) \ for (rem = attr ? blobmsg_data_len(attr) : 0, \ - pos = attr ? blobmsg_data(attr) : 0; \ + pos = (struct blob_attr *) (attr ? blobmsg_data(attr) : NULL); \ rem > 0 && (blob_pad_len(pos) <= rem) && \ (blob_pad_len(pos) >= sizeof(struct blob_attr)); \ rem -= blob_pad_len(pos), pos = blob_next(pos)) diff --git a/src/3P/libubox/blobmsg_json.c b/src/3P/libubox/blobmsg_json.c index 72d0de6e..8a6ed8f8 100644 --- a/src/3P/libubox/blobmsg_json.c +++ b/src/3P/libubox/blobmsg_json.c @@ -18,7 +18,7 @@ #include "blobmsg_json.h" #ifdef JSONC - #include + #include #else #include #endif diff --git a/src/3P/libubox/jshn.c b/src/3P/libubox/jshn.c index d396d8f6..49890994 100644 --- a/src/3P/libubox/jshn.c +++ b/src/3P/libubox/jshn.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef JSONC - #include + #include #else #include #endif diff --git a/src/3P/libubox/kvlist.h b/src/3P/libubox/kvlist.h index d59ff9e0..eaa691c2 100644 --- a/src/3P/libubox/kvlist.h +++ b/src/3P/libubox/kvlist.h @@ -18,6 +18,7 @@ #ifndef __LIBUBOX_KVLIST_H #define __LIBUBOX_KVLIST_H +#include "avl-cmp.h" #include "avl.h" struct kvlist { @@ -32,6 +33,15 @@ struct kvlist_node { char data[0] __attribute__((aligned(4))); }; +#define KVLIST_INIT(_name, _get_len) \ + { \ + .avl = AVL_TREE_INIT(_name.avl, avl_strcmp, false, NULL), \ + .get_len = _get_len \ + } + +#define KVLIST(_name, _get_len) \ + struct kvlist _name = KVLIST_INIT(_name, _get_len) + #define __ptr_to_kv(_ptr) container_of(((char *) (_ptr)), struct kvlist_node, data[0]) #define __avl_list_to_kv(_l) container_of(_l, struct kvlist_node, avl.list) diff --git a/src/3P/libubox/lua/CMakeLists.txt b/src/3P/libubox/lua/CMakeLists.txt new file mode 100644 index 00000000..34c9ab18 --- /dev/null +++ b/src/3P/libubox/lua/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 2.6) + +PROJECT(uloop C) + +SET(CMAKE_INSTALL_PREFIX /) + +IF(NOT LUA_CFLAGS) + pkg_search_module(LUA lua5.1 lua-5.1) +ENDIF() + +ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -g3 -I.. ${LUA_CFLAGS}) +LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/..) + +IF(APPLE) + SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -undefined dynamic_lookup") +ENDIF(APPLE) + +IF(NOT LUAPATH) + EXECUTE_PROCESS( + COMMAND lua -e "for k in string.gmatch(package.cpath .. \";\", \"([^;]+)/..so;\") do if k:sub(1,1) == \"/\" then print(k) break end end" + OUTPUT_VARIABLE LUAPATH + RESULT_VARIABLE LUA_CHECK_RES + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + IF(BUILD_LUA) + IF(NOT ${LUA_CHECK_RES} EQUAL 0 OR "${LUAPATH}" EQUAL "") + MESSAGE(SEND_ERROR "Lua was not found on your system") + ENDIF() + ENDIF() +ENDIF() + +IF(BUILD_LUA) + ADD_LIBRARY(uloop_lua MODULE uloop.c) + SET_TARGET_PROPERTIES(uloop_lua PROPERTIES + OUTPUT_NAME uloop + PREFIX "" + ) + TARGET_LINK_LIBRARIES(uloop_lua ubox) + + INSTALL(TARGETS uloop_lua + LIBRARY DESTINATION ${LUAPATH} + ) +ENDIF() diff --git a/src/3P/libubox/lua/uloop.c b/src/3P/libubox/lua/uloop.c new file mode 100644 index 00000000..c5dd12f0 --- /dev/null +++ b/src/3P/libubox/lua/uloop.c @@ -0,0 +1,441 @@ +/* + * Copyright (C) 2012 John Crispin + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include + +#include +#include +#include + +#include "../uloop.h" +#include "../list.h" + +struct lua_uloop_fd { + struct uloop_fd fd; + int r; + int fd_r; +}; + +struct lua_uloop_timeout { + struct uloop_timeout t; + int r; +}; + +struct lua_uloop_process { + struct uloop_process p; + int r; +}; + +static lua_State *state; + +static void * +ul_create_userdata(lua_State *L, size_t size, const luaL_Reg *reg, lua_CFunction gc) +{ + void *ret = lua_newuserdata(L, size); + + memset(ret, 0, size); + lua_createtable(L, 0, 2); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, gc); + lua_setfield(L, -2, "__gc"); + lua_pushvalue(L, -1); + lua_setmetatable(L, -3); + lua_pushvalue(L, -2); + luaI_openlib(L, NULL, reg, 1); + lua_pushvalue(L, -2); + + return ret; +} + +static void ul_timer_cb(struct uloop_timeout *t) +{ + struct lua_uloop_timeout *tout = container_of(t, struct lua_uloop_timeout, t); + + lua_getglobal(state, "__uloop_cb"); + lua_rawgeti(state, -1, tout->r); + lua_remove(state, -2); + + lua_call(state, 0, 0); + +} + +static int ul_timer_set(lua_State *L) +{ + struct lua_uloop_timeout *tout; + double set; + + if (!lua_isnumber(L, -1)) { + lua_pushstring(L, "invalid arg list"); + lua_error(L); + + return 0; + } + + set = lua_tointeger(L, -1); + tout = lua_touserdata(L, 1); + uloop_timeout_set(&tout->t, set); + + return 1; +} + +static int ul_timer_free(lua_State *L) +{ + struct lua_uloop_timeout *tout = lua_touserdata(L, 1); + + uloop_timeout_cancel(&tout->t); + + /* obj.__index.__gc = nil , make sure executing only once*/ + lua_getfield(L, -1, "__index"); + lua_pushstring(L, "__gc"); + lua_pushnil(L); + lua_settable(L, -3); + + lua_getglobal(state, "__uloop_cb"); + luaL_unref(state, -1, tout->r); + + return 1; +} + +static const luaL_Reg timer_m[] = { + { "set", ul_timer_set }, + { "cancel", ul_timer_free }, + { NULL, NULL } +}; + +static int ul_timer(lua_State *L) +{ + struct lua_uloop_timeout *tout; + int set = 0; + int ref; + + if (lua_isnumber(L, -1)) { + set = lua_tointeger(L, -1); + lua_pop(L, 1); + } + + if (!lua_isfunction(L, -1)) { + lua_pushstring(L, "invalid arg list"); + lua_error(L); + + return 0; + } + + lua_getglobal(L, "__uloop_cb"); + lua_pushvalue(L, -2); + ref = luaL_ref(L, -2); + + tout = ul_create_userdata(L, sizeof(*tout), timer_m, ul_timer_free); + tout->r = ref; + tout->t.cb = ul_timer_cb; + + if (set) + uloop_timeout_set(&tout->t, set); + + return 1; +} + +static void ul_ufd_cb(struct uloop_fd *fd, unsigned int events) +{ + struct lua_uloop_fd *ufd = container_of(fd, struct lua_uloop_fd, fd); + + lua_getglobal(state, "__uloop_cb"); + lua_rawgeti(state, -1, ufd->r); + lua_remove(state, -2); + + /* push fd object */ + lua_getglobal(state, "__uloop_fds"); + lua_rawgeti(state, -1, ufd->fd_r); + lua_remove(state, -2); + + /* push events */ + lua_pushinteger(state, events); + lua_call(state, 2, 0); +} + + +static int get_sock_fd(lua_State* L, int idx) { + int fd; + if(lua_isnumber(L, idx)) { + fd = lua_tonumber(L, idx); + } else { + luaL_checktype(L, idx, LUA_TUSERDATA); + lua_getfield(L, idx, "getfd"); + if(lua_isnil(L, -1)) + return luaL_error(L, "socket type missing 'getfd' method"); + lua_pushvalue(L, idx - 1); + lua_call(L, 1, 1); + fd = lua_tointeger(L, -1); + lua_pop(L, 1); + } + return fd; +} + +static int ul_ufd_delete(lua_State *L) +{ + struct lua_uloop_fd *ufd = lua_touserdata(L, 1); + + uloop_fd_delete(&ufd->fd); + + /* obj.__index.__gc = nil , make sure executing only once*/ + lua_getfield(L, -1, "__index"); + lua_pushstring(L, "__gc"); + lua_pushnil(L); + lua_settable(L, -3); + + lua_getglobal(state, "__uloop_cb"); + luaL_unref(state, -1, ufd->r); + lua_remove(state, -1); + + lua_getglobal(state, "__uloop_fds"); + luaL_unref(state, -1, ufd->fd_r); + lua_remove(state, -1); + + return 1; +} + +static const luaL_Reg ufd_m[] = { + { "delete", ul_ufd_delete }, + { NULL, NULL } +}; + +static int ul_ufd_add(lua_State *L) +{ + struct lua_uloop_fd *ufd; + int fd = 0; + unsigned int flags = 0; + int ref; + int fd_ref; + + if (lua_isnumber(L, -1)) { + flags = lua_tointeger(L, -1); + lua_pop(L, 1); + } + + if (!lua_isfunction(L, -1)) { + lua_pushstring(L, "invalid arg list"); + lua_error(L); + + return 0; + } + + fd = get_sock_fd(L, -2); + + lua_getglobal(L, "__uloop_cb"); + lua_pushvalue(L, -2); + ref = luaL_ref(L, -2); + lua_pop(L, 1); + + lua_getglobal(L, "__uloop_fds"); + lua_pushvalue(L, -3); + fd_ref = luaL_ref(L, -2); + lua_pop(L, 1); + + ufd = ul_create_userdata(L, sizeof(*ufd), ufd_m, ul_ufd_delete); + ufd->r = ref; + ufd->fd.fd = fd; + ufd->fd_r = fd_ref; + ufd->fd.cb = ul_ufd_cb; + if (flags) + uloop_fd_add(&ufd->fd, flags); + + return 1; +} + +static int ul_process_free(lua_State *L) +{ + struct lua_uloop_process *proc = lua_touserdata(L, 1); + + /* obj.__index.__gc = nil , make sure executing only once*/ + lua_getfield(L, -1, "__index"); + lua_pushstring(L, "__gc"); + lua_pushnil(L); + lua_settable(L, -3); + + if (proc->r != LUA_NOREF) { + uloop_process_delete(&proc->p); + + lua_getglobal(state, "__uloop_cb"); + luaL_unref(state, -1, proc->r); + lua_remove(state, -1); + } + + return 1; +} + +static const luaL_Reg process_m[] = { + { "delete", ul_process_free }, + { NULL, NULL } +}; + +static void ul_process_cb(struct uloop_process *p, int ret) +{ + struct lua_uloop_process *proc = container_of(p, struct lua_uloop_process, p); + + lua_getglobal(state, "__uloop_cb"); + lua_rawgeti(state, -1, proc->r); + + luaL_unref(state, -2, proc->r); + proc->r = LUA_NOREF; + lua_remove(state, -2); + lua_pushinteger(state, ret >> 8); + lua_call(state, 1, 0); +} + +static int ul_process(lua_State *L) +{ + struct lua_uloop_process *proc; + pid_t pid; + int ref; + + if (!lua_isfunction(L, -1) || !lua_istable(L, -2) || + !lua_istable(L, -3) || !lua_isstring(L, -4)) { + lua_pushstring(L, "invalid arg list"); + lua_error(L); + + return 0; + } + + pid = fork(); + + if (pid == -1) { + lua_pushstring(L, "failed to fork"); + lua_error(L); + + return 0; + } + + if (pid == 0) { + /* child */ + int argn = lua_objlen(L, -3); + int envn = lua_objlen(L, -2); + char** argp = malloc(sizeof(char*) * (argn + 2)); + char** envp = malloc(sizeof(char*) * (envn + 1)); + int i = 1; + + if (!argp || !envp) + _exit(-1); + + argp[0] = (char*) lua_tostring(L, -4); + for (i = 1; i <= argn; i++) { + lua_rawgeti(L, -3, i); + argp[i] = (char*) lua_tostring(L, -1); + lua_pop(L, 1); + } + argp[i] = NULL; + + for (i = 1; i <= envn; i++) { + lua_rawgeti(L, -2, i); + envp[i - 1] = (char*) lua_tostring(L, -1); + lua_pop(L, 1); + } + envp[i - 1] = NULL; + + execve(*argp, argp, envp); + _exit(-1); + } + + lua_getglobal(L, "__uloop_cb"); + lua_pushvalue(L, -2); + ref = luaL_ref(L, -2); + + proc = ul_create_userdata(L, sizeof(*proc), process_m, ul_process_free); + proc->r = ref; + proc->p.pid = pid; + proc->p.cb = ul_process_cb; + uloop_process_add(&proc->p); + + return 1; +} + +static int ul_init(lua_State *L) +{ + uloop_init(); + lua_pushboolean(L, 1); + + return 1; +} + +static int ul_run(lua_State *L) +{ + uloop_run(); + lua_pushboolean(L, 1); + + return 1; +} + +static int ul_end(lua_State *L) +{ + uloop_end(); + return 1; +} + +static luaL_reg uloop_func[] = { + {"init", ul_init}, + {"run", ul_run}, + {"timer", ul_timer}, + {"process", ul_process}, + {"fd_add", ul_ufd_add}, + {"cancel", ul_end}, + {NULL, NULL}, +}; + +/* avoid warnings about missing declarations */ +int luaopen_uloop(lua_State *L); +int luaclose_uloop(lua_State *L); + +int luaopen_uloop(lua_State *L) +{ + state = L; + + lua_createtable(L, 1, 0); + lua_setglobal(L, "__uloop_cb"); + + lua_createtable(L, 1, 0); + lua_setglobal(L, "__uloop_fds"); + + luaL_openlib(L, "uloop", uloop_func, 0); + lua_pushstring(L, "_VERSION"); + lua_pushstring(L, "1.0"); + lua_rawset(L, -3); + + lua_pushstring(L, "ULOOP_READ"); + lua_pushinteger(L, ULOOP_READ); + lua_rawset(L, -3); + + lua_pushstring(L, "ULOOP_WRITE"); + lua_pushinteger(L, ULOOP_WRITE); + lua_rawset(L, -3); + + lua_pushstring(L, "ULOOP_EDGE_TRIGGER"); + lua_pushinteger(L, ULOOP_EDGE_TRIGGER); + lua_rawset(L, -3); + + lua_pushstring(L, "ULOOP_BLOCKING"); + lua_pushinteger(L, ULOOP_BLOCKING); + lua_rawset(L, -3); + + return 1; +} + +int luaclose_uloop(lua_State *L) +{ + lua_pushstring(L, "Called"); + + return 1; +} diff --git a/src/3P/libubox/uloop.c b/src/3P/libubox/uloop.c index 296366e8..1c5bcee7 100644 --- a/src/3P/libubox/uloop.c +++ b/src/3P/libubox/uloop.c @@ -382,6 +382,7 @@ static void uloop_handle_processes(void) p->cb(p, ret); } } + } static void uloop_signal_wake(void)