Export CONFIG_ options via #version/kconfig
[akaros.git] / kern / drivers / dev / cons.c
1 /*
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9
10 #include <arch/arch.h>
11 #include <ros/fs.h>
12 #include <ns.h>
13 #include <kmalloc.h>
14 #include <string.h>
15 #include <stdio.h>
16 #include <time.h>
17 #include <atomic.h>
18 #include <smp.h>
19 #include <error.h>
20 #include <sys/queue.h>
21 #include <event.h>
22 #include <env.h>
23 #include <ros/procinfo.h>
24
25 #if 0
26 void (*consdebug) (void) = NULL;
27 #endif
28 void (*screenputs) (const char *, int) = cputbuf;
29
30 struct queue *kbdq;                             /* unprocessed console input */
31 struct queue *lineq;                    /* processed console input */
32 struct queue *serialoq;                 /* serial console output */
33 struct queue *kprintoq;                 /* console output, for /dev/kprint */
34 atomic_t kprintinuse = 0;               /* test and set whether /dev/kprint is open */
35 int iprintscreenputs = 1;
36 int keepbroken = 1;
37
38 static bool cons_has_init = FALSE;
39 struct queue *cons_q;                   /* Akaros cons input: keyboard, serial, etc */
40 spinlock_t cons_q_lock = SPINLOCK_INITIALIZER;
41 struct fdtap_slist cons_q_fd_taps = SLIST_HEAD_INITIALIZER(cons_q_fd_taps);
42
43 static uint8_t logbuffer[1 << 20];
44 static int index = 0;
45 static struct queue *logqueue = NULL;
46 static int reading_kmesg = 0;
47
48 typedef unsigned char uint8_t;
49
50 void logbuf(int c)
51 {
52         if (reading_kmesg)
53                 return;
54         if (index > 1 << 20)
55                 return;
56         logbuffer[index++] = c;
57 }
58
59 /*
60  *  return true if current user is eve
61  */
62 int iseve(void)
63 {
64         return strcmp(eve.name, current->user.name) == 0;
65 }
66
67 struct username eve = {.name = "", .name_lock = SPINLOCK_INITIALIZER};
68 char hostdomain[256] = "akaros.org";
69
70 static struct {
71         qlock_t qlock;
72
73         int raw;                                        /* true if we shouldn't process input */
74         struct kref ctl;                        /* number of opens to the control file */
75         int x;                                          /* index into line */
76         char line[1024];                        /* current input line */
77
78         int count;
79         int ctlpoff;
80
81         /* a place to save up characters at interrupt time before dumping them in the queue */
82         spinlock_t lockputc;
83         char istage[1024];
84         char *iw;
85         char *ir;
86         char *ie;
87 } kbd = {
88 .iw = kbd.istage,.ir = kbd.istage,.ie = kbd.istage + sizeof(kbd.istage),};
89
90 char *sysname;
91 int64_t fasthz;
92
93 static int readtime(uint32_t, char *, int);
94 static int readbintime(char *, int);
95 static int writetime(char *, int);
96 static int writebintime(char *, int);
97 static int hostownerwrite(char *, size_t);
98 static void killkid(void);
99
100 enum {
101         CMbroken,
102         CMconsole,
103         CMhalt,
104         CMnobroken,
105         CMpanic,
106         CMreboot,
107 };
108
109
110 struct cmdtab rebootmsg[] = {
111         {CMbroken, "broken", 0},
112         {CMconsole, "console", 1},
113         {CMhalt, "halt", 1},
114         {CMnobroken, "nobroken", 0},
115         {CMpanic, "panic", 0},
116         {CMreboot, "reboot", 0},
117 };
118
119 void printinit(void)
120 {
121         lineq = qopen(2 * 1024, 0, NULL, NULL);
122         if (lineq == NULL)
123                 panic("printinit");
124         qdropoverflow(lineq, 1);
125 }
126
127 int consactive(void)
128 {
129         if (serialoq)
130                 return qlen(serialoq) > 0;
131         return 0;
132 }
133
134 void prflush(void)
135 {
136         long times = 0;
137
138         while (consactive())
139                 if (times++ > 1000)
140                         break;
141 }
142
143 /*
144  * Log console output so it can be retrieved via /dev/kmesg.
145  * This is good for catching boot-time messages after the fact.
146  */
147 struct {
148         spinlock_t lk;
149         char buf[1 << 20];
150         unsigned int n;
151 } kmesg;
152
153 static void kmesgputs(char *str, int n)
154 {
155         unsigned int nn, d;
156
157         spin_lock_irqsave(&kmesg.lk);
158         /* take the tail of huge writes */
159         if (n > sizeof kmesg.buf) {
160                 d = n - sizeof kmesg.buf;
161                 str += d;
162                 n -= d;
163         }
164
165         /* slide the buffer down to make room */
166         nn = kmesg.n;
167         if (nn + n >= sizeof kmesg.buf) {
168                 d = nn + n - sizeof kmesg.buf;
169                 if (d)
170                         memmove(kmesg.buf, kmesg.buf + d, sizeof kmesg.buf - d);
171                 nn -= d;
172         }
173
174         /* copy the data in */
175         memmove(kmesg.buf + nn, str, n);
176         nn += n;
177         kmesg.n = nn;
178         spin_unlock_irqsave(&kmesg.lk);
179 }
180
181 /*
182  *   Print a string on the console.  Convert \n to \r\n for serial
183  *   line consoles.  Locking of the queues is left up to the screen
184  *   or uart code.  Multi-line messages to serial consoles may get
185  *   interspersed with other messages.
186  */
187 static void putstrn0(char *str, int n, int usewrite)
188 {
189         int m;
190         char *t;
191
192 #if 0
193         if (!islo())
194                 usewrite = 0;
195 #endif
196
197         /*
198          *  how many different output devices do we need?
199          */
200         kmesgputs(str, n);
201
202         /*
203          *  if someone is reading /dev/kprint
204          *  put the message there.
205          *  if not and there's an attached bit mapped display,
206          *  put the message there.
207          *
208          *  if there's a serial line being used as a console,
209          *  put the message there.
210          */
211         if (kprintoq != NULL && !qisclosed(kprintoq)) {
212                 if (usewrite)
213                         qwrite(kprintoq, str, n);
214                 else
215                         qiwrite(kprintoq, str, n);
216         } else if (screenputs != NULL)
217                 screenputs(str, n);
218
219         if (serialoq == NULL) {
220 #if 0
221                 uartputs(str, n);
222 #endif
223                 return;
224         }
225
226         while (n > 0) {
227                 t = memchr(str, '\n', n);
228                 if (t && !kbd.raw) {
229                         m = t - str;
230                         if (usewrite) {
231                                 qwrite(serialoq, str, m);
232                                 qwrite(serialoq, "\r\n", 2);
233                         } else {
234                                 qiwrite(serialoq, str, m);
235                                 qiwrite(serialoq, "\r\n", 2);
236                         }
237                         n -= m + 1;
238                         str = t + 1;
239                 } else {
240                         if (usewrite)
241                                 qwrite(serialoq, str, n);
242                         else
243                                 qiwrite(serialoq, str, n);
244                         break;
245                 }
246         }
247 }
248
249 void putstrn(char *str, int n)
250 {
251         putstrn0(str, n, 0);
252 }
253
254 int noprint;
255
256 int print(char *fmt, ...)
257 {
258         int n;
259         va_list arg;
260         char buf[PRINTSIZE];
261
262         if (noprint)
263                 return -1;
264
265         va_start(arg, fmt);
266         n = vsnprintf(buf, sizeof(buf), fmt, arg);
267         va_end(arg);
268         putstrn(buf, n);
269
270         return n;
271 }
272
273 /*
274  * Want to interlock iprints to avoid interlaced output on
275  * multiprocessor, but don't want to deadlock if one processor
276  * dies during print and another has something important to say.
277  * Make a good faith effort.
278  */
279 static spinlock_t iprintlock;
280 static int iprintcanlock(spinlock_t * l)
281 {
282         int i;
283
284         for (i = 0; i < 1000; i++) {
285                 if (spin_trylock(l))
286                         return 1;
287         }
288         return 0;
289 }
290
291 int iprint(char *fmt, ...)
292 {
293         int8_t s = 0;
294         int n, locked;
295         va_list arg;
296         char buf[PRINTSIZE];
297
298         disable_irqsave(&s);
299         va_start(arg, fmt);
300         n = vsnprintf(buf, sizeof(buf), fmt, arg);
301         va_end(arg);
302         locked = iprintcanlock(&iprintlock);
303         if (screenputs != NULL && iprintscreenputs)
304                 screenputs(buf, n);
305 #if 0
306         uartputs(buf, n);
307 #endif
308         if (locked)
309                 spin_unlock(&iprintlock);
310         enable_irqsave(&s);
311
312         return n;
313 }
314
315 /* libmp at least contains a few calls to sysfatal; simulate with panic */
316 void sysfatal(char *fmt, ...)
317 {
318         char err[256];
319         va_list arg;
320
321         va_start(arg, fmt);
322         vsnprintf(err, sizeof err, fmt, arg);
323         va_end(arg);
324         panic("sysfatal: %s", err);
325 }
326
327 void _assert(char *fmt)
328 {
329         panic("assert failed at %#p: %s", getcallerpc(&fmt), fmt);
330 }
331
332 #if 0
333 int pprint(char *fmt, ...)
334 {
335         ERRSTACK(2);
336         int n;
337         struct chan *c;
338         va_list arg;
339         char buf[2 * PRINTSIZE];
340
341         if (up == NULL || current->fgrp == NULL)
342                 return 0;
343
344         c = current->fgrp->fd[2];
345         if (c == 0 || (c->mode != O_WRITE && c->mode != O_RDWR))
346                 return 0;
347         n = snprintf(buf, sizeof buf, "%s %lud: ", current->text, current->pid);
348         va_start(arg, fmt);
349         n = vsnprintf(buf + n, sizeof(buf), fmt, arg);
350         va_end(arg);
351
352         if (waserror())
353                 return 0;
354         devtab[c->type]->write(c, buf, n, c->offset);
355         poperror();
356
357         spin_lock(&c->lock);
358         c->offset += n;
359         spin_unlock(&c->lock);
360
361         return n;
362 }
363 #endif
364
365 static void echoscreen(char *buf, int n)
366 {
367         char *e, *p;
368         char ebuf[128];
369         int x;
370
371         p = ebuf;
372         e = ebuf + sizeof(ebuf) - 4;
373         while (n-- > 0) {
374                 if (p >= e) {
375                         screenputs(ebuf, p - ebuf);
376                         p = ebuf;
377                 }
378                 x = *buf++;
379                 if (x == 0x15) {
380                         *p++ = '^';
381                         *p++ = 'U';
382                         *p++ = '\n';
383                 } else
384                         *p++ = x;
385         }
386         if (p != ebuf)
387                 screenputs(ebuf, p - ebuf);
388 }
389
390 static void echoserialoq(char *buf, int n)
391 {
392         char *e, *p;
393         char ebuf[128];
394         int x;
395
396         p = ebuf;
397         e = ebuf + sizeof(ebuf) - 4;
398         while (n-- > 0) {
399                 if (p >= e) {
400                         qiwrite(serialoq, ebuf, p - ebuf);
401                         p = ebuf;
402                 }
403                 x = *buf++;
404                 if (x == '\n') {
405                         *p++ = '\r';
406                         *p++ = '\n';
407                 } else if (x == 0x15) {
408                         *p++ = '^';
409                         *p++ = 'U';
410                         *p++ = '\n';
411                 } else
412                         *p++ = x;
413         }
414         if (p != ebuf)
415                 qiwrite(serialoq, ebuf, p - ebuf);
416 }
417
418 static void echo(char *buf, int n)
419 {
420         static int ctrlt, pid;
421         char *e, *p;
422
423         if (n == 0)
424                 return;
425
426         e = buf + n;
427         for (p = buf; p < e; p++) {
428                 switch (*p) {
429 #if 0
430                         case 0x10:      /* ^P */
431                                 if (cpuserver && !kbd.ctlpoff) {
432                                         active.exiting = 1;
433                                         return;
434                                 }
435                                 break;
436 #endif
437                         case 0x14:      /* ^T */
438                                 ctrlt++;
439                                 if (ctrlt > 2)
440                                         ctrlt = 2;
441                                 continue;
442                 }
443
444                 if (ctrlt != 2)
445                         continue;
446
447                 /* ^T escapes */
448                 ctrlt = 0;
449                 switch (*p) {
450 #if 0
451                         case 'S':{
452                                         int8_t x = 0;
453                                         disable_irqsave(&x);
454                                         dumpstack();
455                                         procdump();
456                                         enable_irqsave(&x);
457                                         return;
458                                 }
459 #endif
460                         case 's':
461                                 dumpstack();
462                                 return;
463 #if 0
464                         case 'x':
465                                 xsummary();
466                                 ixsummary();
467                                 mallocsummary();
468                                 memorysummary();
469                                 pagersummary();
470                                 return;
471                         case 'd':
472                                 if (consdebug == NULL)
473                                         consdebug = rdb;
474                                 else
475                                         consdebug = NULL;
476                                 printd("consdebug now %#p\n", consdebug);
477                                 return;
478                         case 'D':
479                                 if (consdebug == NULL)
480                                         consdebug = rdb;
481                                 consdebug();
482                                 return;
483                         case 'p':
484                                 x = spllo();
485                                 procdump();
486                                 splx(x);
487                                 return;
488                         case 'q':
489                                 scheddump();
490                                 return;
491                         case 'k':
492                                 killbig("^t ^t k");
493                                 return;
494 #endif
495                         case 'r':
496                                 exit(0);
497                                 return;
498                 }
499         }
500
501         qwrite(kbdq, buf, n);   /* was once qproduce, YMMV */
502         if (kbd.raw)
503                 return;
504         kmesgputs(buf, n);
505         if (screenputs != NULL)
506                 echoscreen(buf, n);
507         if (serialoq)
508                 echoserialoq(buf, n);
509 }
510
511 /*
512  *  Called by a uart interrupt for console input.
513  *
514  *  turn '\r' into '\n' before putting it into the queue.
515  */
516 int kbdcr2nl(struct queue *ignored_queue, int ch)
517 {
518         char *next;
519
520         spin_lock_irqsave(&kbd.lockputc);       /* just a mutex */
521         if (ch == '\r' && !kbd.raw)
522                 ch = '\n';
523         next = kbd.iw + 1;
524         if (next >= kbd.ie)
525                 next = kbd.istage;
526         if (next != kbd.ir) {
527                 *kbd.iw = ch;
528                 kbd.iw = next;
529         }
530         spin_unlock_irqsave(&kbd.lockputc);
531         return 0;
532 }
533
534 /*
535  *  Put character, possibly a rune, into read queue at interrupt time.
536  *  Called at interrupt time to process a character.
537  */
538 int kbdputc(struct queue *unused_queue, int ch)
539 {
540         int i, n;
541         char buf[3];
542         // Akaros does not use Rune et al.
543         //Rune r;
544         int r;
545         char *next;
546
547         if (kbd.ir == NULL)
548                 return 0;       /* in case we're not inited yet */
549
550         spin_lock_irqsave(&kbd.lockputc);       /* just a mutex */
551         r = ch;
552         //n = runetochar(buf, &r);
553         // Fake Rune support.
554         n = 1;
555         buf[0] = r;
556         for (i = 0; i < n; i++) {
557                 next = kbd.iw + 1;
558                 if (next >= kbd.ie)
559                         next = kbd.istage;
560                 if (next == kbd.ir)
561                         break;
562                 *kbd.iw = buf[i];
563                 kbd.iw = next;
564         }
565         spin_unlock_irqsave(&kbd.lockputc);
566         return 0;
567 }
568
569 /*
570  *  we save up input characters till clock time to reduce
571  *  per character interrupt overhead.
572  */
573 static void kbdputcclock(void)
574 {
575         char *iw;
576
577         /* this amortizes cost of qproduce */
578         if (kbd.iw != kbd.ir) {
579                 iw = kbd.iw;
580                 if (iw < kbd.ir) {
581                         echo(kbd.ir, kbd.ie - kbd.ir);
582                         kbd.ir = kbd.istage;
583                 }
584                 if (kbd.ir != iw) {
585                         echo(kbd.ir, iw - kbd.ir);
586                         kbd.ir = iw;
587                 }
588         }
589 }
590
591 enum {
592         Qdir,
593         Qbintime,
594         Qconfig,
595         Qcons,
596         Qconsctl,
597         Qcputime,
598         Qdrivers,
599         Qhostdomain,
600         Qhostowner,
601         Qklog,
602         Qkmesg,
603         Qkprint,
604         Qnull,
605         Qosversion,
606         Qpgrpid,
607         Qpid,
608         Qppid,
609         Qreboot,
610         Qstdin,
611         Qstdout,
612         Qstderr,
613         Qswap,
614         Qsysctl,
615         Qsysname,
616         Qsysstat,
617         Qtime,
618         Quser,
619         Qzero,
620         Qkillkid,
621 };
622
623 enum {
624         VLNUMSIZE = 22,
625         DOMLEN = 256,
626 };
627
628 static struct dirtab consdir[] = {
629         {".", {Qdir, 0, QTDIR}, 0, DMDIR | 0555},
630         {"bintime", {Qbintime}, 24, 0664},
631         {"config", {Qconfig}, 0, 0444},
632         {"cons", {Qcons}, 0, 0660},
633         {"consctl", {Qconsctl}, 0, 0220},
634         // FIXME -- we don't have real permissions yet so we set it to 222, not 220
635         {"killkid", {Qkillkid}, 0, 0220 | /* BOGUS */ 2},
636         {"cputime", {Qcputime}, 6 * NUMSIZE, 0444},
637         {"drivers", {Qdrivers}, 0, 0444},
638         {"hostdomain", {Qhostdomain}, DOMLEN, 0664},
639         {"hostowner", {Qhostowner}, 0, 0664},
640         {"klog", {Qklog}, 0, 0440},
641         {"kmesg", {Qkmesg}, 0, 0440},
642         {"kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL | 0440},
643         {"null", {Qnull}, 0, 0666},
644         {"osversion", {Qosversion}, 0, 0444},
645         {"pgrpid", {Qpgrpid}, NUMSIZE, 0444},
646         {"pid", {Qpid}, NUMSIZE, 0444},
647         {"ppid", {Qppid}, NUMSIZE, 0444},
648         {"reboot", {Qreboot}, 0, 0660},
649         {"stdin", {Qstdin}, 0, 0666},
650         {"stdout", {Qstdout}, 0, 0666},
651         {"stderr", {Qstderr}, 0, 0666},
652         {"swap", {Qswap}, 0, 0664},
653         {"sysctl", {Qsysctl}, 0, 0666},
654         {"sysname", {Qsysname}, 0, 0664},
655         {"sysstat", {Qsysstat}, 0, 0666},
656         {"time", {Qtime}, NUMSIZE + 3 * VLNUMSIZE, 0664},
657         {"user", {Quser}, 0, 0666},
658         {"zero", {Qzero}, 0, 0444},
659 };
660
661 int consreadnum(uint32_t off, char *buf, uint32_t n, uint32_t val, int size)
662 {
663         char tmp[64];
664
665         snprintf(tmp, sizeof(tmp), "%*lud", size - 1, val);
666         tmp[size - 1] = ' ';
667         if (off >= size)
668                 return 0;
669         if (off + n > size)
670                 n = size - off;
671         memmove(buf, tmp + off, n);
672         return n;
673 }
674
675 int consreadstr(uint32_t off, char *buf, uint32_t n, char *str)
676 {
677         int size;
678
679         size = strlen(str);
680         if (off >= size)
681                 return 0;
682         if (off + n > size)
683                 n = size - off;
684         memmove(buf, str + off, n);
685         return n;
686 }
687
688 static void consinit(void)
689 {
690         kstrdup(&sysname, "nanwan");
691         cons_q = qopen(256, 0, 0, 0);
692 #if 0
693         todinit();
694 #endif
695         /*
696          * at 115200 baud, the 1024 char buffer takes 56 ms to process,
697          * processing it every 22 ms should be fine
698          */
699 #if 0
700         addclock0link(kbdputcclock, 22);
701 #endif
702         cmb();  /* single-core, just need previous instructions to be issued. */
703         cons_has_init = TRUE;
704 }
705
706 static char *devname(void);
707
708 static struct chan *consattach(char *spec)
709 {
710         return devattach(devname(), spec);
711 }
712
713 static struct walkqid *conswalk(struct chan *c, struct chan *nc, char **name,
714                                                                 int nname)
715 {
716         return devwalk(c, nc, name, nname, consdir, ARRAY_SIZE(consdir), devgen);
717 }
718
719 static int consstat(struct chan *c, uint8_t *dp, int n)
720 {
721         struct dir dir;
722         struct dirtab *tab;
723         int perm;
724
725         switch ((uint32_t)c->qid.path) {
726         case Qstdin:
727                 tab = &consdir[Qstdin];
728                 perm = tab->perm;
729                 perm |= qreadable(cons_q) ? DMREADABLE : 0;
730                 devdir(c, tab->qid, tab->name, qlen(cons_q), eve.name, perm, &dir);
731                 return dev_make_stat(c, &dir, dp, n);
732         default:
733                 return devstat(c, dp, n, consdir, ARRAY_SIZE(consdir), devgen);
734         }
735 }
736
737 static struct chan *consopen(struct chan *c, int omode)
738 {
739         c->aux = NULL;
740         c = devopen(c, omode, consdir, ARRAY_SIZE(consdir), devgen);
741         switch ((uint32_t) c->qid.path) {
742                 case Qconsctl:
743                         kref_get(&kbd.ctl, 1);
744                         break;
745
746                 case Qkprint:
747                         if (atomic_swap(&kprintinuse, 1) != 0) {
748                                 c->flag &= ~COPEN;
749                                 error(EADDRINUSE, "kprintinuse lock failed");
750                         }
751                         if (kprintoq == NULL) {
752                                 kprintoq = qopen(8 * 1024, Qcoalesce, 0, 0);
753                                 if (kprintoq == NULL) {
754                                         c->flag &= ~COPEN;
755                                         error(ENOMEM, "Can't allocate kprintoq");
756                                 }
757                                 qdropoverflow(kprintoq, 1);
758                         } else
759                                 qreopen(kprintoq);
760                         c->iounit = qiomaxatomic;
761                         break;
762         }
763         return c;
764 }
765
766 static void consclose(struct chan *c)
767 {
768         switch ((uint32_t) c->qid.path) {
769                         /* last close of control file turns off raw */
770                 case Qconsctl:
771                         if (c->flag & COPEN) {
772                                 if (kref_put(&kbd.ctl) == 0)
773                                         kbd.raw = 0;
774                         }
775                         break;
776
777                         /* close of kprint allows other opens */
778                 case Qkprint:
779                         if (c->flag & COPEN) {
780                                 kprintinuse = 0;
781                                 qhangup(kprintoq, NULL);
782                         }
783                         break;
784         }
785 }
786
787 static long consread(struct chan *c, void *buf, long n, int64_t off)
788 {
789         ERRSTACK(1);
790         uint32_t l;
791 #if 0
792         Mach *mp;
793 #endif
794         char *b, *bp, ch;
795         char tmp[256];                          /* must be >= 18*NUMSIZE (Qswap) */
796         int i, k, id, send;
797         int64_t offset = off;
798 #if 0
799         extern char configfile[];
800 #endif
801
802         if (n <= 0)
803                 return n;
804
805         switch ((uint32_t) c->qid.path) {
806                 case Qdir:
807                         return devdirread(c, buf, n, consdir, ARRAY_SIZE(consdir), devgen);
808
809                 case Qcons:
810                         qlock(&(&kbd)->qlock);
811                         if (waserror()) {
812                                 qunlock(&(&kbd)->qlock);
813                                 nexterror();
814                         }
815                         while (!qcanread(lineq)) {
816                                 if (qread(kbdq, &ch, 1) == 0)
817                                         continue;
818                                 send = 0;
819                                 if (ch == 0) {
820                                         /* flush output on rawoff -> rawon */
821                                         if (kbd.x > 0)
822                                                 send = !qcanread(kbdq);
823                                 } else if (kbd.raw) {
824                                         kbd.line[kbd.x++] = ch;
825                                         send = !qcanread(kbdq);
826                                 } else {
827                                         switch (ch) {
828                                                 case '\b':
829                                                         if (kbd.x > 0)
830                                                                 kbd.x--;
831                                                         break;
832                                                 case 0x15:      /* ^U */
833                                                         kbd.x = 0;
834                                                         break;
835                                                 case '\n':
836                                                 case 0x04:      /* ^D */
837                                                         send = 1;
838                                                 default:
839                                                         if (ch != 0x04)
840                                                                 kbd.line[kbd.x++] = ch;
841                                                         break;
842                                         }
843                                 }
844                                 if (send || kbd.x == sizeof kbd.line) {
845                                         qwrite(lineq, kbd.line, kbd.x);
846                                         kbd.x = 0;
847                                 }
848                         }
849                         n = qread(lineq, buf, n);
850                         qunlock(&(&kbd)->qlock);
851                         poperror();
852                         return n;
853
854 #if 0
855                 case Qcputime:
856                         k = offset;
857                         if (k >= 6 * NUMSIZE)
858                                 return 0;
859                         if (k + n > 6 * NUMSIZE)
860                                 n = 6 * NUMSIZE - k;
861                         /* easiest to format in a separate buffer and copy out */
862                         for (i = 0; i < 6 && NUMSIZE * i < k + n; i++) {
863                                 l = current->time[i];
864                                 if (i == TReal)
865                                         l = MACHP(0)->ticks - l;
866                                 l = TK2MS(l);
867                                 consreadnum(0, tmp + NUMSIZE * i, NUMSIZE, l, NUMSIZE);
868                         }
869                         memmove(buf, tmp + k, n);
870                         return n;
871 #endif
872
873                 case Qkmesg:
874                         /*
875                          * This is unlocked to avoid tying up a process
876                          * that's writing to the buffer.  kmesg.n never
877                          * gets smaller, so worst case the reader will
878                          * see a slurred buffer.
879                          */
880                         if (off >= kmesg.n)
881                                 n = 0;
882                         else {
883                                 if (off + n > kmesg.n)
884                                         n = kmesg.n - off;
885                                 memmove(buf, kmesg.buf + off, n);
886                         }
887                         return n;
888
889                 case Qkprint:
890                         return qread(kprintoq, buf, n);
891
892                 case Qpgrpid:
893                         return consreadnum((uint32_t) offset, buf, n, current->pgrp->pgrpid,
894                                                            NUMSIZE);
895
896                 case Qpid:
897                         return consreadnum((uint32_t) offset, buf, n, current->pid,
898                                                            NUMSIZE);
899
900                 case Qppid:
901                         return consreadnum((uint32_t) offset, buf, n, current->ppid,
902                                                            NUMSIZE);
903
904                 case Qtime:
905                         return readtime((uint32_t) offset, buf, n);
906
907                 case Qbintime:
908                         return readbintime(buf, n);
909
910                 case Qhostowner:
911                         return consreadstr((uint32_t) offset, buf, n, eve.name);
912
913                 case Qhostdomain:
914                         return consreadstr((uint32_t) offset, buf, n, hostdomain);
915
916                 case Quser:
917                         return consreadstr((uint32_t) offset, buf, n, current->user.name);
918
919                 case Qnull:
920                         return 0;
921
922 #if 0
923                 case Qconfig:
924                         return consreadstr((uint32_t) offset, buf, n, configfile);
925
926                 case Qsysstat:
927                         b = kzmalloc(conf.nmach * (NUMSIZE * 11 + 1) + 1, 0);   /* +1 for NUL */
928                         bp = b;
929                         for (id = 0; id < 32; id++) {
930                                 if (active.machs & (1 << id)) {
931                                         mp = MACHP(id);
932                                         consreadnum(0, bp, NUMSIZE, id, NUMSIZE);
933                                         bp += NUMSIZE;
934                                         consreadnum(0, bp, NUMSIZE, mp->cs, NUMSIZE);
935                                         bp += NUMSIZE;
936                                         consreadnum(0, bp, NUMSIZE, mp->intr, NUMSIZE);
937                                         bp += NUMSIZE;
938                                         consreadnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE);
939                                         bp += NUMSIZE;
940                                         consreadnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE);
941                                         bp += NUMSIZE;
942                                         consreadnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE);
943                                         bp += NUMSIZE;
944                                         consreadnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE);
945                                         bp += NUMSIZE;
946                                         consreadnum(0, bp, NUMSIZE, mp->load, NUMSIZE);
947                                         bp += NUMSIZE;
948                                         consreadnum(0, bp, NUMSIZE,
949                                                                 (mp->perf.avg_inidle * 100) / mp->perf.period,
950                                                                 NUMSIZE);
951                                         bp += NUMSIZE;
952                                         consreadnum(0, bp, NUMSIZE,
953                                                                 (mp->perf.avg_inintr * 100) / mp->perf.period,
954                                                                 NUMSIZE);
955                                         bp += NUMSIZE;
956                                         *bp++ = '\n';
957                                 }
958                         }
959                         if (waserror()) {
960                                 kfree(b);
961                                 nexterror();
962                         }
963                         n = consreadstr((uint32_t) offset, buf, n, b);
964                         kfree(b);
965                         poperror();
966                         return n;
967
968                 case Qswap:
969                         snprintf(tmp, sizeof tmp,
970                                          "%lud memory\n"
971                                          "%d pagesize\n"
972                                          "%lud kernel\n"
973                                          "%lud/%lud user\n"
974                                          "%lud/%lud swap\n"
975                                          "%lud/%lud kernel malloc\n"
976                                          "%lud/%lud kernel draw\n",
977                                          conf.npage * BY2PG,
978                                          BY2PG,
979                                          conf.npage - conf.upages,
980                                          palloc.user - palloc.freecount, palloc.user,
981                                          conf.nswap - swapalloc.free, conf.nswap,
982                                          mainmem->cursize, mainmem->maxsize,
983                                          imagmem->cursize, imagmem->maxsize);
984
985                         return consreadstr((uint32_t) offset, buf, n, tmp);
986 #endif
987
988                 case Qstdin:
989                         if (c->flag & O_NONBLOCK)
990                                 return qread_nonblock(cons_q, buf, n);
991                         else
992                                 return qread(cons_q, buf, n);
993                 case Qsysname:
994                         /* TODO: this is racy */
995                         if (sysname == NULL)
996                                 return 0;
997                         return consreadstr((uint32_t) offset, buf, n, sysname);
998
999                 case Qdrivers:
1000                         b = kzmalloc(READSTR, 0);
1001                         if (b == NULL)
1002                                 error(ENOMEM, "allocation for /dev/drivers read failed");
1003                         k = 0;
1004                         for (int i = 0; &devtab[i] < __devtabend; i++)
1005                                 k += snprintf(b + k, READSTR - k, "#%s\n", devtab[i].name);
1006                         if (waserror()) {
1007                                 kfree(b);
1008                                 nexterror();
1009                         }
1010                         n = consreadstr((uint32_t) offset, buf, n, b);
1011                         kfree(b);
1012                         poperror();
1013                         return n;
1014
1015                 case Qklog:
1016                         //return qread(klogq, buf, n);
1017                         /* the queue gives us some elasticity for log reading. */
1018                         if (!logqueue)
1019                                 logqueue = qopen(1 << 20, 0, 0, 0);
1020                         if (logqueue) {
1021                                 int ret;
1022                                 /* atomic sets/gets are not that important in this case. */
1023                                 reading_kmesg = 1;
1024                                 qwrite(logqueue, logbuffer, index);
1025                                 index = 0;
1026                                 ret = qread(logqueue, buf, n);
1027                                 reading_kmesg = 0;
1028                                 return ret;
1029                         }
1030                         break;
1031
1032                 case Qzero:
1033                         memset(buf, 0, n);
1034                         return n;
1035
1036                 case Qosversion:
1037                         snprintf(tmp, sizeof tmp, "2000");
1038                         n = consreadstr((uint32_t) offset, buf, n, tmp);
1039                         return n;
1040
1041                 default:
1042                         printd("consread %#llux\n", c->qid.path);
1043                         error(EINVAL, "bad QID in consread");
1044         }
1045         return -1;      /* never reached */
1046 }
1047
1048 static long conswrite(struct chan *c, void *va, long n, int64_t off)
1049 {
1050         ERRSTACK(1);
1051         char buf[256], ch;
1052         long l, bp;
1053         char *a;
1054         //Mach *mp;
1055         int id, fd;
1056         struct chan *swc;
1057         uint32_t offset;
1058         struct cmdbuf *cb;
1059         struct cmdtab *ct;
1060         int x;
1061         uint64_t rip, rsp, cr3, flags, vcpu;
1062         int ret;
1063
1064         a = va;
1065         offset = off;
1066
1067         switch ((uint32_t) c->qid.path) {
1068                 case Qcons:
1069                         /*
1070                          * Can't page fault in putstrn, so copy the data locally.
1071                          */
1072                         l = n;
1073                         while (l > 0) {
1074                                 bp = l;
1075                                 if (bp > sizeof buf)
1076                                         bp = sizeof buf;
1077                                 memmove(buf, a, bp);
1078                                 putstrn0(buf, bp, 1);
1079                                 a += bp;
1080                                 l -= bp;
1081                         }
1082                         break;
1083
1084                 /* TODO: have it take a command about just *how* to kill the kid? */
1085                 case Qkillkid:
1086                         killkid();
1087                         break;
1088
1089                 case Qconsctl:
1090                         if (n >= sizeof(buf))
1091                                 n = sizeof(buf) - 1;
1092                         strncpy(buf, a, n);
1093                         buf[n] = 0;
1094                         for (a = buf; a;) {
1095                                 if (strncmp(a, "rawon", 5) == 0) {
1096                                         kbd.raw = 1;
1097                                         /* clumsy hack - wake up reader */
1098                                         ch = 0;
1099                                         qwrite(kbdq, &ch, 1);
1100                                 } else if (strncmp(a, "rawoff", 6) == 0) {
1101                                         kbd.raw = 0;
1102                                 } else if (strncmp(a, "ctlpon", 6) == 0) {
1103                                         kbd.ctlpoff = 0;
1104                                 } else if (strncmp(a, "ctlpoff", 7) == 0) {
1105                                         kbd.ctlpoff = 1;
1106                                 }
1107                                 if ((a = strchr(a, ' ')) != NULL)
1108                                         a++;
1109                         }
1110                         break;
1111
1112                 case Qtime:
1113                         if (!iseve())
1114                                 error(EPERM, "Hodie Natus Est Radici Frater");
1115                         return writetime(a, n);
1116
1117                 case Qbintime:
1118                         if (!iseve())
1119                                 error(EPERM, ERROR_FIXME);
1120                         return writebintime(a, n);
1121
1122                 case Qhostowner:
1123                         return hostownerwrite(a, n);
1124
1125 #if 0
1126                 case Qhostdomain:
1127                         return hostdomainwrite(a, n);
1128
1129                 case Quser:
1130                         return userwrite(a, n);
1131 #endif
1132
1133                 case Qnull:
1134                         break;
1135
1136                 case Qconfig:
1137                         error(EPERM, "Cannot write to config QID");
1138                         break;
1139
1140                 case Qsysctl:
1141                         //if (!iseve()) error(EPERM, ERROR_FIXME);
1142                         cb = parsecmd(a, n);
1143                         if (cb->nf > 1)
1144                         printd("cons sysctl cmd %s\n", cb->f[0]);
1145
1146                 case Qreboot:
1147                         if (!iseve())
1148                                 error(EPERM, ERROR_FIXME);
1149                         cb = parsecmd(a, n);
1150
1151                         if (waserror()) {
1152                                 kfree(cb);
1153                                 nexterror();
1154                         }
1155                         ct = lookupcmd(cb, rebootmsg, ARRAY_SIZE(rebootmsg));
1156                         switch (ct->index) {
1157                                 case CMhalt:
1158                                         cpu_halt();
1159                                         break;
1160                                 case CMbroken:
1161                                         keepbroken = 1;
1162                                         break;
1163                                 case CMnobroken:
1164                                         keepbroken = 0;
1165                                         break;
1166                                 case CMreboot:
1167                                         reboot();
1168                                         break;
1169                                 case CMpanic:
1170                                         *(uint32_t *) 0 = 0;
1171                                         panic("/dev/reboot");
1172                                         break;
1173                         }
1174                         poperror();
1175                         kfree(cb);
1176                         break;
1177
1178 #if 0
1179                 case Qsysstat:
1180                         for (id = 0; id < 32; id++) {
1181                                 if (active.machs & (1 << id)) {
1182                                         mp = MACHP(id);
1183                                         mp->cs = 0;
1184                                         mp->intr = 0;
1185                                         mp->syscall = 0;
1186                                         mp->pfault = 0;
1187                                         mp->tlbfault = 0;
1188                                         mp->tlbpurge = 0;
1189                                 }
1190                         }
1191                         break;
1192
1193                 case Qswap:
1194                         if (n >= sizeof buf)
1195                                 error(EINVAL, "n is bigger than sizeof buf for Qswap");
1196                         memmove(buf, va, n);    /* so we can NUL-terminate */
1197                         buf[n] = 0;
1198                         /* start a pager if not already started */
1199                         if (strncmp(buf, "start", 5) == 0) {
1200                                 kickpager();
1201                                 break;
1202                         }
1203                         if (!iseve())
1204                                 error(EPERM, ERROR_FIXME);
1205                         if (buf[0] < '0' || '9' < buf[0])
1206                                 error(EINVAL, ERROR_FIXME);
1207                         fd = strtoul(buf, 0, 0);
1208                         swc = fdtochan(fd, -1, 1, 1);
1209                         setswapchan(swc);
1210                         break;
1211 #endif
1212
1213                 case Qstdout:
1214                 case Qstderr:
1215                         px_lock();
1216                         if (waserror()) {
1217                                 px_unlock();
1218                                 nexterror();
1219                         }
1220                         /* TODO: tty hack.  they are sending us an escape sequence, and the
1221                          * keyboard would try to print it (which it can't do yet).  The hack
1222                          * is even dirtier in that we only detect it if it is the first
1223                          * char, and we ignore everything else.  \033 is 0x1b. */
1224                         if (((char*)va)[0] != '\033')
1225                                 cputbuf(va, n);
1226                         poperror();
1227                         px_unlock();
1228                         return n;
1229                 case Qsysname:
1230                         /* TODO: this is racy */
1231                         if (offset != 0)
1232                                 error(EINVAL, ERROR_FIXME);
1233                         if (n <= 0 || n >= sizeof buf)
1234                                 error(EINVAL, ERROR_FIXME);
1235                         strncpy(buf, a, n);
1236                         buf[n] = 0;
1237                         if (buf[n - 1] == '\n')
1238                                 buf[n - 1] = 0;
1239                         kstrdup(&sysname, buf);
1240                         break;
1241
1242                 default:
1243                         printd("conswrite: %#llux\n", c->qid.path);
1244                         error(EINVAL, "bad QID in conswrite");
1245         }
1246         return n;
1247 }
1248
1249 static char *cons_chaninfo(struct chan *ch, char *ret, size_t ret_l)
1250 {
1251         switch ((uint32_t)ch->qid.path) {
1252         case Qstdin:
1253                 snprintf(ret, ret_l, "qio len: %d", qlen(cons_q));
1254                 break;
1255         default:
1256                 return devchaninfo(ch, ret, ret_l);
1257         }
1258         return ret;
1259 }
1260
1261 static void __consq_fire_taps(uint32_t srcid, long a0, long a1, long a2)
1262 {
1263         struct fd_tap *tap_i;
1264         int filter = a0;
1265
1266         spin_lock(&cons_q_lock);
1267         SLIST_FOREACH(tap_i, &cons_q_fd_taps, link)
1268                 fire_tap(tap_i, filter);
1269         spin_unlock(&cons_q_lock);
1270
1271 }
1272
1273 static void cons_q_wake_cb(struct queue *q, void *data, int filter)
1274 {
1275         /* TODO: taps can't fire from IRQ context, but the qiwrites for stdin come
1276          * from IRQ context.  So we need an RKM here. */
1277         send_kernel_message(core_id(), __consq_fire_taps, filter,
1278                             0, 0, KMSG_ROUTINE);
1279 }
1280
1281 static int tap_stdin(struct chan *c, struct fd_tap *tap, int cmd)
1282 {
1283         int ret;
1284
1285         /* We don't actually support HANGUP, but epoll implies it. */
1286         #define CONS_STDIN_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_HANGUP)
1287
1288         if (tap->filter & ~CONS_STDIN_TAPS) {
1289                 set_error(ENOSYS, "Unsupported #%s tap, must be %p", devname(),
1290                           CONS_STDIN_TAPS);
1291                 return -1;
1292         }
1293         spin_lock(&cons_q_lock);
1294         switch (cmd) {
1295         case FDTAP_CMD_ADD:
1296                 if (SLIST_EMPTY(&cons_q_fd_taps))
1297                         qio_set_wake_cb(cons_q, cons_q_wake_cb, 0);
1298                 SLIST_INSERT_HEAD(&cons_q_fd_taps, tap, link);
1299                 ret = 0;
1300                 break;
1301         case FDTAP_CMD_REM:
1302                 SLIST_REMOVE(&cons_q_fd_taps, tap, fd_tap, link);
1303                 if (SLIST_EMPTY(&cons_q_fd_taps))
1304                         qio_set_wake_cb(cons_q, 0, 0);
1305                 ret = 0;
1306                 break;
1307         default:
1308                 set_error(ENOSYS, "Unsupported #%s tap command %p", devname(), cmd);
1309                 ret = -1;
1310         }
1311         spin_unlock(&cons_q_lock);
1312         return ret;
1313 }
1314
1315 static int cons_tapfd(struct chan *c, struct fd_tap *tap, int cmd)
1316 {
1317         switch ((uint32_t)c->qid.path) {
1318         case Qstdin:
1319                 return tap_stdin(c, tap, cmd);
1320         default:
1321                 set_error(ENOSYS, "Can't tap #%s file type %d", devname(),
1322                           c->qid.path);
1323                 return -1;
1324         }
1325 }
1326
1327 struct dev consdevtab __devtab = {
1328         .name = "cons",
1329
1330         .reset = devreset,
1331         .init = consinit,
1332         .shutdown = devshutdown,
1333         .attach = consattach,
1334         .walk = conswalk,
1335         .stat = consstat,
1336         .open = consopen,
1337         .create = devcreate,
1338         .close = consclose,
1339         .read = consread,
1340         .bread = devbread,
1341         .write = conswrite,
1342         .bwrite = devbwrite,
1343         .remove = devremove,
1344         .wstat = devwstat,
1345         .power = devpower,
1346         .chaninfo = cons_chaninfo,
1347         .tapfd = cons_tapfd,
1348 };
1349
1350 static char *devname(void)
1351 {
1352         return consdevtab.name;
1353 }
1354
1355 static uint64_t uvorder = 0x0001020304050607ULL;
1356
1357 static uint8_t *le2int64_t(int64_t * to, uint8_t * f)
1358 {
1359         uint8_t *t, *o;
1360         int i;
1361
1362         t = (uint8_t *) to;
1363         o = (uint8_t *) & uvorder;
1364         for (i = 0; i < sizeof(int64_t); i++)
1365                 t[o[i]] = f[i];
1366         return f + sizeof(int64_t);
1367 }
1368
1369 static uint8_t *int64_t2le(uint8_t * t, int64_t from)
1370 {
1371         uint8_t *f, *o;
1372         int i;
1373
1374         f = (uint8_t *) & from;
1375         o = (uint8_t *) & uvorder;
1376         for (i = 0; i < sizeof(int64_t); i++)
1377                 t[i] = f[o[i]];
1378         return t + sizeof(int64_t);
1379 }
1380
1381 static long order = 0x00010203;
1382
1383 static uint8_t *le2long(long *to, uint8_t * f)
1384 {
1385         uint8_t *t, *o;
1386         int i;
1387
1388         t = (uint8_t *) & to;
1389         o = (uint8_t *) & order;
1390         for (i = 0; i < sizeof(long); i++)
1391                 t[o[i]] = f[i];
1392         return f + sizeof(long);
1393 }
1394
1395 static uint8_t *long2le(uint8_t * t, long from)
1396 {
1397         uint8_t *f, *o;
1398         int i;
1399
1400         f = (uint8_t *) & from;
1401         o = (uint8_t *) & order;
1402         for (i = 0; i < sizeof(long); i++)
1403                 t[i] = f[o[i]];
1404         return t + sizeof(long);
1405 }
1406
1407 char *Ebadtimectl = "bad time control";
1408
1409 /*
1410  *  like the old #c/time but with added info.  Return
1411  *
1412  *      secs    nanosecs        fastticks       fasthz
1413  */
1414 static int readtime(uint32_t off, char *buf, int n)
1415 {
1416         int64_t nsec, ticks;
1417         long sec;
1418         char str[7 * NUMSIZE];
1419
1420         if (fasthz == 0LL)
1421                 fasthz = __proc_global_info.tsc_freq;
1422 #if 0
1423         fastticks((uint64_t *) & fasthz);
1424         nsec = todget(&ticks);
1425 #endif
1426         ticks = read_tsc();
1427         nsec = tsc2nsec(ticks);
1428         sec = nsec / 1000000000ULL;
1429         snprintf(str, sizeof(str), "%*lud %*llud %*llud %*llud ",
1430                          NUMSIZE - 1, sec,
1431                          VLNUMSIZE - 1, nsec, VLNUMSIZE - 1, ticks, VLNUMSIZE - 1, fasthz);
1432         return consreadstr(off, buf, n, str);
1433 }
1434
1435 /*
1436  *  set the time in seconds
1437  */
1438 static int writetime(char *buf, int n)
1439 {
1440         char b[13];
1441         long i;
1442         int64_t now;
1443
1444         if (n >= sizeof(b))
1445                 error(EINVAL, "bad size in writetime");
1446         strncpy(b, buf, n);
1447         b[n] = 0;
1448         i = strtol(b, 0, 0);
1449         if (i <= 0)
1450                 error(EINVAL, "Bad time in write");
1451         now = i * 1000000000LL;
1452 #if 0
1453         todset(now, 0, 0);
1454 #endif
1455         return n;
1456 }
1457
1458 /*
1459  *  read binary time info.  all numbers are little endian.
1460  *  ticks and nsec are syncronized.
1461  */
1462 static int readbintime(char *buf, int n)
1463 {
1464         int i;
1465         int64_t nsec, ticks;
1466         uint8_t *b = (uint8_t *) buf;
1467
1468         i = 0;
1469         if (fasthz == 0LL)
1470                 fasthz = __proc_global_info.tsc_freq;
1471 #if 0
1472         fastticks((uint64_t *) & fasthz);
1473         nsec = todget(&ticks);
1474 #endif
1475         ticks = read_tsc();
1476         nsec = tsc2nsec(ticks);
1477         if (n >= 3 * sizeof(uint64_t)) {
1478                 int64_t2le(b + 2 * sizeof(uint64_t), fasthz);
1479                 i += sizeof(uint64_t);
1480         }
1481         if (n >= 2 * sizeof(uint64_t)) {
1482                 int64_t2le(b + sizeof(uint64_t), ticks);
1483                 i += sizeof(uint64_t);
1484         }
1485         if (n >= 8) {
1486                 int64_t2le(b, nsec);
1487                 i += sizeof(int64_t);
1488         }
1489         return i;
1490 }
1491
1492 /*
1493  *  set any of the following
1494  *      - time in nsec
1495  *      - nsec trim applied over some seconds
1496  *      - clock frequency
1497  */
1498 static int writebintime(char *buf, int n)
1499 {
1500         uint8_t *p;
1501         int64_t delta = 0;
1502         long period = 0;
1503
1504         n--;
1505         p = (uint8_t *) buf + 1;
1506         switch (*buf) {
1507                 case 'n':
1508                         if (n < sizeof(int64_t))
1509                                 error(EINVAL, ERROR_FIXME);
1510                         le2int64_t(&delta, p);
1511 #if 0
1512                         todset(delta, 0, 0);
1513 #endif
1514                         break;
1515                 case 'd':
1516                         if (n < sizeof(int64_t) + sizeof(long))
1517                                 error(EINVAL, ERROR_FIXME);
1518                         p = le2int64_t(&delta, p);
1519                         le2long(&period, p);
1520 #if 0
1521                         todset(-1, delta, period);
1522 #endif
1523                         break;
1524                 case 'f':
1525                         if (n < sizeof(uint64_t))
1526                                 error(EINVAL, ERROR_FIXME);
1527                         le2int64_t(&fasthz, p);
1528                         if (fasthz <= 0)
1529                                 error(EINVAL, ERROR_FIXME);
1530 #if 0
1531                         todsetfreq(fasthz);
1532 #endif
1533                         break;
1534         }
1535         return n;
1536 }
1537
1538 /*
1539  * set the hostowner, but only if current is the hostowner and the new value
1540  * isn't too long
1541  */
1542 static int hostownerwrite(char *buf, size_t n)
1543 {
1544         ERRSTACK(1);
1545
1546         if (!iseve())
1547                 error(EPERM, "only hostowner can change hostowner");
1548
1549         if (strlen(buf) < 1)
1550                 error(EINVAL, "hostowner cannot be set to \"\"");
1551
1552         spin_lock(&eve.name_lock);
1553
1554         if (waserror()) {
1555                 spin_unlock(&eve.name_lock);
1556                 nexterror();
1557         }
1558
1559         // value at boot is ""
1560         if (eve.name[0] != 0)
1561                 error(EPERM, "hostowner can only be set once");
1562
1563         __set_username(&eve, buf);
1564
1565         poperror();
1566         spin_unlock(&eve.name_lock);
1567
1568         // Set this username first so it gets set regardless of an error below
1569         proc_set_username(current, buf);
1570
1571         // Update all other hostowner processes
1572         // This is costly, but should only happen very early on
1573         struct process_set pset;
1574
1575         proc_get_set(&pset);
1576         if (waserror()) {
1577                 proc_free_set(&pset);
1578                 nexterror();
1579         }
1580
1581         for (size_t i = 0; i < pset.num_processes; i++) {
1582                 // Won't update current again
1583                 // Note: if a name is being written to the user field as it is read
1584                 //       here, it will appear as ""; but no other writes should occur
1585                 //       as early as this should be run
1586                 if (strcmp(pset.procs[i]->user.name, "") == 0)
1587                         proc_set_username(pset.procs[i], buf);
1588         }
1589
1590         poperror();
1591         proc_free_set(&pset);
1592
1593         return n;
1594 }
1595
1596 /*
1597  * find_first_kid finds your immediate descendant. Not because we're
1598  * trying to give it a check from the estate, mind you. We're here on
1599  * much more unpleasant business. To make it easy to call this
1600  * multiple times without lots of fussy checking, we allow it to be
1601  * called with NULL pointers; hence find_first_kid(find_first_kid(x))
1602  * works even if x is chaste and will return NULL.
1603  */
1604 static struct proc *find_first_kid(struct proc *p)
1605 {
1606         struct proc *kid;
1607
1608         cv_lock(&p->child_wait);
1609         kid = TAILQ_FIRST(&p->children);
1610         if (kid) {
1611                 proc_incref(kid, 1);
1612                 proc_decref(p);
1613         }
1614         cv_unlock(&p->child_wait);
1615         return kid;
1616 }
1617
1618 /*
1619  * killkid manages population issues by killing your kids.  This is a
1620  * particular temporary (we think) function for ssh. As such, we are
1621  * going to make a Command Decision to never kill the top level
1622  * kid. We start on grandkids, in other words.  Hey, the parent/child
1623  * terminology was Ken's idea; go yell at him.  If you want, we can
1624  * rename this to DrownCuteKittens.
1625  *
1626  * This was hard to get right so it's way more verbose than you might think we need.
1627  * Sorry.
1628  */
1629 void killkid(void)
1630 {
1631         struct proc *check, *kid, *grandkid, *victim;
1632
1633         /* find first grandkid */
1634         proc_incref(current, 1);
1635         kid = find_first_kid(current);
1636         if (!kid) {
1637                 proc_decref(current);
1638                 return;
1639         }
1640         grandkid = find_first_kid(kid);
1641         if (!grandkid) {
1642                 proc_decref(kid);
1643                 return;
1644         }
1645         victim = grandkid;
1646         while (1) {
1647                 check = find_first_kid(victim);
1648                 if (!check)
1649                         break;
1650                 victim = check;
1651         }
1652         send_posix_signal(victim, SIGINT);
1653         proc_decref(victim);
1654 }
1655
1656 /* This can be called any time after arch_init()->cons_irq_init().  That can
1657  * happen *before* the console device is initialized (devtab{reset,init}()).
1658  *
1659  * All other functions in #cons shouldn't be called until after cons_init(). */
1660 void cons_add_char(char c)
1661 {
1662         if (!cons_has_init)
1663                 return;
1664         qiwrite(cons_q, &c, sizeof(char));
1665 }