178527Sassar/* $NetBSD: lua.c,v 1.28 2022/03/31 19:30:17 pgoyette Exp $ */ 2233294Sstas 3233294Sstas/* 4233294Sstas * Copyright (c) 2011 - 2017 by Marc Balmer <mbalmer@NetBSD.org>. 578527Sassar * Copyright (c) 2014 by Lourival Vieira Neto <lneto@NetBSD.org>. 6233294Sstas * All rights reserved. 7233294Sstas * 8233294Sstas * Redistribution and use in source and binary forms, with or without 978527Sassar * modification, are permitted provided that the following conditions 10233294Sstas * are met: 11233294Sstas * 1. Redistributions of source code must retain the above copyright 1278527Sassar * notice, this list of conditions and the following disclaimer. 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1678527Sassar * 3. The name of the Author may not be used to endorse or promote products 17233294Sstas * derived from this software without specific prior written permission. 18233294Sstas * 19233294Sstas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2078527Sassar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29233294Sstas * SUCH DAMAGE. 30233294Sstas */ 31233294Sstas 3278527Sassar/* Lua device driver */ 3378527Sassar 34233294Sstas#include <sys/param.h> 3578527Sassar#include <sys/fcntl.h> 3678527Sassar#include <sys/conf.h> 3778527Sassar#include <sys/condvar.h> 3878527Sassar#include <sys/device.h> 3978527Sassar#include <sys/ioctl.h> 4078527Sassar#include <sys/kmem.h> 4178527Sassar#include <sys/lock.h> 4278527Sassar#include <sys/lua.h> 43102644Snectar#include <sys/module.h> 4478527Sassar#include <sys/mutex.h> 45102644Snectar#include <sys/namei.h> 46102644Snectar#include <sys/queue.h> 47102644Snectar#include <sys/sysctl.h> 48102644Snectar#include <sys/vnode.h> 49102644Snectar#include <sys/cpu.h> 50178825Sdfr 51178825Sdfr#include <lauxlib.h> 52178825Sdfr 5378527Sassar#include "luavar.h" 54102644Snectar 55233294Sstasstruct lua_softc { 56102644Snectar device_t sc_dev; 57102644Snectar 58233294Sstas kmutex_t sc_lock; 59102644Snectar kcondvar_t sc_inuse_cv; 60102644Snectar bool sc_inuse; 61233294Sstas 62102644Snectar /* Locking access to state queues */ 6390926Snectar kmutex_t sc_state_lock; 6478527Sassar kcondvar_t sc_state_cv; 65 bool sc_state; 66 67 struct sysctllog *sc_log; 68}; 69 70static device_t sc_self; 71static bool lua_autoload_on = true; 72static bool lua_require_on = true; 73static bool lua_bytecode_on = false; 74static int lua_verbose; 75static int lua_max_instr; 76 77static LIST_HEAD(, lua_state) lua_states = 78 LIST_HEAD_INITIALIZER(lua_states); 79static LIST_HEAD(, lua_module) lua_modules = 80 LIST_HEAD_INITIALIZER(lua_modules); 81 82static int lua_match(device_t, cfdata_t, void *); 83static void lua_attach(device_t, device_t, void *); 84static int lua_detach(device_t, int); 85static klua_State *klua_find(const char *); 86static const char *lua_reader(lua_State *, void *, size_t *); 87static void lua_maxcount(lua_State *, lua_Debug *); 88 89static int lua_require(lua_State *); 90 91CFATTACH_DECL_NEW(lua, sizeof(struct lua_softc), 92 lua_match, lua_attach, lua_detach, NULL); 93 94dev_type_open(luaopen); 95dev_type_close(luaclose); 96dev_type_ioctl(luaioctl); 97 98const struct cdevsw lua_cdevsw = { 99 .d_open = luaopen, 100 .d_close = luaclose, 101 .d_read = noread, 102 .d_write = nowrite, 103 .d_ioctl = luaioctl, 104 .d_stop = nostop, 105 .d_tty = notty, 106 .d_poll = nopoll, 107 .d_mmap = nommap, 108 .d_kqfilter = nokqfilter, 109 .d_discard = nodiscard, 110 .d_flag = D_OTHER | D_MPSAFE 111}; 112 113struct lua_loadstate { 114 struct vnode *vp; 115 size_t size; 116 off_t off; 117}; 118 119extern struct cfdriver lua_cd; 120 121static int 122lua_match(device_t parent, cfdata_t match, void *aux) 123{ 124 return 1; 125} 126 127static void 128lua_attach(device_t parent, device_t self, void *aux) 129{ 130 struct lua_softc *sc; 131 const struct sysctlnode *node; 132 133 if (sc_self) 134 return; 135 136 sc = device_private(self); 137 sc->sc_dev = self; 138 sc_self = self; 139 140 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 141 cv_init(&sc->sc_inuse_cv, "luactl"); 142 143 mutex_init(&sc->sc_state_lock, MUTEX_DEFAULT, IPL_VM); 144 cv_init(&sc->sc_state_cv, "luastate"); 145 146 if (!pmf_device_register(self, NULL, NULL)) 147 aprint_error_dev(self, "couldn't establish power handler\n"); 148 149 /* Sysctl to provide some control over behaviour */ 150 sysctl_createv(&sc->sc_log, 0, NULL, &node, 151 CTLFLAG_OWNDESC, 152 CTLTYPE_NODE, "lua", 153 SYSCTL_DESCR("Lua options"), 154 NULL, 0, NULL, 0, 155 CTL_KERN, CTL_CREATE, CTL_EOL); 156 157 if (node == NULL) { 158 aprint_error(": can't create sysctl node\n"); 159 return; 160 } 161 162 /* 163 * XXX Some of the sysctl values must not be changed after the 164 * securelevel has been raised. 165 */ 166 sysctl_createv(&sc->sc_log, 0, &node, NULL, 167 CTLFLAG_READWRITE | CTLFLAG_OWNDESC, 168 CTLTYPE_BOOL, "require", 169 SYSCTL_DESCR("Enable the require command"), 170 NULL, 0, &lua_require_on, 0, 171 CTL_CREATE, CTL_EOL); 172 173 sysctl_createv(&sc->sc_log, 0, &node, NULL, 174 CTLFLAG_READWRITE | CTLFLAG_OWNDESC, 175 CTLTYPE_BOOL, "autoload", 176 SYSCTL_DESCR("Enable automatic load of modules"), 177 NULL, 0, &lua_autoload_on, 0, 178 CTL_CREATE, CTL_EOL); 179 180 sysctl_createv(&sc->sc_log, 0, &node, NULL, 181 CTLFLAG_READWRITE | CTLFLAG_OWNDESC, 182 CTLTYPE_BOOL, "bytecode", 183 SYSCTL_DESCR("Enable loading of bytecode"), 184 NULL, 0, &lua_bytecode_on, 0, 185 CTL_CREATE, CTL_EOL); 186 187 sysctl_createv(&sc->sc_log, 0, &node, NULL, 188 CTLFLAG_READWRITE | CTLFLAG_OWNDESC, 189 CTLTYPE_INT, "verbose", 190 SYSCTL_DESCR("Enable verbose output"), 191 NULL, 0, &lua_verbose, 0, 192 CTL_CREATE, CTL_EOL); 193 194 sysctl_createv(&sc->sc_log, 0, &node, NULL, 195 CTLFLAG_READWRITE | CTLFLAG_OWNDESC, 196 CTLTYPE_INT, "maxcount", 197 SYSCTL_DESCR("Limit maximum instruction count"), 198 NULL, 0, &lua_max_instr, 0, 199 CTL_CREATE, CTL_EOL); 200 201 aprint_normal_dev(self, "%s\n", LUA_COPYRIGHT); 202} 203 204static int 205lua_detach(device_t self, int flags) 206{ 207 struct lua_softc *sc; 208 struct lua_state *s; 209 210 sc = device_private(self); 211 pmf_device_deregister(self); 212 213 if (sc->sc_log != NULL) { 214 sysctl_teardown(&sc->sc_log); 215 sc->sc_log = NULL; 216 } 217 218 /* Traverse the list of states and close them */ 219 while ((s = LIST_FIRST(&lua_states)) != NULL) { 220 LIST_REMOVE(s, lua_next); 221 klua_close(s->K); 222 if (lua_verbose) 223 device_printf(self, "state %s destroyed\n", 224 s->lua_name); 225 kmem_free(s, sizeof(struct lua_state)); 226 } 227 mutex_destroy(&sc->sc_lock); 228 cv_destroy(&sc->sc_inuse_cv); 229 mutex_destroy(&sc->sc_state_lock); 230 cv_destroy(&sc->sc_state_cv); 231 sc_self = NULL; 232 return 0; 233} 234 235int 236luaopen(dev_t dev, int flag, int mode, struct lwp *l) 237{ 238 struct lua_softc *sc; 239 int error = 0; 240 241 if (minor(dev) > 0) 242 return ENXIO; 243 244 sc = device_lookup_private(&lua_cd, minor(dev)); 245 if (sc == NULL) 246 return ENXIO; 247 248 mutex_enter(&sc->sc_lock); 249 while (sc->sc_inuse == true) { 250 error = cv_wait_sig(&sc->sc_inuse_cv, &sc->sc_lock); 251 if (error) 252 break; 253 } 254 if (!error) 255 sc->sc_inuse = true; 256 mutex_exit(&sc->sc_lock); 257 258 if (error) 259 return error; 260 return 0; 261} 262 263int 264luaclose(dev_t dev, int flag, int mode, struct lwp *l) 265{ 266 struct lua_softc *sc; 267 268 if (minor(dev) > 0) 269 return ENXIO; 270 sc = device_lookup_private(&lua_cd, minor(dev)); 271 mutex_enter(&sc->sc_lock); 272 sc->sc_inuse = false; 273 cv_signal(&sc->sc_inuse_cv); 274 mutex_exit(&sc->sc_lock); 275 return 0; 276} 277 278int 279luaioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 280{ 281 struct lua_softc *sc; 282 struct lua_info *info; 283 struct lua_create *create; 284 struct lua_require *require; 285 struct lua_load *load; 286 struct lua_state *s; 287 struct lua_module *m; 288 kauth_cred_t cred; 289 struct vnode *vp; 290 struct pathbuf *pb; 291 struct vattr va; 292 struct lua_loadstate ls; 293 struct lua_state_info *states; 294 int error, n; 295 klua_State *K; 296 297 sc = device_lookup_private(&lua_cd, minor(dev)); 298 if (!device_is_active(sc->sc_dev)) 299 return EBUSY; 300 301 switch (cmd) { 302 case LUAINFO: 303 info = data; 304 if (info->states == NULL) { 305 info->num_states = 0; 306 LIST_FOREACH(s, &lua_states, lua_next) 307 info->num_states++; 308 } else { 309 n = 0; 310 LIST_FOREACH(s, &lua_states, lua_next) { 311 if (n > info->num_states) 312 break; 313 n++; 314 } 315 info->num_states = n; 316 states = kmem_alloc(sizeof(*states) * n, KM_SLEEP); 317 if (copyin(info->states, states, sizeof(*states) * n) 318 == 0) { 319 n = 0; 320 LIST_FOREACH(s, &lua_states, lua_next) { 321 if (n > info->num_states) 322 break; 323 strcpy(states[n].name, s->lua_name); 324 strcpy(states[n].desc, s->lua_desc); 325 states[n].user = s->K->ks_user; 326 n++; 327 } 328 copyout(states, info->states, 329 sizeof(*states) * n); 330 kmem_free(states, sizeof(*states) * n); 331 } 332 } 333 break; 334 case LUACREATE: 335 create = data; 336 337 if (*create->name == '_') { 338 if (lua_verbose) 339 device_printf(sc->sc_dev, "names of user " 340 "created states must not begin with '_'"); 341 return ENXIO; 342 } 343 LIST_FOREACH(s, &lua_states, lua_next) 344 if (!strcmp(s->lua_name, create->name)) { 345 if (lua_verbose) 346 device_printf(sc->sc_dev, 347 "state %s exists\n", create->name); 348 return EBUSY; 349 } 350 351 K = kluaL_newstate(create->name, create->desc, IPL_NONE); 352 353 if (K == NULL) 354 return ENOMEM; 355 356 K->ks_user = true; 357 358 if (lua_verbose) 359 device_printf(sc->sc_dev, "state %s created\n", 360 create->name); 361 break; 362 case LUADESTROY: 363 create = data; 364 365 K = klua_find(create->name); 366 367 if (K != NULL && (K->ks_user == true)) { 368 klua_close(K); 369 return 0; 370 } 371 return EBUSY; 372 case LUAREQUIRE: /* 'require' a module in a State */ 373 require = data; 374 LIST_FOREACH(s, &lua_states, lua_next) 375 if (!strcmp(s->lua_name, require->state)) { 376 LIST_FOREACH(m, &s->lua_modules, mod_next) 377 if (!strcmp(m->mod_name, require->module)) 378 return ENXIO; 379 LIST_FOREACH(m, &lua_modules, mod_next) 380 if (!strcmp(m->mod_name, 381 require->module)) { 382 if (lua_verbose) 383 device_printf( 384 sc->sc_dev, 385 "requiring module " 386 "%s to state %s\n", 387 m->mod_name, 388 s->lua_name); 389 klua_lock(s->K); 390 luaL_requiref( 391 s->K->L, 392 m->mod_name, 393 m->open, 394 1); 395 klua_unlock(s->K); 396 m->refcount++; 397 LIST_INSERT_HEAD( 398 &s->lua_modules, m, 399 mod_next); 400 return 0; 401 } 402 } 403 return ENXIO; 404 case LUALOAD: 405 load = data; 406 if (strrchr(load->path, '/') == NULL) 407 return ENXIO; 408 409 LIST_FOREACH(s, &lua_states, lua_next) 410 if (!strcmp(s->lua_name, load->state)) { 411 if (lua_verbose) 412 device_printf(sc->sc_dev, 413 "loading %s into state %s\n", 414 load->path, s->lua_name); 415 cred = kauth_cred_get(); 416 pb = pathbuf_create(load->path); 417 if (pb == NULL) 418 return ENOMEM; 419 error = vn_open(NULL, pb, NOCHROOT, FREAD, 0, 420 &vp, NULL, NULL); 421 pathbuf_destroy(pb); 422 if (error) { 423 if (lua_verbose) 424 device_printf(sc->sc_dev, 425 "error vn_open %d\n", 426 error); 427 return error; 428 } 429 error = VOP_GETATTR(vp, &va, 430 kauth_cred_get()); 431 if (error) { 432 VOP_UNLOCK(vp); 433 vn_close(vp, FREAD, 434 kauth_cred_get()); 435 if (lua_verbose) 436 device_printf(sc->sc_dev, 437 "erro VOP_GETATTR %d\n", 438 error); 439 return error; 440 } 441 if (va.va_type != VREG) { 442 VOP_UNLOCK(vp); 443 vn_close(vp, FREAD, 444 kauth_cred_get()); 445 return EINVAL; 446 } 447 ls.vp = vp; 448 ls.off = 0L; 449 ls.size = va.va_size; 450 VOP_UNLOCK(vp); 451 klua_lock(s->K); 452 error = lua_load(s->K->L, lua_reader, &ls, 453 strrchr(load->path, '/') + 1, "bt"); 454 vn_close(vp, FREAD, cred); 455 switch (error) { 456 case 0: /* no error */ 457 break; 458 case LUA_ERRSYNTAX: 459 if (lua_verbose) 460 device_printf(sc->sc_dev, 461 "syntax error\n"); 462 klua_unlock(s->K); 463 return EINVAL; 464 case LUA_ERRMEM: 465 if (lua_verbose) 466 device_printf(sc->sc_dev, 467 "memory error\n"); 468 klua_unlock(s->K); 469 return ENOMEM; 470 default: 471 if (lua_verbose) 472 device_printf(sc->sc_dev, 473 "load error %d: %s\n", 474 error, 475 lua_tostring(s->K->L, -1)); 476 klua_unlock(s->K); 477 return EINVAL; 478 } 479 if (lua_max_instr > 0) 480 lua_sethook(s->K->L, lua_maxcount, 481 LUA_MASKCOUNT, lua_max_instr); 482 error = lua_pcall(s->K->L, 0, LUA_MULTRET, 0); 483 if (error) { 484 if (lua_verbose) { 485 device_printf(sc->sc_dev, 486 "execution error: %s\n", 487 lua_tostring(s->K->L, -1)); 488 } 489 klua_unlock(s->K); 490 return EINVAL; 491 } 492 klua_unlock(s->K); 493 return 0; 494 } 495 return ENXIO; 496 } 497 return 0; 498} 499 500static int 501lua_require(lua_State *L) 502{ 503 struct lua_state *s; 504 struct lua_module *m, *md; 505 const char *module; 506 char name[MAXPATHLEN]; 507 508 module = lua_tostring(L, -1); 509 md = NULL; 510 LIST_FOREACH(m, &lua_modules, mod_next) 511 if (!strcmp(m->mod_name, module)) { 512 md = m; 513 break; 514 } 515 516 if (md == NULL && lua_autoload_on && strchr(module, '/') == NULL) { 517 snprintf(name, sizeof name, "lua%s", module); 518 if (lua_verbose) 519 device_printf(sc_self, "autoload %s\n", name); 520 module_autoload(name, MODULE_CLASS_MISC); 521 LIST_FOREACH(m, &lua_modules, mod_next) 522 if (!strcmp(m->mod_name, module)) { 523 md = m; 524 break; 525 } 526 } 527 528 if (md != NULL) 529 LIST_FOREACH(s, &lua_states, lua_next) 530 if (s->K->L == L) { 531 if (lua_verbose) 532 device_printf(sc_self, 533 "require module %s\n", 534 md->mod_name); 535 luaL_requiref(L, md->mod_name, md->open, 0); 536 537 LIST_FOREACH(m, &s->lua_modules, mod_next) 538 if (m == md) 539 return 1; 540 541 md->refcount++; 542 LIST_INSERT_HEAD(&s->lua_modules, md, mod_next); 543 return 1; 544 } 545 546 lua_pushstring(L, "module not found"); 547 return lua_error(L); 548} 549 550typedef struct { 551 size_t size; 552} alloc_header_t; 553 554static void * 555lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) 556{ 557 void *nptr = NULL; 558 559 /* 560 * Make sure that buffers allocated by lua_alloc() are aligned to 561 * 8-byte boundaries as done by kmem_alloc(9). 562 */ 563 const size_t hdr_size = roundup(sizeof(alloc_header_t), 8); 564 alloc_header_t *hdr = (alloc_header_t *) ((char *) ptr - hdr_size); 565 566 if (nsize == 0) { /* freeing */ 567 if (ptr != NULL) 568 kmem_intr_free(hdr, hdr->size); 569 } else if (ptr != NULL && nsize <= hdr->size - hdr_size) /* shrinking */ 570 return ptr; /* don't need to reallocate */ 571 else { /* creating or expanding */ 572 km_flag_t sleep = cpu_intr_p() || cpu_softintr_p() ? 573 KM_NOSLEEP : KM_SLEEP; 574 575 size_t alloc_size = nsize + hdr_size; 576 alloc_header_t *nhdr = kmem_intr_alloc(alloc_size, sleep); 577 if (nhdr == NULL) /* failed to allocate */ 578 return NULL; 579 580 nhdr->size = alloc_size; 581 nptr = (void *) ((char *) nhdr + hdr_size); 582 583 if (ptr != NULL) { /* expanding */ 584 memcpy(nptr, ptr, osize); 585 kmem_intr_free(hdr, hdr->size); 586 } 587 } 588 return nptr; 589} 590 591static const char * 592lua_reader(lua_State *L, void *data, size_t *size) 593{ 594 struct lua_loadstate *ls; 595 static char buf[1024]; 596 size_t rsiz; 597 598 ls = data; 599 if (ls->size < sizeof(buf)) 600 rsiz = ls->size; 601 else 602 rsiz = sizeof(buf); 603 vn_rdwr(UIO_READ, ls->vp, buf, rsiz, ls->off, UIO_SYSSPACE, 604 0, curlwp->l_cred, NULL, curlwp); 605 if (ls->off == 0L && lua_bytecode_on == false && buf[0] == 0x1b) { 606 *size = 0L; 607 lua_pushstring(L, "loading of bytecode is not allowed"); 608 lua_error(L); 609 return NULL; 610 } else { 611 *size = rsiz; 612 ls->off += *size; 613 ls->size -= *size; 614 } 615 return buf; 616} 617 618static void 619lua_maxcount(lua_State *L, lua_Debug *d) 620{ 621 lua_pushstring(L, "maximum instruction count exceeded"); 622 lua_error(L); 623} 624 625int 626klua_mod_register(const char *name, lua_CFunction open) 627{ 628 struct lua_module *m; 629 630 LIST_FOREACH(m, &lua_modules, mod_next) 631 if (!strcmp(m->mod_name, name)) 632 return EBUSY; 633 m = kmem_zalloc(sizeof(struct lua_module), KM_SLEEP); 634 strlcpy(m->mod_name, name, LUA_MAX_MODNAME); 635 m->open = open; 636 m->refcount = 0; 637 LIST_INSERT_HEAD(&lua_modules, m, mod_next); 638 if (lua_verbose) 639 device_printf(sc_self, "registered lua module %s\n", name); 640 return 0; 641} 642 643int 644klua_mod_unregister(const char *name) 645{ 646 struct lua_module *m; 647 648 LIST_FOREACH(m, &lua_modules, mod_next) 649 if (!strcmp(m->mod_name, name)) { 650 if (m->refcount == 0) { 651 LIST_REMOVE(m, mod_next); 652 kmem_free(m, sizeof(struct lua_module)); 653 if (lua_verbose) 654 device_printf(sc_self, 655 "unregistered lua module %s\n", 656 name); 657 return 0; 658 } else 659 return EBUSY; 660 } 661 return 0; 662} 663 664klua_State * 665klua_newstate(lua_Alloc f, void *ud, const char *name, const char *desc, 666 int ipl) 667{ 668 klua_State *K; 669 struct lua_state *s; 670 struct lua_softc *sc; 671 int error = 0; 672 673 s = kmem_zalloc(sizeof(struct lua_state), KM_SLEEP); 674 sc = device_private(sc_self); 675 mutex_enter(&sc->sc_state_lock); 676 while (sc->sc_state == true) { 677 error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock); 678 if (error) 679 break; 680 } 681 if (!error) 682 sc->sc_state = true; 683 mutex_exit(&sc->sc_state_lock); 684 685 if (error) { 686 kmem_free(s, sizeof(struct lua_state)); 687 return NULL; 688 } 689 690 K = kmem_zalloc(sizeof(klua_State), KM_SLEEP); 691 K->L = lua_newstate(f, ud); 692 K->ks_user = false; 693 if (K->L == NULL) { 694 kmem_free(K, sizeof(klua_State)); 695 K = NULL; 696 goto finish; 697 } 698 699 strlcpy(s->lua_name, name, MAX_LUA_NAME); 700 strlcpy(s->lua_desc, desc, MAX_LUA_DESC); 701 s->K = K; 702 703 if (lua_require_on || lua_autoload_on) { 704 lua_pushcfunction(K->L, lua_require); 705 lua_setglobal(K->L, "require"); 706 } 707 LIST_INSERT_HEAD(&lua_states, s, lua_next); 708 709 mutex_init(&K->ks_lock, MUTEX_DEFAULT, ipl); 710 711finish: 712 mutex_enter(&sc->sc_state_lock); 713 sc->sc_state = false; 714 cv_signal(&sc->sc_state_cv); 715 mutex_exit(&sc->sc_state_lock); 716 return K; 717} 718 719inline klua_State * 720kluaL_newstate(const char *name, const char *desc, int ipl) 721{ 722 return klua_newstate(lua_alloc, NULL, name, desc, ipl); 723} 724 725void 726klua_close(klua_State *K) 727{ 728 struct lua_state *s, *ns; 729 struct lua_softc *sc; 730 struct lua_module *m; 731 int error = 0; 732 733 /* XXX consider registering a handler instead of a fixed name. */ 734 lua_getglobal(K->L, "onClose"); 735 if (lua_isfunction(K->L, -1)) 736 lua_pcall(K->L, -1, 0, 0); 737 738 sc = device_private(sc_self); 739 mutex_enter(&sc->sc_state_lock); 740 while (sc->sc_state == true) { 741 error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock); 742 if (error) 743 break; 744 } 745 if (!error) 746 sc->sc_state = true; 747 mutex_exit(&sc->sc_state_lock); 748 749 if (error) 750 return; /* Nothing we can do... */ 751 752 LIST_FOREACH_SAFE(s, &lua_states, lua_next, ns) 753 if (s->K == K) { 754 LIST_REMOVE(s, lua_next); 755 LIST_FOREACH(m, &s->lua_modules, mod_next) 756 m->refcount--; 757 kmem_free(s, sizeof(struct lua_state)); 758 } 759 760 lua_close(K->L); 761 mutex_destroy(&K->ks_lock); 762 kmem_free(K, sizeof(klua_State)); 763 764 mutex_enter(&sc->sc_state_lock); 765 sc->sc_state = false; 766 cv_signal(&sc->sc_state_cv); 767 mutex_exit(&sc->sc_state_lock); 768} 769 770static klua_State * 771klua_find(const char *name) 772{ 773 struct lua_state *s; 774 struct lua_softc *sc; 775 klua_State *K; 776 int error = 0; 777 778 K = NULL; 779 sc = device_private(sc_self); 780 mutex_enter(&sc->sc_state_lock); 781 while (sc->sc_state == true) { 782 error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock); 783 if (error) 784 break; 785 } 786 if (!error) 787 sc->sc_state = true; 788 mutex_exit(&sc->sc_state_lock); 789 790 if (error) 791 return NULL; 792 793 LIST_FOREACH(s, &lua_states, lua_next) 794 if (!strcmp(s->lua_name, name)) { 795 K = s->K; 796 break; 797 } 798 799 mutex_enter(&sc->sc_state_lock); 800 sc->sc_state = false; 801 cv_signal(&sc->sc_state_cv); 802 mutex_exit(&sc->sc_state_lock); 803 return K; 804} 805 806inline void 807klua_lock(klua_State *K) 808{ 809 mutex_enter(&K->ks_lock); 810} 811 812inline void 813klua_unlock(klua_State *K) 814{ 815 mutex_exit(&K->ks_lock); 816} 817 818MODULE(MODULE_CLASS_MISC, lua, NULL); 819 820#ifdef _MODULE 821static const struct cfiattrdata luabus_iattrdata = { 822 "luabus", 0, { { NULL, NULL, 0 },} 823}; 824 825static const struct cfiattrdata *const lua_attrs[] = { 826 &luabus_iattrdata, NULL 827}; 828 829CFDRIVER_DECL(lua, DV_DULL, lua_attrs); 830extern struct cfattach lua_ca; 831static int lualoc[] = { 832 -1, 833 -1, 834 -1 835}; 836 837static struct cfdata lua_cfdata[] = { 838 { 839 .cf_name = "lua", 840 .cf_atname = "lua", 841 .cf_unit = 0, 842 .cf_fstate = FSTATE_STAR, 843 .cf_loc = lualoc, 844 .cf_flags = 0, 845 .cf_pspec = NULL, 846 }, 847 { NULL, NULL, 0, FSTATE_NOTFOUND, NULL, 0, NULL } 848}; 849#endif 850 851static int 852lua_modcmd(modcmd_t cmd, void *opaque) 853{ 854#ifdef _MODULE 855 devmajor_t cmajor, bmajor; 856 int error = 0; 857 858 cmajor = bmajor = NODEVMAJOR; 859#endif 860 switch (cmd) { 861 case MODULE_CMD_INIT: 862#ifdef _MODULE 863 error = devsw_attach(lua_cd.cd_name, NULL, &bmajor, 864 &lua_cdevsw, &cmajor); 865 if (error) { 866 aprint_error("%s: unable to register devsw\n", 867 lua_cd.cd_name); 868 return error; 869 } 870 871 error = config_cfdriver_attach(&lua_cd); 872 if (error) { 873 devsw_detach(NULL, &lua_cdevsw); 874 return error; 875 } 876 877 error = config_cfattach_attach(lua_cd.cd_name, 878 &lua_ca); 879 if (error) { 880 config_cfdriver_detach(&lua_cd); 881 devsw_detach(NULL, &lua_cdevsw); 882 aprint_error("%s: unable to register cfattach\n", 883 lua_cd.cd_name); 884 return error; 885 } 886 error = config_cfdata_attach(lua_cfdata, 1); 887 if (error) { 888 config_cfattach_detach(lua_cd.cd_name, 889 &lua_ca); 890 config_cfdriver_detach(&lua_cd); 891 devsw_detach(NULL, &lua_cdevsw); 892 aprint_error("%s: unable to register cfdata\n", 893 lua_cd.cd_name); 894 return error; 895 } 896 config_attach_pseudo(lua_cfdata); 897#endif 898 return 0; 899 case MODULE_CMD_FINI: 900#ifdef _MODULE 901 error = config_cfdata_detach(lua_cfdata); 902 if (error) 903 return error; 904 905 config_cfattach_detach(lua_cd.cd_name, &lua_ca); 906 config_cfdriver_detach(&lua_cd); 907 devsw_detach(NULL, &lua_cdevsw); 908#endif 909 return 0; 910 case MODULE_CMD_AUTOUNLOAD: 911 /* no auto-unload */ 912 return EBUSY; 913 default: 914 return ENOTTY; 915 } 916} 917