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