FreeBSD kernel kern code
subr_prf.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 1986, 1988, 1991, 1993
3  * The Regents of the University of California. All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  * 4. Neither the name of the University nor the names of its contributors
19  * may be used to endorse or promote products derived from this software
20  * without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
35  */
36 
37 #include <sys/cdefs.h>
38 __FBSDID("$BSDSUniX$");
39 
40 #include "opt_ddb.h"
41 #include "opt_printf.h"
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/lock.h>
46 #include <sys/kdb.h>
47 #include <sys/mutex.h>
48 #include <sys/sx.h>
49 #include <sys/kernel.h>
50 #include <sys/msgbuf.h>
51 #include <sys/malloc.h>
52 #include <sys/priv.h>
53 #include <sys/proc.h>
54 #include <sys/stddef.h>
55 #include <sys/sysctl.h>
56 #include <sys/tty.h>
57 #include <sys/syslog.h>
58 #include <sys/cons.h>
59 #include <sys/uio.h>
60 #include <sys/ctype.h>
61 
62 #ifdef DDB
63 #include <ddb/ddb.h>
64 #endif
65 
66 /*
67  * Note that stdarg.h and the ANSI style va_start macro is used for both
68  * ANSI and traditional C compilers.
69  */
70 #include <machine/stdarg.h>
71 
72 #define TOCONS 0x01
73 #define TOTTY 0x02
74 #define TOLOG 0x04
75 
76 /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
77 #define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
78 
79 struct putchar_arg {
80  int flags;
81  int pri;
82  struct tty *tty;
83  char *p_bufr;
84  size_t n_bufr;
85  char *p_next;
86  size_t remain;
87 };
88 
89 struct snprintf_arg {
90  char *str;
91  size_t remain;
92 };
93 
94 extern int log_open;
95 
96 static void msglogchar(int c, int pri);
97 static void msglogstr(char *str, int pri, int filter_cr);
98 static void putchar(int ch, void *arg);
99 static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper);
100 static void snprintf_func(int ch, void *arg);
101 
102 static int msgbufmapped; /* Set when safe to use msgbuf */
104 
105 static int log_console_output = 1;
106 TUNABLE_INT("kern.log_console_output", &log_console_output);
107 SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW,
108  &log_console_output, 0, "Duplicate console output to the syslog.");
109 
110 /*
111  * See the comment in log_console() below for more explanation of this.
112  */
114 TUNABLE_INT("kern.log_console_add_linefeed", &log_console_add_linefeed);
115 SYSCTL_INT(_kern, OID_AUTO, log_console_add_linefeed, CTLFLAG_RW,
116  &log_console_add_linefeed, 0, "log_console() adds extra newlines.");
117 
118 static int always_console_output = 0;
119 TUNABLE_INT("kern.always_console_output", &always_console_output);
120 SYSCTL_INT(_kern, OID_AUTO, always_console_output, CTLFLAG_RW,
121  &always_console_output, 0, "Always output to console despite TIOCCONS.");
122 
123 /*
124  * Warn that a system table is full.
125  */
126 void
127 tablefull(const char *tab)
128 {
129 
130  log(LOG_ERR, "%s: table is full\n", tab);
131 }
132 
133 /*
134  * Uprintf prints to the controlling terminal for the current process.
135  */
136 int
137 uprintf(const char *fmt, ...)
138 {
139  va_list ap;
140  struct putchar_arg pca;
141  struct proc *p;
142  struct thread *td;
143  int retval;
144 
145  td = curthread;
146  if (TD_IS_IDLETHREAD(td))
147  return (0);
148 
149  sx_slock(&proctree_lock);
150  p = td->td_proc;
151  PROC_LOCK(p);
152  if ((p->p_flag & P_CONTROLT) == 0) {
153  PROC_UNLOCK(p);
154  sx_sunlock(&proctree_lock);
155  return (0);
156  }
157  SESS_LOCK(p->p_session);
158  pca.tty = p->p_session->s_ttyp;
159  SESS_UNLOCK(p->p_session);
160  PROC_UNLOCK(p);
161  if (pca.tty == NULL) {
162  sx_sunlock(&proctree_lock);
163  return (0);
164  }
165  pca.flags = TOTTY;
166  pca.p_bufr = NULL;
167  va_start(ap, fmt);
168  tty_lock(pca.tty);
169  sx_sunlock(&proctree_lock);
170  retval = kvprintf(fmt, putchar, &pca, 10, ap);
171  tty_unlock(pca.tty);
172  va_end(ap);
173  return (retval);
174 }
175 
176 /*
177  * tprintf prints on the controlling terminal associated with the given
178  * session, possibly to the log as well.
179  */
180 void
181 tprintf(struct proc *p, int pri, const char *fmt, ...)
182 {
183  struct tty *tp = NULL;
184  int flags = 0;
185  va_list ap;
186  struct putchar_arg pca;
187  struct session *sess = NULL;
188 
189  sx_slock(&proctree_lock);
190  if (pri != -1)
191  flags |= TOLOG;
192  if (p != NULL) {
193  PROC_LOCK(p);
194  if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
195  sess = p->p_session;
196  sess_hold(sess);
197  PROC_UNLOCK(p);
198  tp = sess->s_ttyp;
199  if (tp != NULL && tty_checkoutq(tp))
200  flags |= TOTTY;
201  else
202  tp = NULL;
203  } else
204  PROC_UNLOCK(p);
205  }
206  pca.pri = pri;
207  pca.tty = tp;
208  pca.flags = flags;
209  pca.p_bufr = NULL;
210  va_start(ap, fmt);
211  if (pca.tty != NULL)
212  tty_lock(pca.tty);
213  sx_sunlock(&proctree_lock);
214  kvprintf(fmt, putchar, &pca, 10, ap);
215  if (pca.tty != NULL)
216  tty_unlock(pca.tty);
217  va_end(ap);
218  if (sess != NULL)
219  sess_release(sess);
220  msgbuftrigger = 1;
221 }
222 
223 /*
224  * Ttyprintf displays a message on a tty; it should be used only by
225  * the tty driver, or anything that knows the underlying tty will not
226  * be revoke(2)'d away. Other callers should use tprintf.
227  */
228 int
229 ttyprintf(struct tty *tp, const char *fmt, ...)
230 {
231  va_list ap;
232  struct putchar_arg pca;
233  int retval;
234 
235  va_start(ap, fmt);
236  pca.tty = tp;
237  pca.flags = TOTTY;
238  pca.p_bufr = NULL;
239  retval = kvprintf(fmt, putchar, &pca, 10, ap);
240  va_end(ap);
241  return (retval);
242 }
243 
244 static int
245 _vprintf(int level, int flags, const char *fmt, va_list ap)
246 {
247  struct putchar_arg pca;
248  int retval;
249 #ifdef PRINTF_BUFR_SIZE
250  char bufr[PRINTF_BUFR_SIZE];
251 #endif
252 
253  pca.tty = NULL;
254  pca.pri = level;
255  pca.flags = flags;
256 #ifdef PRINTF_BUFR_SIZE
257  pca.p_bufr = bufr;
258  pca.p_next = pca.p_bufr;
259  pca.n_bufr = sizeof(bufr);
260  pca.remain = sizeof(bufr);
261  *pca.p_next = '\0';
262 #else
263  /* Don't buffer console output. */
264  pca.p_bufr = NULL;
265 #endif
266 
267  retval = kvprintf(fmt, putchar, &pca, 10, ap);
268 
269 #ifdef PRINTF_BUFR_SIZE
270  /* Write any buffered console/log output: */
271  if (*pca.p_bufr != '\0') {
272  if (pca.flags & TOLOG)
273  msglogstr(pca.p_bufr, level, /*filter_cr*/1);
274 
275  if (pca.flags & TOCONS)
276  cnputs(pca.p_bufr);
277  }
278 #endif
279 
280  return (retval);
281 }
282 
283 /*
284  * Log writes to the log buffer, and guarantees not to sleep (so can be
285  * called by interrupt routines). If there is no process reading the
286  * log yet, it writes to the console also.
287  */
288 void
289 log(int level, const char *fmt, ...)
290 {
291  va_list ap;
292 
293  va_start(ap, fmt);
294  (void)_vprintf(level, log_open ? TOLOG : TOCONS, fmt, ap);
295  va_end(ap);
296 
297  msgbuftrigger = 1;
298 }
299 
300 #define CONSCHUNK 128
301 
302 void
303 log_console(struct uio *uio)
304 {
305  int c, error, nl;
306  char *consbuffer;
307  int pri;
308 
309  if (!log_console_output)
310  return;
311 
312  pri = LOG_INFO | LOG_CONSOLE;
313  uio = cloneuio(uio);
314  consbuffer = malloc(CONSCHUNK, M_TEMP, M_WAITOK);
315 
316  nl = 0;
317  while (uio->uio_resid > 0) {
318  c = imin(uio->uio_resid, CONSCHUNK - 1);
319  error = uiomove(consbuffer, c, uio);
320  if (error != 0)
321  break;
322  /* Make sure we're NUL-terminated */
323  consbuffer[c] = '\0';
324  if (consbuffer[c - 1] == '\n')
325  nl = 1;
326  else
327  nl = 0;
328  msglogstr(consbuffer, pri, /*filter_cr*/ 1);
329  }
330  /*
331  * The previous behavior in log_console() is preserved when
332  * log_console_add_linefeed is non-zero. For that behavior, if an
333  * individual console write came in that was not terminated with a
334  * line feed, it would add a line feed.
335  *
336  * This results in different data in the message buffer than
337  * appears on the system console (which doesn't add extra line feed
338  * characters).
339  *
340  * A number of programs and rc scripts write a line feed, or a period
341  * and a line feed when they have completed their operation. On
342  * the console, this looks seamless, but when displayed with
343  * 'dmesg -a', you wind up with output that looks like this:
344  *
345  * Updating motd:
346  * .
347  *
348  * On the console, it looks like this:
349  * Updating motd:.
350  *
351  * We could add logic to detect that situation, or just not insert
352  * the extra newlines. Set the kern.log_console_add_linefeed
353  * sysctl/tunable variable to get the old behavior.
354  */
355  if (!nl && log_console_add_linefeed) {
356  consbuffer[0] = '\n';
357  consbuffer[1] = '\0';
358  msglogstr(consbuffer, pri, /*filter_cr*/ 1);
359  }
360  msgbuftrigger = 1;
361  free(uio, M_IOV);
362  free(consbuffer, M_TEMP);
363  return;
364 }
365 
366 int
367 printf(const char *fmt, ...)
368 {
369  va_list ap;
370  int retval;
371 
372  va_start(ap, fmt);
373  retval = vprintf(fmt, ap);
374  va_end(ap);
375 
376  return (retval);
377 }
378 
379 int
380 vprintf(const char *fmt, va_list ap)
381 {
382  int retval;
383 
384  retval = _vprintf(-1, TOCONS | TOLOG, fmt, ap);
385 
386  if (!panicstr)
387  msgbuftrigger = 1;
388 
389  return (retval);
390 }
391 
392 static void
393 putbuf(int c, struct putchar_arg *ap)
394 {
395  /* Check if no console output buffer was provided. */
396  if (ap->p_bufr == NULL) {
397  /* Output direct to the console. */
398  if (ap->flags & TOCONS)
399  cnputc(c);
400 
401  if (ap->flags & TOLOG)
402  msglogchar(c, ap->pri);
403  } else {
404  /* Buffer the character: */
405  *ap->p_next++ = c;
406  ap->remain--;
407 
408  /* Always leave the buffer zero terminated. */
409  *ap->p_next = '\0';
410 
411  /* Check if the buffer needs to be flushed. */
412  if (ap->remain == 2 || c == '\n') {
413 
414  if (ap->flags & TOLOG)
415  msglogstr(ap->p_bufr, ap->pri, /*filter_cr*/1);
416 
417  if (ap->flags & TOCONS) {
418  if ((panicstr == NULL) && (constty != NULL))
419  msgbuf_addstr(&consmsgbuf, -1,
420  ap->p_bufr, /*filter_cr*/ 0);
421 
422  if ((constty == NULL) ||(always_console_output))
423  cnputs(ap->p_bufr);
424  }
425 
426  ap->p_next = ap->p_bufr;
427  ap->remain = ap->n_bufr;
428  *ap->p_next = '\0';
429  }
430 
431  /*
432  * Since we fill the buffer up one character at a time,
433  * this should not happen. We should always catch it when
434  * ap->remain == 2 (if not sooner due to a newline), flush
435  * the buffer and move on. One way this could happen is
436  * if someone sets PRINTF_BUFR_SIZE to 1 or something
437  * similarly silly.
438  */
439  KASSERT(ap->remain > 2, ("Bad buffer logic, remain = %zd",
440  ap->remain));
441  }
442 }
443 
444 /*
445  * Print a character on console or users terminal. If destination is
446  * the console then the last bunch of characters are saved in msgbuf for
447  * inspection later.
448  */
449 static void
450 putchar(int c, void *arg)
451 {
452  struct putchar_arg *ap = (struct putchar_arg*) arg;
453  struct tty *tp = ap->tty;
454  int flags = ap->flags;
455  int putbuf_done = 0;
456 
457  /* Don't use the tty code after a panic or while in ddb. */
458  if (kdb_active) {
459  if (c != '\0')
460  cnputc(c);
461  } else {
462  if ((panicstr == NULL) && (flags & TOTTY) && (tp != NULL))
463  tty_putchar(tp, c);
464 
465  if (flags & TOCONS) {
466  putbuf(c, ap);
467  putbuf_done = 1;
468  }
469  }
470  if ((flags & TOLOG) && (putbuf_done == 0)) {
471  if (c != '\0')
472  putbuf(c, ap);
473  }
474 }
475 
476 /*
477  * Scaled down version of sprintf(3).
478  */
479 int
480 sprintf(char *buf, const char *cfmt, ...)
481 {
482  int retval;
483  va_list ap;
484 
485  va_start(ap, cfmt);
486  retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
487  buf[retval] = '\0';
488  va_end(ap);
489  return (retval);
490 }
491 
492 /*
493  * Scaled down version of vsprintf(3).
494  */
495 int
496 vsprintf(char *buf, const char *cfmt, va_list ap)
497 {
498  int retval;
499 
500  retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
501  buf[retval] = '\0';
502  return (retval);
503 }
504 
505 /*
506  * Scaled down version of snprintf(3).
507  */
508 int
509 snprintf(char *str, size_t size, const char *format, ...)
510 {
511  int retval;
512  va_list ap;
513 
514  va_start(ap, format);
515  retval = vsnprintf(str, size, format, ap);
516  va_end(ap);
517  return(retval);
518 }
519 
520 /*
521  * Scaled down version of vsnprintf(3).
522  */
523 int
524 vsnprintf(char *str, size_t size, const char *format, va_list ap)
525 {
526  struct snprintf_arg info;
527  int retval;
528 
529  info.str = str;
530  info.remain = size;
531  retval = kvprintf(format, snprintf_func, &info, 10, ap);
532  if (info.remain >= 1)
533  *info.str++ = '\0';
534  return (retval);
535 }
536 
537 /*
538  * Kernel version which takes radix argument vsnprintf(3).
539  */
540 int
541 vsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap)
542 {
543  struct snprintf_arg info;
544  int retval;
545 
546  info.str = str;
547  info.remain = size;
548  retval = kvprintf(format, snprintf_func, &info, radix, ap);
549  if (info.remain >= 1)
550  *info.str++ = '\0';
551  return (retval);
552 }
553 
554 static void
555 snprintf_func(int ch, void *arg)
556 {
557  struct snprintf_arg *const info = arg;
558 
559  if (info->remain >= 2) {
560  *info->str++ = ch;
561  info->remain--;
562  }
563 }
564 
565 /*
566  * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
567  * order; return an optional length and a pointer to the last character
568  * written in the buffer (i.e., the first character of the string).
569  * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
570  */
571 static char *
572 ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
573 {
574  char *p, c;
575 
576  p = nbuf;
577  *p = '\0';
578  do {
579  c = hex2ascii(num % base);
580  *++p = upper ? toupper(c) : c;
581  } while (num /= base);
582  if (lenp)
583  *lenp = p - nbuf;
584  return (p);
585 }
586 
587 /*
588  * Scaled down version of printf(3).
589  *
590  * Two additional formats:
591  *
592  * The format %b is supported to decode error registers.
593  * Its usage is:
594  *
595  * printf("reg=%b\n", regval, "<base><arg>*");
596  *
597  * where <base> is the output base expressed as a control character, e.g.
598  * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
599  * the first of which gives the bit number to be inspected (origin 1), and
600  * the next characters (up to a control character, i.e. a character <= 32),
601  * give the name of the register. Thus:
602  *
603  * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
604  *
605  * would produce output:
606  *
607  * reg=3<BITTWO,BITONE>
608  *
609  * XXX: %D -- Hexdump, takes pointer and separator string:
610  * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
611  * ("%*D", len, ptr, " " -> XX XX XX XX ...
612  */
613 int
614 kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
615 {
616 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
617  char nbuf[MAXNBUF];
618  char *d;
619  const char *p, *percent, *q;
620  u_char *up;
621  int ch, n;
622  uintmax_t num;
623  int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
624  int cflag, hflag, jflag, tflag, zflag;
625  int dwidth, upper;
626  char padc;
627  int stop = 0, retval = 0;
628 
629  num = 0;
630  if (!func)
631  d = (char *) arg;
632  else
633  d = NULL;
634 
635  if (fmt == NULL)
636  fmt = "(fmt null)\n";
637 
638  if (radix < 2 || radix > 36)
639  radix = 10;
640 
641  for (;;) {
642  padc = ' ';
643  width = 0;
644  while ((ch = (u_char)*fmt++) != '%' || stop) {
645  if (ch == '\0')
646  return (retval);
647  PCHAR(ch);
648  }
649  percent = fmt - 1;
650  qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
651  sign = 0; dot = 0; dwidth = 0; upper = 0;
652  cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
653 reswitch: switch (ch = (u_char)*fmt++) {
654  case '.':
655  dot = 1;
656  goto reswitch;
657  case '#':
658  sharpflag = 1;
659  goto reswitch;
660  case '+':
661  sign = 1;
662  goto reswitch;
663  case '-':
664  ladjust = 1;
665  goto reswitch;
666  case '%':
667  PCHAR(ch);
668  break;
669  case '*':
670  if (!dot) {
671  width = va_arg(ap, int);
672  if (width < 0) {
673  ladjust = !ladjust;
674  width = -width;
675  }
676  } else {
677  dwidth = va_arg(ap, int);
678  }
679  goto reswitch;
680  case '0':
681  if (!dot) {
682  padc = '0';
683  goto reswitch;
684  }
685  case '1': case '2': case '3': case '4':
686  case '5': case '6': case '7': case '8': case '9':
687  for (n = 0;; ++fmt) {
688  n = n * 10 + ch - '0';
689  ch = *fmt;
690  if (ch < '0' || ch > '9')
691  break;
692  }
693  if (dot)
694  dwidth = n;
695  else
696  width = n;
697  goto reswitch;
698  case 'b':
699  num = (u_int)va_arg(ap, int);
700  p = va_arg(ap, char *);
701  for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
702  PCHAR(*q--);
703 
704  if (num == 0)
705  break;
706 
707  for (tmp = 0; *p;) {
708  n = *p++;
709  if (num & (1 << (n - 1))) {
710  PCHAR(tmp ? ',' : '<');
711  for (; (n = *p) > ' '; ++p)
712  PCHAR(n);
713  tmp = 1;
714  } else
715  for (; *p > ' '; ++p)
716  continue;
717  }
718  if (tmp)
719  PCHAR('>');
720  break;
721  case 'c':
722  PCHAR(va_arg(ap, int));
723  break;
724  case 'D':
725  up = va_arg(ap, u_char *);
726  p = va_arg(ap, char *);
727  if (!width)
728  width = 16;
729  while(width--) {
730  PCHAR(hex2ascii(*up >> 4));
731  PCHAR(hex2ascii(*up & 0x0f));
732  up++;
733  if (width)
734  for (q=p;*q;q++)
735  PCHAR(*q);
736  }
737  break;
738  case 'd':
739  case 'i':
740  base = 10;
741  sign = 1;
742  goto handle_sign;
743  case 'h':
744  if (hflag) {
745  hflag = 0;
746  cflag = 1;
747  } else
748  hflag = 1;
749  goto reswitch;
750  case 'j':
751  jflag = 1;
752  goto reswitch;
753  case 'l':
754  if (lflag) {
755  lflag = 0;
756  qflag = 1;
757  } else
758  lflag = 1;
759  goto reswitch;
760  case 'n':
761  if (jflag)
762  *(va_arg(ap, intmax_t *)) = retval;
763  else if (qflag)
764  *(va_arg(ap, quad_t *)) = retval;
765  else if (lflag)
766  *(va_arg(ap, long *)) = retval;
767  else if (zflag)
768  *(va_arg(ap, size_t *)) = retval;
769  else if (hflag)
770  *(va_arg(ap, short *)) = retval;
771  else if (cflag)
772  *(va_arg(ap, char *)) = retval;
773  else
774  *(va_arg(ap, int *)) = retval;
775  break;
776  case 'o':
777  base = 8;
778  goto handle_nosign;
779  case 'p':
780  base = 16;
781  sharpflag = (width == 0);
782  sign = 0;
783  num = (uintptr_t)va_arg(ap, void *);
784  goto number;
785  case 'q':
786  qflag = 1;
787  goto reswitch;
788  case 'r':
789  base = radix;
790  if (sign)
791  goto handle_sign;
792  goto handle_nosign;
793  case 's':
794  p = va_arg(ap, char *);
795  if (p == NULL)
796  p = "(null)";
797  if (!dot)
798  n = strlen (p);
799  else
800  for (n = 0; n < dwidth && p[n]; n++)
801  continue;
802 
803  width -= n;
804 
805  if (!ladjust && width > 0)
806  while (width--)
807  PCHAR(padc);
808  while (n--)
809  PCHAR(*p++);
810  if (ladjust && width > 0)
811  while (width--)
812  PCHAR(padc);
813  break;
814  case 't':
815  tflag = 1;
816  goto reswitch;
817  case 'u':
818  base = 10;
819  goto handle_nosign;
820  case 'X':
821  upper = 1;
822  case 'x':
823  base = 16;
824  goto handle_nosign;
825  case 'y':
826  base = 16;
827  sign = 1;
828  goto handle_sign;
829  case 'z':
830  zflag = 1;
831  goto reswitch;
832 handle_nosign:
833  sign = 0;
834  if (jflag)
835  num = va_arg(ap, uintmax_t);
836  else if (qflag)
837  num = va_arg(ap, u_quad_t);
838  else if (tflag)
839  num = va_arg(ap, ptrdiff_t);
840  else if (lflag)
841  num = va_arg(ap, u_long);
842  else if (zflag)
843  num = va_arg(ap, size_t);
844  else if (hflag)
845  num = (u_short)va_arg(ap, int);
846  else if (cflag)
847  num = (u_char)va_arg(ap, int);
848  else
849  num = va_arg(ap, u_int);
850  goto number;
851 handle_sign:
852  if (jflag)
853  num = va_arg(ap, intmax_t);
854  else if (qflag)
855  num = va_arg(ap, quad_t);
856  else if (tflag)
857  num = va_arg(ap, ptrdiff_t);
858  else if (lflag)
859  num = va_arg(ap, long);
860  else if (zflag)
861  num = va_arg(ap, ssize_t);
862  else if (hflag)
863  num = (short)va_arg(ap, int);
864  else if (cflag)
865  num = (char)va_arg(ap, int);
866  else
867  num = va_arg(ap, int);
868 number:
869  if (sign && (intmax_t)num < 0) {
870  neg = 1;
871  num = -(intmax_t)num;
872  }
873  p = ksprintn(nbuf, num, base, &n, upper);
874  tmp = 0;
875  if (sharpflag && num != 0) {
876  if (base == 8)
877  tmp++;
878  else if (base == 16)
879  tmp += 2;
880  }
881  if (neg)
882  tmp++;
883 
884  if (!ladjust && padc == '0')
885  dwidth = width - tmp;
886  width -= tmp + imax(dwidth, n);
887  dwidth -= n;
888  if (!ladjust)
889  while (width-- > 0)
890  PCHAR(' ');
891  if (neg)
892  PCHAR('-');
893  if (sharpflag && num != 0) {
894  if (base == 8) {
895  PCHAR('0');
896  } else if (base == 16) {
897  PCHAR('0');
898  PCHAR('x');
899  }
900  }
901  while (dwidth-- > 0)
902  PCHAR('0');
903 
904  while (*p)
905  PCHAR(*p--);
906 
907  if (ladjust)
908  while (width-- > 0)
909  PCHAR(' ');
910 
911  break;
912  default:
913  while (percent < fmt)
914  PCHAR(*percent++);
915  /*
916  * Since we ignore an formatting argument it is no
917  * longer safe to obey the remaining formatting
918  * arguments as the arguments will no longer match
919  * the format specs.
920  */
921  stop = 1;
922  break;
923  }
924  }
925 #undef PCHAR
926 }
927 
928 /*
929  * Put character in log buffer with a particular priority.
930  */
931 static void
932 msglogchar(int c, int pri)
933 {
934  static int lastpri = -1;
935  static int dangling;
936  char nbuf[MAXNBUF];
937  char *p;
938 
939  if (!msgbufmapped)
940  return;
941  if (c == '\0' || c == '\r')
942  return;
943  if (pri != -1 && pri != lastpri) {
944  if (dangling) {
945  msgbuf_addchar(msgbufp, '\n');
946  dangling = 0;
947  }
948  msgbuf_addchar(msgbufp, '<');
949  for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL, 0); *p;)
950  msgbuf_addchar(msgbufp, *p--);
951  msgbuf_addchar(msgbufp, '>');
952  lastpri = pri;
953  }
954  msgbuf_addchar(msgbufp, c);
955  if (c == '\n') {
956  dangling = 0;
957  lastpri = -1;
958  } else {
959  dangling = 1;
960  }
961 }
962 
963 static void
964 msglogstr(char *str, int pri, int filter_cr)
965 {
966  if (!msgbufmapped)
967  return;
968 
969  msgbuf_addstr(msgbufp, pri, str, filter_cr);
970 }
971 
972 void
973 msgbufinit(void *ptr, int size)
974 {
975  char *cp;
976  static struct msgbuf *oldp = NULL;
977 
978  size -= sizeof(*msgbufp);
979  cp = (char *)ptr;
980  msgbufp = (struct msgbuf *)(cp + size);
981  msgbuf_reinit(msgbufp, cp, size);
982  if (msgbufmapped && oldp != msgbufp)
983  msgbuf_copy(oldp, msgbufp);
984  msgbufmapped = 1;
985  oldp = msgbufp;
986 }
987 
989 SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_read_msgbuf,
990  CTLFLAG_RW, &unprivileged_read_msgbuf, 0,
991  "Unprivileged processes may read the kernel message buffer");
992 
993 /* Sysctls for accessing/clearing the msgbuf */
994 static int
995 sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
996 {
997  char buf[128];
998  u_int seq;
999  int error, len;
1000 
1001  if (!unprivileged_read_msgbuf) {
1002  error = priv_check(req->td, PRIV_MSGBUF);
1003  if (error)
1004  return (error);
1005  }
1006 
1007  /* Read the whole buffer, one chunk at a time. */
1008  mtx_lock(&msgbuf_lock);
1009  msgbuf_peekbytes(msgbufp, NULL, 0, &seq);
1010  for (;;) {
1011  len = msgbuf_peekbytes(msgbufp, buf, sizeof(buf), &seq);
1012  mtx_unlock(&msgbuf_lock);
1013  if (len == 0)
1014  return (0);
1015 
1016  error = sysctl_handle_opaque(oidp, buf, len, req);
1017  if (error)
1018  return (error);
1019 
1020  mtx_lock(&msgbuf_lock);
1021  }
1022 }
1023 
1024 SYSCTL_PROC(_kern, OID_AUTO, msgbuf,
1025  CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
1026  NULL, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer");
1027 
1028 static int msgbuf_clearflag;
1029 
1030 static int
1031 sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS)
1032 {
1033  int error;
1034  error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
1035  if (!error && req->newptr) {
1036  mtx_lock(&msgbuf_lock);
1037  msgbuf_clear(msgbufp);
1038  mtx_unlock(&msgbuf_lock);
1039  msgbuf_clearflag = 0;
1040  }
1041  return (error);
1042 }
1043 
1044 SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear,
1045  CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE,
1046  &msgbuf_clearflag, 0, sysctl_kern_msgbuf_clear, "I",
1047  "Clear kernel message buffer");
1048 
1049 #ifdef DDB
1050 
1051 DB_SHOW_COMMAND(msgbuf, db_show_msgbuf)
1052 {
1053  int i, j;
1054 
1055  if (!msgbufmapped) {
1056  db_printf("msgbuf not mapped yet\n");
1057  return;
1058  }
1059  db_printf("msgbufp = %p\n", msgbufp);
1060  db_printf("magic = %x, size = %d, r= %u, w = %u, ptr = %p, cksum= %u\n",
1061  msgbufp->msg_magic, msgbufp->msg_size, msgbufp->msg_rseq,
1062  msgbufp->msg_wseq, msgbufp->msg_ptr, msgbufp->msg_cksum);
1063  for (i = 0; i < msgbufp->msg_size && !db_pager_quit; i++) {
1064  j = MSGBUF_SEQ_TO_POS(msgbufp, i + msgbufp->msg_rseq);
1065  db_printf("%c", msgbufp->msg_ptr[j]);
1066  }
1067  db_printf("\n");
1068 }
1069 
1070 #endif /* DDB */
1071 
1072 void
1073 hexdump(const void *ptr, int length, const char *hdr, int flags)
1074 {
1075  int i, j, k;
1076  int cols;
1077  const unsigned char *cp;
1078  char delim;
1079 
1080  if ((flags & HD_DELIM_MASK) != 0)
1081  delim = (flags & HD_DELIM_MASK) >> 8;
1082  else
1083  delim = ' ';
1084 
1085  if ((flags & HD_COLUMN_MASK) != 0)
1086  cols = flags & HD_COLUMN_MASK;
1087  else
1088  cols = 16;
1089 
1090  cp = ptr;
1091  for (i = 0; i < length; i+= cols) {
1092  if (hdr != NULL)
1093  printf("%s", hdr);
1094 
1095  if ((flags & HD_OMIT_COUNT) == 0)
1096  printf("%04x ", i);
1097 
1098  if ((flags & HD_OMIT_HEX) == 0) {
1099  for (j = 0; j < cols; j++) {
1100  k = i + j;
1101  if (k < length)
1102  printf("%c%02x", delim, cp[k]);
1103  else
1104  printf(" ");
1105  }
1106  }
1107 
1108  if ((flags & HD_OMIT_CHARS) == 0) {
1109  printf(" |");
1110  for (j = 0; j < cols; j++) {
1111  k = i + j;
1112  if (k >= length)
1113  printf(" ");
1114  else if (cp[k] >= ' ' && cp[k] <= '~')
1115  printf("%c", cp[k]);
1116  else
1117  printf(".");
1118  }
1119  printf("|");
1120  }
1121  printf("\n");
1122  }
1123 }
1124 
#define TOLOG
Definition: subr_prf.c:74
static char * ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper)
Definition: subr_prf.c:572
struct uio * cloneuio(struct uio *uiop)
Definition: subr_uio.c:544
int vsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap)
Definition: subr_prf.c:541
size_t n_bufr
Definition: subr_prf.c:84
struct buf * buf
Definition: vfs_bio.c:97
char * p_next
Definition: subr_prf.c:85
static int _vprintf(int level, int flags, const char *fmt, va_list ap)
Definition: subr_prf.c:245
int snprintf(char *str, size_t size, const char *format,...)
Definition: subr_prf.c:509
size_t remain
Definition: subr_prf.c:86
void sess_hold(struct session *s)
Definition: kern_proc.c:709
static int log_console_output
Definition: subr_prf.c:105
char * str
Definition: subr_prf.c:90
int sprintf(char *buf, const char *cfmt,...)
Definition: subr_prf.c:480
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
Definition: kern_malloc.c:454
static int sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS)
Definition: subr_prf.c:1031
const char * panicstr
int kvprintf(char const *fmt, void(*func)(int, void *), void *arg, int radix, va_list ap)
Definition: subr_prf.c:614
int log_open
Definition: subr_log.c:94
void sess_release(struct session *s)
Definition: kern_proc.c:716
static void putchar(int ch, void *arg)
Definition: subr_prf.c:450
#define MAXNBUF
Definition: subr_prf.c:77
static int msgbufmapped
Definition: subr_prf.c:102
int nbuf
Definition: subr_param.c:93
void hexdump(const void *ptr, int length, const char *hdr, int flags)
Definition: subr_prf.c:1073
int uprintf(const char *fmt,...)
Definition: subr_prf.c:137
void tablefull(const char *tab)
Definition: subr_prf.c:127
TUNABLE_INT("kern.log_console_output",&log_console_output)
int vsnprintf(char *str, size_t size, const char *format, va_list ap)
Definition: subr_prf.c:524
void tprintf(struct proc *p, int pri, const char *fmt,...)
Definition: subr_prf.c:181
int ttyprintf(struct tty *tp, const char *fmt,...)
Definition: subr_prf.c:229
static int sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
Definition: subr_prf.c:995
int priv_check(struct thread *td, int priv)
Definition: kern_priv.c:170
size_t remain
Definition: subr_prf.c:91
int msgbuf_peekbytes(struct msgbuf *mbp, char *buf, int buflen, u_int *seqp)
Definition: subr_msgbuf.c:360
#define PCHAR(c)
static void msglogstr(char *str, int pri, int filter_cr)
Definition: subr_prf.c:964
void msgbuf_addchar(struct msgbuf *mbp, int c)
Definition: subr_msgbuf.c:165
void log_console(struct uio *uio)
Definition: subr_prf.c:303
int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS)
Definition: kern_sysctl.c:1163
int vsprintf(char *buf, const char *cfmt, va_list ap)
Definition: subr_prf.c:496
static const int qflag
Definition: inflate.c:49
void msgbuf_addstr(struct msgbuf *mbp, int pri, char *str, int filter_cr)
Definition: subr_msgbuf.c:183
#define TOTTY
Definition: subr_prf.c:73
int tty_putchar(struct tty *tp, char c)
Definition: tty_ttydisc.c:1256
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
Definition: kern_sysctl.c:986
#define CONSCHUNK
Definition: subr_prf.c:300
char * p_bufr
Definition: subr_prf.c:83
void log(int level, const char *fmt,...)
Definition: subr_prf.c:289
__FBSDID("$BSDSUniX$")
int tty_checkoutq(struct tty *tp)
Definition: tty.c:1767
struct mtx msgbuf_lock
Definition: subr_log.c:96
SYSCTL_PROC(_kern, OID_AUTO, msgbuf, CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, 0, sysctl_kern_msgbuf,"A","Contents of kernel message buffer")
int uiomove(void *cp, int n, struct uio *uio)
Definition: subr_uio.c:202
void free(void *addr, struct malloc_type *mtp)
Definition: kern_malloc.c:554
int printf(const char *fmt,...)
Definition: subr_prf.c:367
void msgbuf_copy(struct msgbuf *src, struct msgbuf *dst)
Definition: subr_msgbuf.c:412
struct tty * tty
Definition: subr_prf.c:82
void msgbufinit(void *ptr, int size)
Definition: subr_prf.c:973
static void putbuf(int c, struct putchar_arg *ap)
Definition: subr_prf.c:393
static int unprivileged_read_msgbuf
Definition: subr_prf.c:988
void msgbuf_reinit(struct msgbuf *mbp, void *ptr, int size)
Definition: subr_msgbuf.c:85
#define TOCONS
Definition: subr_prf.c:72
int msgbuftrigger
Definition: subr_prf.c:103
SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW,&log_console_output, 0,"Duplicate console output to the syslog.")
static int msgbuf_clearflag
Definition: subr_prf.c:1028
int vprintf(const char *fmt, va_list ap)
Definition: subr_prf.c:380
void cnputc(int c)
Definition: kern_cons.c:463
void msgbuf_clear(struct msgbuf *mbp)
Definition: subr_msgbuf.c:118
int kdb_active
Definition: subr_kdb.c:53
struct sx proctree_lock
Definition: kern_proc.c:137
static int always_console_output
Definition: subr_prf.c:118
void cnputs(char *p)
Definition: kern_cons.c:494
int flags
Definition: subr_prf.c:80
static int log_console_add_linefeed
Definition: subr_prf.c:113
void *** stop
Definition: linker_if.m:87
static void snprintf_func(int ch, void *arg)
Definition: subr_prf.c:555
const struct cf_level * level
Definition: cpufreq_if.m:45
static void msglogchar(int c, int pri)
Definition: subr_prf.c:932