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