1 /* $NetBSD: lua.c,v 1.29 2026/06/27 20:05:06 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 2011 - 2017 by Marc Balmer <mbalmer (at) NetBSD.org>. 5 * Copyright (c) 2014 by Lourival Vieira Neto <lneto (at) NetBSD.org>. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the Author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /* Lua device driver */ 33 34 #include <sys/param.h> 35 #include <sys/fcntl.h> 36 #include <sys/conf.h> 37 #include <sys/condvar.h> 38 #include <sys/device.h> 39 #include <sys/ioctl.h> 40 #include <sys/kmem.h> 41 #include <sys/lock.h> 42 #include <sys/lua.h> 43 #include <sys/module.h> 44 #include <sys/mutex.h> 45 #include <sys/namei.h> 46 #include <sys/queue.h> 47 #include <sys/sysctl.h> 48 #include <sys/vnode.h> 49 #include <sys/cpu.h> 50 51 #include <lauxlib.h> 52 53 #include "luavar.h" 54 55 struct lua_softc { 56 device_t sc_dev; 57 58 kmutex_t sc_lock; 59 kcondvar_t sc_inuse_cv; 60 bool sc_inuse; 61 62 /* Locking access to state queues */ 63 kmutex_t sc_state_lock; 64 kcondvar_t sc_state_cv; 65 bool sc_state; 66 67 struct sysctllog *sc_log; 68 }; 69 70 static device_t sc_self; 71 static bool lua_autoload_on = true; 72 static bool lua_require_on = true; 73 static bool lua_bytecode_on = false; 74 static int lua_verbose; 75 static int lua_max_instr; 76 77 static LIST_HEAD(, lua_state) lua_states = 78 LIST_HEAD_INITIALIZER(lua_states); 79 static LIST_HEAD(, lua_module) lua_modules = 80 LIST_HEAD_INITIALIZER(lua_modules); 81 82 static int lua_match(device_t, cfdata_t, void *); 83 static void lua_attach(device_t, device_t, void *); 84 static int lua_detach(device_t, int); 85 static klua_State *klua_find(const char *); 86 static const char *lua_reader(lua_State *, void *, size_t *); 87 static void lua_maxcount(lua_State *, lua_Debug *); 88 89 static int lua_require(lua_State *); 90 91 CFATTACH_DECL_NEW(lua, sizeof(struct lua_softc), 92 lua_match, lua_attach, lua_detach, NULL); 93 94 dev_type_open(luaopen); 95 dev_type_close(luaclose); 96 dev_type_ioctl(luaioctl); 97 98 const 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 113 struct lua_loadstate { 114 struct vnode *vp; 115 size_t size; 116 off_t off; 117 }; 118 119 extern struct cfdriver lua_cd; 120 121 static int 122 lua_match(device_t parent, cfdata_t match, void *aux) 123 { 124 return 1; 125 } 126 127 static void 128 lua_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 204 static int 205 lua_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 235 int 236 luaopen(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 263 int 264 luaclose(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 278 int 279 luaioctl(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 if (!(flag & FREAD)) 304 return EACCES; 305 info = data; 306 if (info->states == NULL) { 307 info->num_states = 0; 308 LIST_FOREACH(s, &lua_states, lua_next) 309 info->num_states++; 310 } else { 311 n = 0; 312 LIST_FOREACH(s, &lua_states, lua_next) { 313 if (n > info->num_states) 314 break; 315 n++; 316 } 317 info->num_states = n; 318 if (n == 0) 319 break; 320 states = kmem_alloc(sizeof(*states) * n, KM_SLEEP); 321 if (copyin(info->states, states, sizeof(*states) * n) 322 == 0) { 323 n = 0; 324 LIST_FOREACH(s, &lua_states, lua_next) { 325 if (n > info->num_states) 326 break; 327 strcpy(states[n].name, s->lua_name); 328 strcpy(states[n].desc, s->lua_desc); 329 states[n].user = s->K->ks_user; 330 n++; 331 } 332 copyout(states, info->states, 333 sizeof(*states) * n); 334 kmem_free(states, sizeof(*states) * n); 335 } 336 } 337 break; 338 case LUACREATE: 339 if (!(flag & FWRITE)) 340 return EACCES; 341 create = data; 342 343 if (*create->name == '_') { 344 if (lua_verbose) 345 device_printf(sc->sc_dev, "names of user " 346 "created states must not begin with '_'"); 347 return ENXIO; 348 } 349 LIST_FOREACH(s, &lua_states, lua_next) 350 if (!strcmp(s->lua_name, create->name)) { 351 if (lua_verbose) 352 device_printf(sc->sc_dev, 353 "state %s exists\n", create->name); 354 return EBUSY; 355 } 356 357 K = kluaL_newstate(create->name, create->desc, IPL_NONE); 358 359 if (K == NULL) 360 return ENOMEM; 361 362 K->ks_user = true; 363 364 if (lua_verbose) 365 device_printf(sc->sc_dev, "state %s created\n", 366 create->name); 367 break; 368 case LUADESTROY: 369 if (!(flag & FWRITE)) 370 return EACCES; 371 create = data; 372 373 K = klua_find(create->name); 374 375 if (K != NULL && (K->ks_user == true)) { 376 klua_close(K); 377 return 0; 378 } 379 return EBUSY; 380 case LUAREQUIRE: /* 'require' a module in a State */ 381 if (!(flag & FWRITE)) 382 return EACCES; 383 require = data; 384 LIST_FOREACH(s, &lua_states, lua_next) 385 if (!strcmp(s->lua_name, require->state)) { 386 LIST_FOREACH(m, &s->lua_modules, mod_next) 387 if (!strcmp(m->mod_name, require->module)) 388 return ENXIO; 389 LIST_FOREACH(m, &lua_modules, mod_next) 390 if (!strcmp(m->mod_name, 391 require->module)) { 392 if (lua_verbose) 393 device_printf( 394 sc->sc_dev, 395 "requiring module " 396 "%s to state %s\n", 397 m->mod_name, 398 s->lua_name); 399 klua_lock(s->K); 400 luaL_requiref( 401 s->K->L, 402 m->mod_name, 403 m->open, 404 1); 405 klua_unlock(s->K); 406 m->refcount++; 407 LIST_INSERT_HEAD( 408 &s->lua_modules, m, 409 mod_next); 410 return 0; 411 } 412 } 413 return ENXIO; 414 case LUALOAD: 415 if (!(flag & FWRITE)) 416 return EACCES; 417 load = data; 418 if (strrchr(load->path, '/') == NULL) 419 return ENXIO; 420 421 LIST_FOREACH(s, &lua_states, lua_next) 422 if (!strcmp(s->lua_name, load->state)) { 423 if (lua_verbose) 424 device_printf(sc->sc_dev, 425 "loading %s into state %s\n", 426 load->path, s->lua_name); 427 cred = kauth_cred_get(); 428 pb = pathbuf_create(load->path); 429 if (pb == NULL) 430 return ENOMEM; 431 error = vn_open(NULL, pb, NOCHROOT, FREAD, 0, 432 &vp, NULL, NULL); 433 pathbuf_destroy(pb); 434 if (error) { 435 if (lua_verbose) 436 device_printf(sc->sc_dev, 437 "error vn_open %d\n", 438 error); 439 return error; 440 } 441 error = VOP_GETATTR(vp, &va, 442 kauth_cred_get()); 443 if (error) { 444 VOP_UNLOCK(vp); 445 vn_close(vp, FREAD, 446 kauth_cred_get()); 447 if (lua_verbose) 448 device_printf(sc->sc_dev, 449 "erro VOP_GETATTR %d\n", 450 error); 451 return error; 452 } 453 if (va.va_type != VREG) { 454 VOP_UNLOCK(vp); 455 vn_close(vp, FREAD, 456 kauth_cred_get()); 457 return EINVAL; 458 } 459 ls.vp = vp; 460 ls.off = 0L; 461 ls.size = va.va_size; 462 VOP_UNLOCK(vp); 463 klua_lock(s->K); 464 error = lua_load(s->K->L, lua_reader, &ls, 465 strrchr(load->path, '/') + 1, "bt"); 466 vn_close(vp, FREAD, cred); 467 switch (error) { 468 case 0: /* no error */ 469 break; 470 case LUA_ERRSYNTAX: 471 if (lua_verbose) 472 device_printf(sc->sc_dev, 473 "syntax error\n"); 474 klua_unlock(s->K); 475 return EINVAL; 476 case LUA_ERRMEM: 477 if (lua_verbose) 478 device_printf(sc->sc_dev, 479 "memory error\n"); 480 klua_unlock(s->K); 481 return ENOMEM; 482 default: 483 if (lua_verbose) 484 device_printf(sc->sc_dev, 485 "load error %d: %s\n", 486 error, 487 lua_tostring(s->K->L, -1)); 488 klua_unlock(s->K); 489 return EINVAL; 490 } 491 if (lua_max_instr > 0) 492 lua_sethook(s->K->L, lua_maxcount, 493 LUA_MASKCOUNT, lua_max_instr); 494 error = lua_pcall(s->K->L, 0, LUA_MULTRET, 0); 495 if (error) { 496 if (lua_verbose) { 497 device_printf(sc->sc_dev, 498 "execution error: %s\n", 499 lua_tostring(s->K->L, -1)); 500 } 501 klua_unlock(s->K); 502 return EINVAL; 503 } 504 klua_unlock(s->K); 505 return 0; 506 } 507 return ENXIO; 508 } 509 return 0; 510 } 511 512 static int 513 lua_require(lua_State *L) 514 { 515 struct lua_state *s; 516 struct lua_module *m, *md; 517 const char *module; 518 char name[MAXPATHLEN]; 519 520 module = lua_tostring(L, -1); 521 md = NULL; 522 LIST_FOREACH(m, &lua_modules, mod_next) 523 if (!strcmp(m->mod_name, module)) { 524 md = m; 525 break; 526 } 527 528 if (md == NULL && lua_autoload_on && strchr(module, '/') == NULL) { 529 snprintf(name, sizeof name, "lua%s", module); 530 if (lua_verbose) 531 device_printf(sc_self, "autoload %s\n", name); 532 module_autoload(name, MODULE_CLASS_MISC); 533 LIST_FOREACH(m, &lua_modules, mod_next) 534 if (!strcmp(m->mod_name, module)) { 535 md = m; 536 break; 537 } 538 } 539 540 if (md != NULL) 541 LIST_FOREACH(s, &lua_states, lua_next) 542 if (s->K->L == L) { 543 if (lua_verbose) 544 device_printf(sc_self, 545 "require module %s\n", 546 md->mod_name); 547 luaL_requiref(L, md->mod_name, md->open, 0); 548 549 LIST_FOREACH(m, &s->lua_modules, mod_next) 550 if (m == md) 551 return 1; 552 553 md->refcount++; 554 LIST_INSERT_HEAD(&s->lua_modules, md, mod_next); 555 return 1; 556 } 557 558 lua_pushstring(L, "module not found"); 559 return lua_error(L); 560 } 561 562 typedef struct { 563 size_t size; 564 } alloc_header_t; 565 566 static void * 567 lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) 568 { 569 void *nptr = NULL; 570 571 /* 572 * Make sure that buffers allocated by lua_alloc() are aligned to 573 * 8-byte boundaries as done by kmem_alloc(9). 574 */ 575 const size_t hdr_size = roundup(sizeof(alloc_header_t), 8); 576 alloc_header_t *hdr = (alloc_header_t *) ((char *) ptr - hdr_size); 577 578 if (nsize == 0) { /* freeing */ 579 if (ptr != NULL) 580 kmem_intr_free(hdr, hdr->size); 581 } else if (ptr != NULL && nsize <= hdr->size - hdr_size) /* shrinking */ 582 return ptr; /* don't need to reallocate */ 583 else { /* creating or expanding */ 584 km_flag_t sleep = cpu_intr_p() || cpu_softintr_p() ? 585 KM_NOSLEEP : KM_SLEEP; 586 587 size_t alloc_size = nsize + hdr_size; 588 alloc_header_t *nhdr = kmem_intr_alloc(alloc_size, sleep); 589 if (nhdr == NULL) /* failed to allocate */ 590 return NULL; 591 592 nhdr->size = alloc_size; 593 nptr = (void *) ((char *) nhdr + hdr_size); 594 595 if (ptr != NULL) { /* expanding */ 596 memcpy(nptr, ptr, osize); 597 kmem_intr_free(hdr, hdr->size); 598 } 599 } 600 return nptr; 601 } 602 603 static const char * 604 lua_reader(lua_State *L, void *data, size_t *size) 605 { 606 struct lua_loadstate *ls; 607 static char buf[1024]; 608 size_t rsiz; 609 610 ls = data; 611 if (ls->size < sizeof(buf)) 612 rsiz = ls->size; 613 else 614 rsiz = sizeof(buf); 615 vn_rdwr(UIO_READ, ls->vp, buf, rsiz, ls->off, UIO_SYSSPACE, 616 0, curlwp->l_cred, NULL, curlwp); 617 if (ls->off == 0L && lua_bytecode_on == false && buf[0] == 0x1b) { 618 *size = 0L; 619 lua_pushstring(L, "loading of bytecode is not allowed"); 620 lua_error(L); 621 return NULL; 622 } else { 623 *size = rsiz; 624 ls->off += *size; 625 ls->size -= *size; 626 } 627 return buf; 628 } 629 630 static void 631 lua_maxcount(lua_State *L, lua_Debug *d) 632 { 633 lua_pushstring(L, "maximum instruction count exceeded"); 634 lua_error(L); 635 } 636 637 int 638 klua_mod_register(const char *name, lua_CFunction open) 639 { 640 struct lua_module *m; 641 642 LIST_FOREACH(m, &lua_modules, mod_next) 643 if (!strcmp(m->mod_name, name)) 644 return EBUSY; 645 m = kmem_zalloc(sizeof(struct lua_module), KM_SLEEP); 646 strlcpy(m->mod_name, name, LUA_MAX_MODNAME); 647 m->open = open; 648 m->refcount = 0; 649 LIST_INSERT_HEAD(&lua_modules, m, mod_next); 650 if (lua_verbose) 651 device_printf(sc_self, "registered lua module %s\n", name); 652 return 0; 653 } 654 655 int 656 klua_mod_unregister(const char *name) 657 { 658 struct lua_module *m; 659 660 LIST_FOREACH(m, &lua_modules, mod_next) 661 if (!strcmp(m->mod_name, name)) { 662 if (m->refcount == 0) { 663 LIST_REMOVE(m, mod_next); 664 kmem_free(m, sizeof(struct lua_module)); 665 if (lua_verbose) 666 device_printf(sc_self, 667 "unregistered lua module %s\n", 668 name); 669 return 0; 670 } else 671 return EBUSY; 672 } 673 return 0; 674 } 675 676 klua_State * 677 klua_newstate(lua_Alloc f, void *ud, const char *name, const char *desc, 678 int ipl) 679 { 680 klua_State *K; 681 struct lua_state *s; 682 struct lua_softc *sc; 683 int error = 0; 684 685 s = kmem_zalloc(sizeof(struct lua_state), KM_SLEEP); 686 sc = device_private(sc_self); 687 mutex_enter(&sc->sc_state_lock); 688 while (sc->sc_state == true) { 689 error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock); 690 if (error) 691 break; 692 } 693 if (!error) 694 sc->sc_state = true; 695 mutex_exit(&sc->sc_state_lock); 696 697 if (error) { 698 kmem_free(s, sizeof(struct lua_state)); 699 return NULL; 700 } 701 702 K = kmem_zalloc(sizeof(klua_State), KM_SLEEP); 703 K->L = lua_newstate(f, ud); 704 K->ks_user = false; 705 if (K->L == NULL) { 706 kmem_free(K, sizeof(klua_State)); 707 K = NULL; 708 goto finish; 709 } 710 711 strlcpy(s->lua_name, name, MAX_LUA_NAME); 712 strlcpy(s->lua_desc, desc, MAX_LUA_DESC); 713 s->K = K; 714 715 if (lua_require_on || lua_autoload_on) { 716 lua_pushcfunction(K->L, lua_require); 717 lua_setglobal(K->L, "require"); 718 } 719 LIST_INSERT_HEAD(&lua_states, s, lua_next); 720 721 mutex_init(&K->ks_lock, MUTEX_DEFAULT, ipl); 722 723 finish: 724 mutex_enter(&sc->sc_state_lock); 725 sc->sc_state = false; 726 cv_signal(&sc->sc_state_cv); 727 mutex_exit(&sc->sc_state_lock); 728 return K; 729 } 730 731 inline klua_State * 732 kluaL_newstate(const char *name, const char *desc, int ipl) 733 { 734 return klua_newstate(lua_alloc, NULL, name, desc, ipl); 735 } 736 737 void 738 klua_close(klua_State *K) 739 { 740 struct lua_state *s, *ns; 741 struct lua_softc *sc; 742 struct lua_module *m; 743 int error = 0; 744 745 /* XXX consider registering a handler instead of a fixed name. */ 746 lua_getglobal(K->L, "onClose"); 747 if (lua_isfunction(K->L, -1)) 748 lua_pcall(K->L, -1, 0, 0); 749 750 sc = device_private(sc_self); 751 mutex_enter(&sc->sc_state_lock); 752 while (sc->sc_state == true) { 753 error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock); 754 if (error) 755 break; 756 } 757 if (!error) 758 sc->sc_state = true; 759 mutex_exit(&sc->sc_state_lock); 760 761 if (error) 762 return; /* Nothing we can do... */ 763 764 LIST_FOREACH_SAFE(s, &lua_states, lua_next, ns) 765 if (s->K == K) { 766 LIST_REMOVE(s, lua_next); 767 LIST_FOREACH(m, &s->lua_modules, mod_next) 768 m->refcount--; 769 kmem_free(s, sizeof(struct lua_state)); 770 } 771 772 lua_close(K->L); 773 mutex_destroy(&K->ks_lock); 774 kmem_free(K, sizeof(klua_State)); 775 776 mutex_enter(&sc->sc_state_lock); 777 sc->sc_state = false; 778 cv_signal(&sc->sc_state_cv); 779 mutex_exit(&sc->sc_state_lock); 780 } 781 782 static klua_State * 783 klua_find(const char *name) 784 { 785 struct lua_state *s; 786 struct lua_softc *sc; 787 klua_State *K; 788 int error = 0; 789 790 K = NULL; 791 sc = device_private(sc_self); 792 mutex_enter(&sc->sc_state_lock); 793 while (sc->sc_state == true) { 794 error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock); 795 if (error) 796 break; 797 } 798 if (!error) 799 sc->sc_state = true; 800 mutex_exit(&sc->sc_state_lock); 801 802 if (error) 803 return NULL; 804 805 LIST_FOREACH(s, &lua_states, lua_next) 806 if (!strcmp(s->lua_name, name)) { 807 K = s->K; 808 break; 809 } 810 811 mutex_enter(&sc->sc_state_lock); 812 sc->sc_state = false; 813 cv_signal(&sc->sc_state_cv); 814 mutex_exit(&sc->sc_state_lock); 815 return K; 816 } 817 818 inline void 819 klua_lock(klua_State *K) 820 { 821 mutex_enter(&K->ks_lock); 822 } 823 824 inline void 825 klua_unlock(klua_State *K) 826 { 827 mutex_exit(&K->ks_lock); 828 } 829 830 MODULE(MODULE_CLASS_MISC, lua, NULL); 831 832 #ifdef _MODULE 833 static const struct cfiattrdata luabus_iattrdata = { 834 "luabus", 0, { { NULL, NULL, 0 },} 835 }; 836 837 static const struct cfiattrdata *const lua_attrs[] = { 838 &luabus_iattrdata, NULL 839 }; 840 841 CFDRIVER_DECL(lua, DV_DULL, lua_attrs); 842 extern struct cfattach lua_ca; 843 static int lualoc[] = { 844 -1, 845 -1, 846 -1 847 }; 848 849 static struct cfdata lua_cfdata[] = { 850 { 851 .cf_name = "lua", 852 .cf_atname = "lua", 853 .cf_unit = 0, 854 .cf_fstate = FSTATE_STAR, 855 .cf_loc = lualoc, 856 .cf_flags = 0, 857 .cf_pspec = NULL, 858 }, 859 { NULL, NULL, 0, FSTATE_NOTFOUND, NULL, 0, NULL } 860 }; 861 #endif 862 863 static int 864 lua_modcmd(modcmd_t cmd, void *opaque) 865 { 866 #ifdef _MODULE 867 devmajor_t cmajor, bmajor; 868 int error = 0; 869 870 cmajor = bmajor = NODEVMAJOR; 871 #endif 872 switch (cmd) { 873 case MODULE_CMD_INIT: 874 #ifdef _MODULE 875 error = devsw_attach(lua_cd.cd_name, NULL, &bmajor, 876 &lua_cdevsw, &cmajor); 877 if (error) { 878 aprint_error("%s: unable to register devsw\n", 879 lua_cd.cd_name); 880 return error; 881 } 882 883 error = config_cfdriver_attach(&lua_cd); 884 if (error) { 885 devsw_detach(NULL, &lua_cdevsw); 886 return error; 887 } 888 889 error = config_cfattach_attach(lua_cd.cd_name, 890 &lua_ca); 891 if (error) { 892 config_cfdriver_detach(&lua_cd); 893 devsw_detach(NULL, &lua_cdevsw); 894 aprint_error("%s: unable to register cfattach\n", 895 lua_cd.cd_name); 896 return error; 897 } 898 error = config_cfdata_attach(lua_cfdata, 1); 899 if (error) { 900 config_cfattach_detach(lua_cd.cd_name, 901 &lua_ca); 902 config_cfdriver_detach(&lua_cd); 903 devsw_detach(NULL, &lua_cdevsw); 904 aprint_error("%s: unable to register cfdata\n", 905 lua_cd.cd_name); 906 return error; 907 } 908 config_attach_pseudo(lua_cfdata); 909 #endif 910 return 0; 911 case MODULE_CMD_FINI: 912 #ifdef _MODULE 913 error = config_cfdata_detach(lua_cfdata); 914 if (error) 915 return error; 916 917 config_cfattach_detach(lua_cd.cd_name, &lua_ca); 918 config_cfdriver_detach(&lua_cd); 919 devsw_detach(NULL, &lua_cdevsw); 920 #endif 921 return 0; 922 case MODULE_CMD_AUTOUNLOAD: 923 /* no auto-unload */ 924 return EBUSY; 925 default: 926 return ENOTTY; 927 } 928 } 929