初始化仓库

This commit is contained in:
2026-03-18 16:20:46 +08:00
parent 8ebf63008e
commit 20221fac5f
79 changed files with 35257 additions and 0 deletions

326
lib/lua_cj_api.cpp Executable file
View File

@ -0,0 +1,326 @@
#include "lua_cj_api.h"
extern "C"
{
#include <string.h>
#include "errors.h"
}
using namespace std;
bool check_luastatue(lua_State *L)
{
/*检查lua状态机状况*/
if(L == NULL)
{
errno = NAPI_LUA_STACK_ERROR;
return false;
}
//分为两部分写,防止空指针访问
if(lua_status(L) != LUA_OK)
{
errno = NAPI_LUA_STATE_ERROR;
return false;
}
return true;
}
int get_errno(void) { return errno; }//获取错误码
/// @brief 加载lua文件到lua虚拟栈
/// @param self 使用init_lua_runner初始化的lua_runner结构体指针
/// @param path 需要加载的脚本的位置
/// @param name module命名卸载库时指定
/// @return 0代表正常结束-1表示异常退出
int load_lib(void *selfd,const char *path,const char *name)
{
lua_runner* self = (lua_runner*)selfd;
Lua_runner *runner = (Lua_runner*)self->lua_obj;//还原对象
if(runner == NULL)
{
errno = NAPI_LUA_STATE_ERROR;
return -1;
}
if(runner->load_lib(path,name)==-1)
return -1;
return 0;
}
/// @brief 卸载lua虚拟栈中的lua文件
/// @param self 使用init_lua_runner初始化的lua_runner结构体指针
/// @param name module命名loadlib时的name
/// @return 0代表正常结束-1表示异常退出
int unload_lib(void *selfd,const char *name)
{
lua_runner* self = (lua_runner*)selfd;
Lua_runner *runner = (Lua_runner*)self->lua_obj;//还原对象
if(runner == NULL)
{
errno = NAPI_LUA_STATE_ERROR;
return -1;
}
if(runner->unload_lib(name)==-1)
return -1;
return 0;
}
/// @brief 运行脚本(可指定入参)
/// @param self 使用init_lua_runner初始化的lua_runner结构体指针
/// @param path 脚本的沙盒内路径
/// @param arg 脚本的入参
/// @return 0代表正常结束-1表示异常退出
int run(void *selfd,const char *path,const char *arg)
{
lua_runner* self = (lua_runner*)selfd;
//重定向输入到回调函数
Lua_runner *runner = (Lua_runner*)self->lua_obj;//还原对象
if(runner == NULL)
{
errno = NAPI_LUA_STATE_ERROR;
return -1;
}
if(runner->run(path,arg)==-1)
{
snprintf(self->result,MAX_RESULT,"%s",runner->reslt.c_str());
return -1;
}
snprintf(self->result,MAX_RESULT,"%s",runner->reslt.c_str());
return 0;
}
/// @brief 清理lua状态机缓存虚拟栈加载的包等
/// @param self 使用init_lua_runner初始化的lua_runner结构体指针
/// @return 0代表正常结束-1表示异常退出
int cleanup(void *selfd)
{
lua_runner* self = (lua_runner*)selfd;
Lua_runner *runner = (Lua_runner*)self->lua_obj;//还原对象
if(runner == NULL)
{
errno = NAPI_LUA_STATE_ERROR;
return -1;
}
if(runner->clean()==-1)
return -1;
return 0;
}
/// @brief 释放lua状态机资源
/// @param self 使用init_lua_runner初始化的lua_runner结构体指针
/// @return 0代表正常结束-1表示异常退出
int free_lua(void *selfd)
{
lua_runner* self = (lua_runner*)selfd;
delete((Lua_runner*)self->lua_obj);
free(self);
return 0;
}
/*-------------重定向io操作------------------------*/
static const char *full_path(lua_State *L, int isOut)
{
iopath *r = (iopath *)lua_getextraspace(L);
static char buf[512];
snprintf(buf, sizeof(buf), "%s/%s", r->iopath, isOut ? "output" : "input");
return buf;
}
//劫持读取终端输入,触发回调
static int l_tty_read(lua_State *L)
{
iopath *r = (iopath *)lua_getextraspace(L);
if (r->funcs.io_input) r->funcs.io_input();
const char *fname = full_path(L, 0);
FILE *fp = fopen(fname, "rb");
if (!fp) return luaL_error(L, "tty read open fail: %s", fname);
fseek(fp, 0, SEEK_END);
size_t sz = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *tmp = (char*)lua_newuserdata(L, sz);
if(0 ==fread(tmp, 1, sz, fp))
return luaL_error(L, "tty fail to read input: %s", fname);
fclose(fp);
if(remove(fname) != 0)
{
errno = NAPI_RESET_INPUT_FILE_ERROR;
return luaL_error(L, "fail to reset input file: %s", fname);
}
lua_pushlstring(L, tmp, sz);
return 1;
}
//劫持到终端输出,输出结束触发回调
static int l_tty_write(lua_State *L)
{
iopath *r = (iopath *)lua_getextraspace(L);
const char *fname = full_path(L, 1);
FILE *fp = fopen(fname, "a");
if (!fp) return luaL_error(L, "tty write open fail: %s", fname);
int n = lua_gettop(L);
for (int i = 1; i <= n; ++i)
if (lua_isstring(L, i)) fputs(lua_tostring(L, i), fp);
fclose(fp);
if (r->funcs.io_output) r->funcs.io_output();
return 0;
}
static int l_print(lua_State *L) {
iopath *r = (iopath *)lua_getextraspace(L);
const char *fname = full_path(L, 1); // 输出到 output 文件
FILE *fp = fopen(fname, "a");
if (!fp) return luaL_error(L, "print redirect open fail: %s", fname);
int n = lua_gettop(L);
for (int i = 1; i <= n; ++i) {
if (i > 1) fputc('\t', fp);
const char *str = luaL_tolstring(L, i, NULL);
fputs(str, fp);
lua_pop(L, 1);
}
fputc('\n', fp);
fclose(fp);
if (r->funcs.io_output) r->funcs.io_output();
return 0;
}
/*空实现*/
static int l_tty_flush(lua_State *L)
{
(void)L;
return 0;
}
static int l_tty_close(lua_State *L)
{
(void)L;
return 0;
}
/*空实现(不需要)*/
static int l_tty_call(lua_State *L)
{
// 当尝试调用tty对象时返回自身或执行某些操作
lua_pushvalue(L, 1); // 返回对象自身
return 1;
}
static void push_tty_file(lua_State *L, int isout, const luaL_Reg *fake_tty_meta)
{
lua_newuserdata(L, sizeof(int));
luaL_newmetatable(L, isout ? "tty_out" : "tty_in");
luaL_setfuncs(L, fake_tty_meta, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
// 添加__call元方法
lua_pushcfunction(L, l_tty_call);
lua_setfield(L, -2, "__call");
// 添加__tostring
lua_pushstring(L, isout ? "TTY_OUT" : "TTY_IN");
lua_setfield(L, -2, "__tostring");
lua_setmetatable(L, -2);
}
int redirecct_path(lua_State *L)
{
if(!check_luastatue(L)){
errno = NAPI_LUA_STATE_ERROR;
return -1;
}
iopath *p = (iopath*)lua_getextraspace(L);
static const luaL_Reg fake_methods[] = {
{"read", l_tty_read},
{"write", l_tty_write},
{"flush", l_tty_flush},
{"close", l_tty_close},
{NULL, NULL}
};
/* 1. 把 io.output() 换成 tty 替身 */
push_tty_file(L, 1,fake_methods);
lua_getglobal(L, "io");
lua_pushvalue(L, -2);
lua_setfield(L, -2, "output"); /* io.output = 替身 */
lua_pop(L, 2);
/* 2. 把 io.input() 换成 tty 替身 */
push_tty_file(L, 0,fake_methods);
lua_getglobal(L, "io");
lua_pushvalue(L, -2);
lua_setfield(L, -2, "input"); /* io.input = 替身 */
lua_pop(L, 2);
lua_pushcfunction(L, l_print);
lua_setglobal(L, "print");
lua_getglobal(L, "io");
lua_pushcfunction(L, l_tty_read);
lua_setfield(L, -2, "read");
lua_pushcfunction(L, l_tty_write);
lua_setfield(L, -2, "write");
lua_pop(L, 1);
return 0;
}
/*----------------重定向io操作------------------------*/
//获取对象中的返回值
char *getresult(void *selfd){lua_runner*self =(lua_runner*) selfd;return self->result;}
/// @brief 初始化lua解释器
/// @param self lua_runner结构体指针
/// @param pathio 重定向io目录
/// @param pkgpath 用户包搜索目录
/// @param funcs 重定向回调函数
/// @return 0正常结束-1异常退出
void *init_lua_runner(const char *pathio,const char *pkgpath,int(*input)(),int(*output)())//该函数挂载到cj构造函数中执行
{
//分配内存
lua_runner *self = (lua_runner*)malloc(sizeof(lua_runner));
//创建对象
self->lua_obj = (void*)new Lua_runner(pkgpath);
if(errno != 0)
return NULL;
if(self->lua_obj == NULL)
{
errno = NAPI_LUA_CLASS_LOST;
return NULL;
}
//提取对象
Lua_runner *runner = (Lua_runner*)self->lua_obj;
//提取lua状态机
lua_State *L = runner->get_lua_State();
if(!check_luastatue(L)){
errno = NAPI_LUA_STATE_ERROR;
return NULL;
}
//申请额外空间
iopath *io_path = (iopath*)lua_getextraspace(L);
if(io_path == NULL){
errno = NAPI_ERROR_FUNCS;
return NULL;
}
if(pathio == NULL)
{
errno = NAPI_LUA_MISS_REDIRECT;
return NULL;
}
//装载重定向函数
io_path->funcs.io_input = input;
io_path->funcs.io_output = output;
//装载重定向路径
strcpy(io_path->iopath,pathio);
//注册重定向
if(redirecct_path(L)==-1){
errno = NAPI_LUA_STATE_ERROR;
return NULL;
}
return (void*)self;
}