Skip to content

Instantly share code, notes, and snippets.

@furandon-pig
Last active December 31, 2018 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save furandon-pig/764cf2aa763d62226afe3284aae926a0 to your computer and use it in GitHub Desktop.
Save furandon-pig/764cf2aa763d62226afe3284aae926a0 to your computer and use it in GitHub Desktop.
NetBSDのLuaカーネルモジュールサンプルです。
/*-
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/lua.h>
#include <sys/module.h>
#include <lua.h>
#include <lauxlib.h>
/*
* To use this device you need to do:
* mknod /dev/happy c 210 0
*/
dev_type_open(luaread_open);
dev_type_close(luaread_close);
dev_type_read(luaread_read);
static struct cdevsw luaread_cdevsw = {
.d_open = luaread_open,
.d_close = luaread_close,
.d_read = luaread_read,
.d_write = nowrite,
.d_ioctl = noioctl,
.d_stop = nostop,
.d_tty = notty,
.d_poll = nopoll,
.d_mmap = nommap,
.d_kqfilter = nokqfilter,
.d_discard = nodiscard,
.d_flag = D_OTHER
};
struct luaread_softc {
int refcnt;
unsigned last;
klua_State *kL;
};
static struct luaread_softc sc;
static int
luaopen_systm(lua_State *L)
{
const luaL_Reg systm_lib[] = {
{ NULL, NULL }
};
luaL_newlib(sc.kL->L, systm_lib);
lua_pushstring(sc.kL->L, copyright);
lua_setfield(sc.kL->L, -2, "copyright");
return 1;
}
int
luaread_open(dev_t self __unused, int flag __unused, int mode __unused,
struct lwp *l __unused)
{
printf("-=> luaread_open()\n");
if (sc.refcnt > 0)
return EBUSY;
sc.last = 0;
++sc.refcnt;
return 0;
}
int
luaread_close(dev_t self __unused, int flag __unused, int mode __unused,
struct lwp *l __unused)
{
printf("-=> luaread_close()\n");
--sc.refcnt;
return 0;
}
int
luaread_read(dev_t self __unused, struct uio *uio, int flags __unused)
{
int len;
int e;
printf("-=> luaread_read()\n");
klua_lock(sc.kL);
lua_getglobal(sc.kL->L, "myread");
if (!lua_isfunction(sc.kL->L, -1)) {
printf("-=> fail: lua_isfunction()\n");
lua_pop(sc.kL->L, 1);
klua_unlock(sc.kL);
return -1;
}
if (lua_pcall(sc.kL->L, 0 /* args */, 1 /* res */, 0) != 0) {
printf("-=> fail: lua_pcall()\n");
lua_pop(sc.kL->L, 2);
klua_unlock(sc.kL);
return -1;
}
if (!lua_isstring(sc.kL->L, -1)) {
printf("-=> fail: lua_isstring()\n");
lua_pop(sc.kL->L, 2);
klua_unlock(sc.kL);
return -1;
}
char line[256];
strncpy(line, lua_tostring(sc.kL->L, -1), 254);
line[255] = '\0';
/* Send it to User-Space */
if ((e = uiomove(line, len, uio)))
return e;
return 0;
}
MODULE(MODULE_CLASS_MISC, luaread, "lua");
static int
luaread_modcmd(modcmd_t cmd, void *arg __unused)
{
/* The major should be verified and changed if needed to avoid
* conflicts with other devices. */
int cmajor = 210, bmajor = -1;
switch (cmd) {
case MODULE_CMD_INIT:
printf("-=> MODULE_CMD_INIT\n"); // XXX debug
klua_mod_register("luaread", luaopen_systm);
if (devsw_attach("luaread", NULL, &bmajor, &luaread_cdevsw,
&cmajor))
return ENXIO;
if ((sc.kL = kluaL_newstate("luaread",
"Lua read/write sample",
IPL_NONE)) == NULL) {
devsw_detach(NULL, &luaread_cdevsw);
return ENXIO;
}
return 0;
case MODULE_CMD_FINI:
if (sc.refcnt > 0)
return EBUSY;
klua_mod_unregister("luaread");
klua_close(sc.kL);
devsw_detach(NULL, &luaread_cdevsw);
return 0;
default:
return ENOTTY;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment