* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)subr_prf.c 7.2 (Berkeley) %G%
* In case console is off,
* panicstr contains argument to last
extern cnputc(); /* standard console putc */
extern struct tty cons
; /* standard console tty */
struct tty
*constty
; /* pointer to console "window" tty */
int (*v_console
)() = cnputc
; /* routine to putc on virtual console */
* Scaled down version of C Library printf.
* Used to print diagnostic information directly on console tty.
* Since it is not interrupt driven, all system activities are
* suspended. Printf should not be used for chit-chat.
* One additional format: %b is supported to decode error registers.
* printf("reg=%b\n", regval, "<base><arg>*");
* Where <base> is the output base expressed as a control character,
* e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of
* characters, the first of which gives the bit number to be inspected
* (origin 1), and the next characters (up to a control character, i.e.
* a character <= 32), give the name of the register. Thus
* printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
prf(fmt
, &x1
, TOCONS
| TOLOG
, (struct tty
*)0);
* Uprintf prints to the current user's terminal.
* It may block if the tty queue is overfull.
* Should determine whether current terminal user is related
if ((tp
= u
.u_ttyp
) == NULL
)
if (tp
->t_pgrp
&& (p
= pfind(tp
->t_pgrp
)))
if (p
->p_uid
!= u
.u_uid
) /* doesn't account for setuid */
(void)ttycheckoutq(tp
, 1);
prf(fmt
, &x1
, TOTTY
, tp
);
* tprintf prints on the specified terminal (console if none)
* and logs the message. It is designed for error messages from
* single-open devices, and may be called from interrupt level
int flags
= TOTTY
| TOLOG
;
if (tp
== (struct tty
*)NULL
) {
if (tp
== (struct tty
*)NULL
)
if (ttycheckoutq(tp
, 0) == 0)
prf(fmt
, &x1
, flags
, tp
);
* Log writes to the log buffer,
* and guarantees not to sleep (so can be called by interrupt routines).
* If there is no process reading the log yet, it writes to the console also.
prf(fmt
, &x1
, TOLOG
, (struct tty
*)0);
prf(fmt
, &x1
, TOCONS
, (struct tty
*)0);
putchar('<', TOLOG
, (struct tty
*)0);
printn((u_long
)level
, 10, TOLOG
, (struct tty
*)0);
putchar('>', TOLOG
, (struct tty
*)0);
prf(fmt
, adx
, flags
, ttyp
)
while ((c
= *fmt
++) != '%') {
/* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
case 'u': /* what a joke */
printn((u_long
)*adx
, b
, flags
, ttyp
);
for (i
= 24; i
>= 0; i
-= 8)
printn((u_long
)b
, *s
++, flags
, ttyp
);
putchar(any
? ',' : '<', flags
, ttyp
);
for (; (c
= *s
) > 32; s
++)
putchar('>', flags
, ttyp
);
putchar('%', flags
, ttyp
);
* Printn prints a number n in base b.
* We don't use recursion to avoid deep kernel stacks.
printn(n
, b
, flags
, ttyp
)
if (b
== 10 && (int)n
< 0) {
putchar('-', flags
, ttyp
);
*cp
++ = "0123456789abcdef"[n
%b
];
putchar(*--cp
, flags
, ttyp
);
* Panic is called on unresolvable fatal errors.
* It prints "panic: mesg", and then reboots.
* If we are called twice, then we avoid trying to
* sync the disks as this often leads to recursive panics.
int bootopt
= RB_AUTOBOOT
;
printf("panic: %s\n", s
);
* Warn that a system table is full.
log(LOG_ERR
, "%s: table is full\n", tab
);
* Hard error is the preface to plaintive error messages
* about failing disk transfers.
printf("%s%d%c: hard error sn%d ", cp
,
minor(bp
->b_dev
) >> 3, 'a'+(minor(bp
->b_dev
)&07), bp
->b_blkno
);
* Print a character on console or users terminal.
* If destination is console then the last MSGBUFS characters
* are saved in msgbuf for inspection later.
if ((flags
& TOCONS
) && panicstr
== 0 && tp
== 0 && constty
) {
if (tp
&& (tp
->t_state
& (TS_CARR_ON
| TS_ISOPEN
)) ==
(TS_CARR_ON
| TS_ISOPEN
)) {
(void) ttyoutput('\r', tp
);
} else if ((flags
& TOCONS
) && tp
== constty
)
if ((flags
& TOLOG
) && c
!= '\0' && c
!= '\r' && c
!= 0177
if (msgbuf
.msg_magic
!= MSG_MAGIC
) {
msgbuf
.msg_magic
= MSG_MAGIC
;
msgbuf
.msg_bufx
= msgbuf
.msg_bufr
= 0;
for (i
=0; i
< MSG_BSIZE
; i
++)
msgbuf
.msg_bufc
[msgbuf
.msg_bufx
++] = c
;
if (msgbuf
.msg_bufx
< 0 || msgbuf
.msg_bufx
>= MSG_BSIZE
)
if ((flags
& TOCONS
) && c
!= '\0')