X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/39236c6e673c41db228275375ab7fdb0f837b292..f427ee49d309d8fc33ebf3042c3a775f2f530ded:/bsd/kern/subr_prf.c diff --git a/bsd/kern/subr_prf.c b/bsd/kern/subr_prf.c index 5bb098bbb..d5d5c7de7 100644 --- a/bsd/kern/subr_prf.c +++ b/bsd/kern/subr_prf.c @@ -2,7 +2,7 @@ * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,7 +22,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ @@ -74,8 +74,8 @@ * in bsd/dev/XXX/cons.c * * 26-MAR-1997 Umesh Vaishampayan (umeshv@NeXT.com - * Fixed tharshing format in many functions. Cleanup. - * + * Fixed tharshing format in many functions. Cleanup. + * * 17-Jun-1995 Mac Gillon (mgillon) at NeXT * Purged old history * New version based on 4.4 and NS3.3 @@ -97,14 +97,17 @@ #include #include -#include /* for cpu_number() */ -#include +#include /* for cpu_number() */ #include +#include /* for vaddlog(): the following are implemented in osfmk/kern/printf.c */ -extern void bsd_log_lock(void); +extern bool bsd_log_lock(bool); extern void bsd_log_unlock(void); +uint32_t vaddlog_msgcount = 0; +uint32_t vaddlog_msgcount_dropped = 0; + /* Keep this around only because it's exported */ void _printf(int, struct tty *, const char *, ...); @@ -116,29 +119,28 @@ struct snprintf_arg { /* * In case console is off, - * panicstr contains argument to last + * debugger_panic_str contains argument to last * call to panic. */ -extern const char *panicstr; +extern const char *debugger_panic_str; -extern void cnputc(char); /* standard console putc */ -void (*v_putc)(char) = cnputc; /* routine to putc on virtual console */ +extern void cnputc(char); /* standard console putc */ -extern struct tty cons; /* standard console tty */ -extern struct tty *constty; /* pointer to console "window" tty */ +extern struct tty cons; /* standard console tty */ +extern struct tty *constty; /* pointer to console "window" tty */ extern int __doprnt(const char *fmt, - va_list argp, - void (*)(int, void *), - void *arg, - int radix); + va_list argp, + void (*)(int, void *), + void *arg, + int radix, + int is_log); /* * Record cpu that panic'd and lock around panic data */ -static void printn(uint32_t n, int b, int flags, struct tty *ttyp, int zf, int fld_size); -extern void logwakeup(void); -extern void halt_cpu(void); +extern void logwakeup(struct msgbuf *); +extern void halt_cpu(void); static void snprintf_func(int ch, void *arg); @@ -146,6 +148,7 @@ snprintf_func(int ch, void *arg); struct putchar_args { int flags; struct tty *tty; + bool last_char_was_cr; }; static void putchar(int c, void *arg); @@ -162,22 +165,25 @@ uprintf(const char *fmt, ...) struct putchar_args pca; va_list ap; struct session *sessp; - + sessp = proc_session(p); if (p->p_flag & P_CONTROLT && sessp != SESSION_NULL && sessp->s_ttyvp) { pca.flags = TOTTY; pca.tty = SESSION_TP(sessp); - if (pca.tty != NULL) + if (pca.tty != NULL) { tty_lock(pca.tty); + } va_start(ap, fmt); - __doprnt(fmt, ap, putchar, &pca, 10); + __doprnt(fmt, ap, putchar, &pca, 10, FALSE); va_end(ap); - if (pca.tty != NULL) - tty_unlock(pca.tty); + if (pca.tty != NULL) { + tty_unlock(pca.tty); + } } - if (sessp != SESSION_NULL) + if (sessp != SESSION_NULL) { session_rele(sessp); + } } tpr_t @@ -188,19 +194,21 @@ tprintf_open(struct proc *p) sessp = proc_session(p); if (p->p_flag & P_CONTROLT && sessp->s_ttyvp) { - return ((tpr_t)sessp); + return (tpr_t)sessp; } - if (sessp != SESSION_NULL) + if (sessp != SESSION_NULL) { session_rele(sessp); + } - return ((tpr_t) NULL); + return (tpr_t) NULL; } void tprintf_close(tpr_t sessp) { - if (sessp) + if (sessp) { session_rele((struct session *) sessp); + } } /* @@ -213,36 +221,27 @@ void tprintf(tpr_t tpr, const char *fmt, ...) { struct session *sess = (struct session *)tpr; - struct tty *tp = TTY_NULL; - int flags = TOLOG; + struct tty *tp; va_list ap; struct putchar_args pca; - logpri(LOG_INFO); - if (sess && (tp = SESSION_TP(sess)) != TTY_NULL) { /* ttycheckoutq(), tputchar() require a locked tp */ tty_lock(tp); - if(ttycheckoutq(tp, 0)) { - flags |= TOTTY; + if (ttycheckoutq(tp, 0)) { + pca.flags = TOTTY; /* going to the tty; leave locked */ - } else { - /* not going to the tty... */ - tty_unlock(tp); - tp = TTY_NULL; + pca.tty = tp; + va_start(ap, fmt); + __doprnt(fmt, ap, putchar, &pca, 10, FALSE); + va_end(ap); } + tty_unlock(tp); } - - pca.flags = flags; - pca.tty = tp; + va_start(ap, fmt); - __doprnt(fmt, ap, putchar, &pca, 10); + os_log_with_args(OS_LOG_DEFAULT, OS_LOG_TYPE_DEFAULT, fmt, ap, __builtin_return_address(0)); va_end(ap); - - if (tp != NULL) - tty_unlock(tp); /* lock/unlock is guarded by tp, above */ - - logwakeup(); } /* @@ -263,61 +262,51 @@ ttyprintf(struct tty *tp, const char *fmt, ...) struct putchar_args pca; pca.flags = TOTTY; pca.tty = tp; - + va_start(ap, fmt); - __doprnt(fmt, ap, putchar, &pca, 10); + __doprnt(fmt, ap, putchar, &pca, 10, TRUE); va_end(ap); } } - -extern int log_open; - - void -logpri(int level) +logtime(time_t secs) { - struct putchar_args pca; - pca.flags = TOLOG; - pca.tty = NULL; - - putchar('<', &pca); - printn((uint32_t)level, 10, TOLOG, (struct tty *)0, 0, 0); - putchar('>', &pca); + printf("Time 0x%lx Message ", secs); } static void -_logtime(const char *fmt, ...) +putchar_asl(int c, void *arg) { - va_list ap; - va_start(ap, fmt); - vaddlog(fmt, ap); - va_end(ap); -} + struct putchar_args *pca = arg; -void -logtime(time_t secs) -{ - _logtime(" 0 [Time %ld] [Message ", secs); + if ((pca->flags & TOLOGLOCKED) && c != '\0' && c != '\r' && c != 0177) { + log_putc_locked(aslbufp, (char)c); + } + putchar(c, arg); } +/* + * Vestigial support for kern_asl_msg() via /dev/klog + */ int vaddlog(const char *fmt, va_list ap) { - struct putchar_args pca; - - pca.flags = TOLOGLOCKED; - pca.tty = NULL; - - if (!log_open) { - pca.flags |= TOCONS; + if (!bsd_log_lock(oslog_is_safe())) { + os_atomic_inc(&vaddlog_msgcount_dropped, relaxed); + return 1; } - bsd_log_lock(); - __doprnt(fmt, ap, putchar, &pca, 10); + struct putchar_args pca = { + .flags = TOLOGLOCKED, + .tty = NULL, + }; + + __doprnt(fmt, ap, putchar_asl, &pca, 10, TRUE); bsd_log_unlock(); - - logwakeup(); + logwakeup(NULL); + + os_atomic_inc(&vaddlog_msgcount, relaxed); return 0; } @@ -332,9 +321,9 @@ _printf(int flags, struct tty *ttyp, const char *format, ...) if (ttyp != NULL) { tty_lock(ttyp); - + va_start(ap, format); - __doprnt(format, ap, putchar, &pca, 10); + __doprnt(format, ap, putchar, &pca, 10, TRUE); va_end(ap); tty_unlock(ttyp); @@ -349,52 +338,16 @@ prf(const char *fmt, va_list ap, int flags, struct tty *ttyp) pca.flags = flags; pca.tty = ttyp; - __doprnt(fmt, ap, putchar, &pca, 10); + __doprnt(fmt, ap, putchar, &pca, 10, TRUE); return 0; } -/* - * Printn prints a number n in base b. - * We don't use recursion to avoid deep kernel stacks. - */ -static void -printn(uint32_t n, int b, int flags, struct tty *ttyp, int zf, int fld_size) -{ - char prbuf[11]; - char *cp; - struct putchar_args pca; - - pca.flags = flags; - pca.tty = ttyp; - - if (b == 10 && (int)n < 0) { - putchar('-', &pca); - n = (unsigned)(-(int)n); - } - cp = prbuf; - do { - *cp++ = "0123456789abcdef"[n%b]; - n /= b; - } while (n); - if (fld_size) { - for (fld_size -= cp - prbuf; fld_size > 0; fld_size--) - if (zf) - putchar('0', &pca); - else - putchar(' ', &pca); - } - do - putchar(*--cp, &pca); - while (cp > prbuf); -} - - - /* * Warn that a system table is full. */ -void tablefull(const char *tab) +void +tablefull(const char *tab) { log(LOG_ERR, "%s: table is full\n", tab); } @@ -414,44 +367,68 @@ putchar(int c, void *arg) struct putchar_args *pca = arg; char **sp = (char**) pca->tty; - if (panicstr) + if (debugger_panic_str) { constty = 0; + } if ((pca->flags & TOCONS) && pca->tty == NULL && constty) { pca->tty = constty; pca->flags |= TOTTY; } if ((pca->flags & TOTTY) && pca->tty && tputchar(c, pca->tty) < 0 && - (pca->flags & TOCONS) && pca->tty == constty) + (pca->flags & TOCONS) && pca->tty == constty) { constty = 0; - if ((pca->flags & TOLOG) && c != '\0' && c != '\r' && c != 0177) - log_putc(c); - if ((pca->flags & TOLOGLOCKED) && c != '\0' && c != '\r' && c != 0177) - log_putc_locked(c); - if ((pca->flags & TOCONS) && constty == 0 && c != '\0') - (*v_putc)(c); + } + if ((pca->flags & TOLOG) && c != '\0' && c != '\r' && c != 0177) { + log_putc((char)c); + } + if ((pca->flags & TOLOGLOCKED) && c != '\0' && c != '\r' && c != 0177) { + log_putc_locked(msgbufp, (char)c); + } + if ((pca->flags & TOCONS) && constty == 0 && c != '\0') { + cnputc((char)c); + } if (pca->flags & TOSTR) { - **sp = c; + **sp = (char)c; (*sp)++; } + + pca->last_char_was_cr = ('\n' == c); } -int -vprintf(const char *fmt, va_list ap) +bool +printf_log_locked(bool addcr, const char *fmt, ...) +{ + bool retval; + va_list args; + + va_start(args, fmt); + retval = vprintf_log_locked(fmt, args, addcr); + va_end(args); + + return retval; +} + +bool +vprintf_log_locked(const char *fmt, va_list ap, bool addcr) { struct putchar_args pca; - pca.flags = TOLOG | TOCONS; + pca.flags = TOLOGLOCKED; pca.tty = NULL; - __doprnt(fmt, ap, putchar, &pca, 10); - return 0; + pca.last_char_was_cr = false; + __doprnt(fmt, ap, putchar, &pca, 10, TRUE); + if (addcr) { + putchar('\n', &pca); + } + return pca.last_char_was_cr; } - +#if CONFIG_VSPRINTF /* * Scaled down version of vsprintf(3). * * Deprecation Warning: - * vsprintf() is being deprecated. Please use vsnprintf() instead. + * vsprintf() is being deprecated. Please use vsnprintf() instead. */ int vsprintf(char *buf, const char *cfmt, va_list ap) @@ -462,12 +439,13 @@ vsprintf(char *buf, const char *cfmt, va_list ap) info.str = buf; info.remain = 999999; - retval = __doprnt(cfmt, ap, snprintf_func, &info, 10); + retval = __doprnt(cfmt, ap, snprintf_func, &info, 10, FALSE); if (info.remain >= 1) { *info.str++ = '\0'; } return 0; } +#endif /* CONFIG_VSPRINTF */ /* * Scaled down version of snprintf(3). @@ -481,7 +459,7 @@ snprintf(char *str, size_t size, const char *format, ...) va_start(ap, format); retval = vsnprintf(str, size, format, ap); va_end(ap); - return(retval); + return retval; } /* @@ -495,19 +473,44 @@ vsnprintf(char *str, size_t size, const char *format, va_list ap) info.str = str; info.remain = size; - retval = __doprnt(format, ap, snprintf_func, &info, 10); - if (info.remain >= 1) + retval = __doprnt(format, ap, snprintf_func, &info, 10, FALSE); + if (info.remain >= 1) { *info.str++ = '\0'; + } return retval; } +int +vscnprintf(char *buf, size_t size, const char *fmt, va_list args) +{ + ssize_t ssize = size; + int i; + + i = vsnprintf(buf, size, fmt, args); + + return (i >= ssize) ? (int)(ssize - 1) : i; +} + +int +scnprintf(char *buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = vscnprintf(buf, size, fmt, args); + va_end(args); + + return i; +} + static void snprintf_func(int ch, void *arg) { struct snprintf_arg *const info = arg; if (info->remain >= 2) { - *info->str++ = ch; + *info->str++ = (char)ch; info->remain--; } } @@ -515,7 +518,6 @@ snprintf_func(int ch, void *arg) int kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap) { - __doprnt(fmt, ap, func, arg, radix); + __doprnt(fmt, ap, func, arg, radix, TRUE); return 0; } -