2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
25 * Copyright (c) 1986, 1988, 1991, 1993
26 * The Regents of the University of California. All rights reserved.
27 * (c) UNIX System Laboratories, Inc.
28 * All or some portions of this file are derived from material licensed
29 * to the University of California by American Telephone and Telegraph
30 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
31 * the permission of UNIX System Laboratories, Inc.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by the University of
44 * California, Berkeley and its contributors.
45 * 4. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * @(#)subr_prf.c 8.4 (Berkeley) 5/4/95
64 * 22-Sep-1997 Umesh Vaishampayan (umeshv@apple.com)
65 * Cleaned up m68k crud. Fixed vlog() to do logpri() for ppc, too.
67 * 17-July-97 Umesh Vaishampayan (umeshv@apple.com)
68 * Eliminated multiple definition of constty which is defined
69 * in bsd/dev/XXX/cons.c
71 * 26-MAR-1997 Umesh Vaishampayan (umeshv@NeXT.com
72 * Fixed tharshing format in many functions. Cleanup.
74 * 17-Jun-1995 Mac Gillon (mgillon) at NeXT
76 * New version based on 4.4 and NS3.3
79 #include <sys/param.h>
80 #include <sys/systm.h>
82 #include <sys/reboot.h>
83 #include <sys/msgbuf.h>
84 #include <sys/proc_internal.h>
85 #include <sys/ioctl.h>
87 #include <sys/file_internal.h>
88 #include <sys/tprintf.h>
89 #include <sys/syslog.h>
91 #include <sys/malloc.h>
93 #include <sys/subr_prf.h>
95 #include <kern/cpu_number.h> /* for cpu_number() */
96 #include <machine/spl.h>
97 #include <libkern/libkern.h>
106 * In case console is off,
107 * panicstr contains argument to last
110 extern const char *panicstr
;
112 extern cnputc(); /* standard console putc */
113 int (*v_putc
)() = cnputc
; /* routine to putc on virtual console */
115 extern struct tty cons
; /* standard console tty */
116 extern struct tty
*constty
; /* pointer to console "window" tty */
117 extern int __doprnt(const char *fmt
,
119 void (*putc
)(int, void *arg
),
124 * Record cpu that panic'd and lock around panic data
127 static void puts(const char *s
, int flags
, struct tty
*ttyp
);
128 static void printn(u_long n
, int b
, int flags
, struct tty
*ttyp
, int zf
, int fld_size
);
131 boolean_t new_printf_cpu_number
; /* do we need to output who we are */
134 extern void logwakeup();
135 extern void halt_cpu();
140 snprintf_func(int ch
, void *arg
);
142 struct putchar_args
{
146 static void putchar(int c
, void *arg
);
150 * Uprintf prints to the controlling terminal for the current process.
151 * It may block if the tty queue is overfull. No message is printed if
152 * the queue does not clear in a reasonable time.
155 uprintf(const char *fmt
, ...)
157 register struct proc
*p
= current_proc();
158 struct putchar_args pca
;
162 pca
.tty
= (struct tty
*)p
->p_session
->s_ttyp
;
164 if (p
->p_flag
& P_CONTROLT
&& p
->p_session
->s_ttyvp
) {
166 __doprnt(fmt
, &ap
, putchar
, &pca
, 10);
173 register struct proc
*p
;
175 if (p
->p_flag
& P_CONTROLT
&& p
->p_session
->s_ttyvp
) {
176 SESSHOLD(p
->p_session
);
177 return ((tpr_t
) p
->p_session
);
179 return ((tpr_t
) NULL
);
187 SESSRELE((struct session
*) sess
);
191 * tprintf prints on the controlling terminal associated
192 * with the given session.
195 tprintf(tpr_t tpr
, const char *fmt
, ...)
197 register struct session
*sess
= (struct session
*)tpr
;
198 struct tty
*tp
= NULL
;
201 struct putchar_args pca
;
204 if (sess
&& sess
->s_ttyvp
&& ttycheckoutq(sess
->s_ttyp
, 0)) {
212 __doprnt(fmt
, &ap
, putchar
, &pca
, 10);
219 * Ttyprintf displays a message on a tty; it should be used only by
220 * the tty driver, or anything that knows the underlying tty will not
221 * be revoke(2)'d away. Other callers should use tprintf.
224 ttyprintf(struct tty
*tp
, const char *fmt
, ...)
229 struct putchar_args pca
;
234 __doprnt(fmt
, &ap
, putchar
, &pca
, 10);
246 struct putchar_args pca
;
251 printn((u_long
)level
, 10, TOLOG
, (struct tty
*)0, 0, 0);
256 addlog(const char *fmt
, ...)
258 register s
= splhigh();
260 struct putchar_args pca
;
266 __doprnt(fmt
, &ap
, putchar
, &pca
, 10);
271 __doprnt(fmt
, &ap
, putchar
, &pca
, 10);
276 void _printf(int flags
, struct tty
*ttyp
, const char *format
, ...)
279 struct putchar_args pca
;
284 va_start(ap
, format
);
285 __doprnt(format
, &ap
, putchar
, &pca
, 10);
289 int prf(const char *fmt
, va_list ap
, int flags
, struct tty
*ttyp
)
291 struct putchar_args pca
;
297 int cpun
= cpu_number();
303 if (cpun
!= master_cpu
)
304 new_printf_cpu_number
= TRUE
;
306 if (new_printf_cpu_number
) {
307 putchar('{', flags
, ttyp
);
308 printn((u_long
)cpun
, 10, flags
, ttyp
, 0, 0);
309 putchar('}', flags
, ttyp
);
311 #endif /* NCPUS > 1 */
313 __doprnt(fmt
, &ap
, putchar
, &pca
, 10);
324 static void puts(const char *s
, int flags
, struct tty
*ttyp
)
327 struct putchar_args pca
;
337 * Printn prints a number n in base b.
338 * We don't use recursion to avoid deep kernel stacks.
340 static void printn(u_long n
, int b
, int flags
, struct tty
*ttyp
, int zf
, int fld_size
)
344 struct putchar_args pca
;
349 if (b
== 10 && (int)n
< 0) {
351 n
= (unsigned)(-(int)n
);
355 *cp
++ = "0123456789abcdef"[n%b
];
359 for (fld_size
-= cp
- prbuf
; fld_size
> 0; fld_size
--)
366 putchar(*--cp
, &pca
);
373 * Warn that a system table is full.
375 void tablefull(const char *tab
)
377 log(LOG_ERR
, "%s: table is full\n", tab
);
381 * Print a character on console or users terminal.
382 * If destination is console then the last MSGBUFS characters
383 * are saved in msgbuf for inspection later.
387 putchar(int c
, void *arg
)
389 struct putchar_args
*pca
= arg
;
390 register struct msgbuf
*mbp
;
391 char **sp
= (char**) pca
->tty
;
395 if ((pca
->flags
& TOCONS
) && pca
->tty
== NULL
&& constty
) {
399 if ((pca
->flags
& TOTTY
) && pca
->tty
&& tputchar(c
, pca
->tty
) < 0 &&
400 (pca
->flags
& TOCONS
) && pca
->tty
== constty
)
402 if ((pca
->flags
& TOLOG
) && c
!= '\0' && c
!= '\r' && c
!= 0177)
404 if ((pca
->flags
& TOCONS
) && constty
== 0 && c
!= '\0')
406 if (pca
->flags
& TOSTR
) {
415 * Scaled down version of vsprintf(3).
418 vsprintf(char *buf
, const char *cfmt
, va_list ap
)
421 struct snprintf_arg info
;
424 info
.remain
= 999999;
426 retval
= __doprnt(cfmt
, &ap
, snprintf_func
, &info
, 10);
427 if (info
.remain
>= 1) {
434 * Scaled down version of snprintf(3).
437 snprintf(char *str
, size_t size
, const char *format
, ...)
442 va_start(ap
, format
);
443 retval
= vsnprintf(str
, size
, format
, ap
);
449 * Scaled down version of vsnprintf(3).
452 vsnprintf(char *str
, size_t size
, const char *format
, va_list ap
)
454 struct snprintf_arg info
;
459 retval
= __doprnt(format
, &ap
, snprintf_func
, &info
, 10);
460 if (info
.remain
>= 1)
466 snprintf_func(int ch
, void *arg
)
468 struct snprintf_arg
*const info
= arg
;
470 if (info
->remain
>= 2) {
477 kvprintf(char const *fmt
, void (*func
)(int, void*), void *arg
, int radix
, va_list ap
)
479 __doprnt(fmt
, &ap
, func
, arg
, radix
);