1 /* $NetBSD: lua.c,v 1.28 2022/03/31 19:30:17 pgoyette Exp $ */
2
3 /*
4 * Copyright (c) 2011 - 2017 by Marc Balmer <mbalmer@NetBSD.org>.
5 * Copyright (c) 2014 by Lourival Vieira Neto <lneto@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
lua_match(device_t parent,cfdata_t match,void * aux)122 lua_match(device_t parent, cfdata_t match, void *aux)
123 {
124 return 1;
125 }
126
127 static void
lua_attach(device_t parent,device_t self,void * aux)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
lua_detach(device_t self,int flags)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
luaopen(dev_t dev,int flag,int mode,struct lwp * l)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
luaclose(dev_t dev,int flag,int mode,struct lwp * l)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
luaioctl(dev_t dev,u_long cmd,void * data,int flag,struct lwp * l)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 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
500 static int
lua_require(lua_State * L)501 lua_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
550 typedef struct {
551 size_t size;
552 } alloc_header_t;
553
554 static void *
lua_alloc(void * ud,void * ptr,size_t osize,size_t nsize)555 lua_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
591 static const char *
lua_reader(lua_State * L,void * data,size_t * size)592 lua_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
618 static void
lua_maxcount(lua_State * L,lua_Debug * d)619 lua_maxcount(lua_State *L, lua_Debug *d)
620 {
621 lua_pushstring(L, "maximum instruction count exceeded");
622 lua_error(L);
623 }
624
625 int
klua_mod_register(const char * name,lua_CFunction open)626 klua_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
643 int
klua_mod_unregister(const char * name)644 klua_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
664 klua_State *
klua_newstate(lua_Alloc f,void * ud,const char * name,const char * desc,int ipl)665 klua_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
711 finish:
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
719 inline klua_State *
kluaL_newstate(const char * name,const char * desc,int ipl)720 kluaL_newstate(const char *name, const char *desc, int ipl)
721 {
722 return klua_newstate(lua_alloc, NULL, name, desc, ipl);
723 }
724
725 void
klua_close(klua_State * K)726 klua_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
770 static klua_State *
klua_find(const char * name)771 klua_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
806 inline void
klua_lock(klua_State * K)807 klua_lock(klua_State *K)
808 {
809 mutex_enter(&K->ks_lock);
810 }
811
812 inline void
klua_unlock(klua_State * K)813 klua_unlock(klua_State *K)
814 {
815 mutex_exit(&K->ks_lock);
816 }
817
818 MODULE(MODULE_CLASS_MISC, lua, NULL);
819
820 #ifdef _MODULE
821 static const struct cfiattrdata luabus_iattrdata = {
822 "luabus", 0, { { NULL, NULL, 0 },}
823 };
824
825 static const struct cfiattrdata *const lua_attrs[] = {
826 &luabus_iattrdata, NULL
827 };
828
829 CFDRIVER_DECL(lua, DV_DULL, lua_attrs);
830 extern struct cfattach lua_ca;
831 static int lualoc[] = {
832 -1,
833 -1,
834 -1
835 };
836
837 static 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
851 static int
lua_modcmd(modcmd_t cmd,void * opaque)852 lua_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