#include <sys/subr_prf.h>
#include <kern/cpu_number.h> /* for cpu_number() */
-#include <machine/spl.h>
#include <libkern/libkern.h>
+#include <os/log_private.h>
/* for vaddlog(): the following are implemented in osfmk/kern/printf.c */
extern void bsd_log_lock(void);
/*
* 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 struct tty cons; /* standard console tty */
extern struct tty *constty; /* pointer to console "window" tty */
extern int __doprnt(const char *fmt,
- va_list *argp,
+ va_list argp,
void (*)(int, void *),
void *arg,
- int radix);
+ int radix,
+ int is_log);
/*
* Record cpu that panic'd and lock around panic data
*/
-static void printn(u_long n, int b, int flags, struct tty *ttyp, int zf, int fld_size);
-#if NCPUS > 1
-boolean_t new_printf_cpu_number; /* do we need to output who we are */
-#endif
-
-extern void logwakeup(void);
+extern void logwakeup(struct msgbuf *);
extern void halt_cpu(void);
static void
struct proc *p = current_proc();
struct putchar_args pca;
va_list ap;
- struct session * sessp;
- boolean_t fstate;
+ struct session *sessp;
sessp = proc_session(p);
- fstate = thread_funnel_set(kernel_flock, TRUE);
- pca.flags = TOTTY;
- pca.tty = (struct tty *)sessp->s_ttyp;
-
- if (p->p_flag & P_CONTROLT && sessp->s_ttyvp) {
+ if (p->p_flag & P_CONTROLT && sessp != SESSION_NULL && sessp->s_ttyvp) {
+ pca.flags = TOTTY;
+ pca.tty = SESSION_TP(sessp);
+ 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);
}
- (void) thread_funnel_set(kernel_flock, fstate);
- session_rele(sessp);
+ if (sessp != SESSION_NULL)
+ session_rele(sessp);
}
tpr_t
/*
* tprintf prints on the controlling terminal associated
* with the given session.
+ *
+ * NOTE: No one else should call this function!!!
*/
void
tprintf(tpr_t tpr, const char *fmt, ...)
{
struct session *sess = (struct session *)tpr;
- struct tty *tp = NULL;
- int flags = TOLOG;
+ struct tty *tp;
va_list ap;
struct putchar_args pca;
- boolean_t fstate;
-
- logpri(LOG_INFO);
- /* to protect tty */
- fstate = thread_funnel_set(kernel_flock, TRUE);
- if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
- flags |= TOTTY;
- tp = sess->s_ttyp;
+ if (sess && (tp = SESSION_TP(sess)) != TTY_NULL) {
+ /* ttycheckoutq(), tputchar() require a locked tp */
+ tty_lock(tp);
+ if(ttycheckoutq(tp, 0)) {
+ pca.flags = TOTTY;
+ /* going to the tty; leave locked */
+ 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;
+
+ pca.flags = TOLOG;
+ pca.tty = TTY_NULL;
va_start(ap, fmt);
- __doprnt(fmt, &ap, putchar, &pca, 10);
+ __doprnt(fmt, ap, putchar, &pca, 10, TRUE);
va_end(ap);
- (void) thread_funnel_set(kernel_flock, fstate);
+ logwakeup(msgbufp);
- logwakeup();
+ va_start(ap, fmt);
+ os_log_with_args(OS_LOG_DEFAULT, OS_LOG_TYPE_DEFAULT, fmt, ap, __builtin_return_address(0));
+ va_end(ap);
}
/*
* Ttyprintf displays a message on a tty; it should be used only by
* the tty driver, or anything that knows the underlying tty will not
* be revoke(2)'d away. Other callers should use tprintf.
+ *
+ * Locks: It is assumed that the tty_lock() is held over the call
+ * to this function. Ensuring this is the responsibility
+ * of the caller.
*/
void
ttyprintf(struct tty *tp, const char *fmt, ...)
{
va_list ap;
- boolean_t fstate;
if (tp != NULL) {
- fstate = thread_funnel_set(kernel_flock, TRUE);
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);
- (void) thread_funnel_set(kernel_flock, fstate);
}
}
-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((u_long)level, 10, TOLOG, (struct tty *)0, 0, 0);
- putchar('>', &pca);
+ printf("Time %ld 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, 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;
- }
+ struct putchar_args pca = {
+ .flags = TOLOGLOCKED,
+ .tty = NULL,
+ };
bsd_log_lock();
- __doprnt(fmt, &ap, putchar, &pca, 10);
+ __doprnt(fmt, ap, putchar_asl, &pca, 10, TRUE);
bsd_log_unlock();
-
- logwakeup();
- return 0;
+ logwakeup(NULL);
+
+ return (0);
}
void
{
va_list ap;
struct putchar_args pca;
- boolean_t fstate;
-
- pca.flags = flags;
- pca.tty = ttyp;
- fstate = thread_funnel_set(kernel_flock, TRUE);
-
- va_start(ap, format);
- __doprnt(format, &ap, putchar, &pca, 10);
- va_end(ap);
- (void) thread_funnel_set(kernel_flock, fstate);
-}
-
-int prf(const char *fmt, va_list ap, int flags, struct tty *ttyp)
-{
- struct putchar_args pca;
pca.flags = flags;
pca.tty = ttyp;
-#if NCPUS > 1
- int cpun = cpu_number();
-
- if(ttyp == 0) {
- } else
- TTY_LOCK(ttyp);
-
- if (cpun != master_cpu)
- new_printf_cpu_number = TRUE;
+ if (ttyp != NULL) {
+ tty_lock(ttyp);
+
+ va_start(ap, format);
+ __doprnt(format, ap, putchar, &pca, 10, TRUE);
+ va_end(ap);
- if (new_printf_cpu_number) {
- putchar('{', flags, ttyp);
- printn((u_long)cpun, 10, flags, ttyp, 0, 0);
- putchar('}', flags, ttyp);
+ tty_unlock(ttyp);
}
-#endif /* NCPUS > 1 */
-
- __doprnt(fmt, &ap, putchar, &pca, 10);
-
-#if NCPUS > 1
- if(ttyp == 0) {
- } else
- TTY_UNLOCK(ttyp);
-#endif
-
- return 0;
}
-/*
- * Printn prints a number n in base b.
- * We don't use recursion to avoid deep kernel stacks.
- */
-static void printn(u_long n, int b, int flags, struct tty *ttyp, int zf, int fld_size)
+int
+prf(const char *fmt, va_list ap, int flags, struct tty *ttyp)
{
- 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);
-}
-
+ __doprnt(fmt, ap, putchar, &pca, 10, TRUE);
+ return 0;
+}
/*
* Warn that a system table is full.
* Print a character on console or users terminal.
* If destination is console then the last MSGBUFS characters
* are saved in msgbuf for inspection later.
+ *
+ * Locks: If TOTTY is set, we assume that the tty lock is held
+ * over the call to this function.
*/
/*ARGSUSED*/
void
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;
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);
+ log_putc_locked(msgbufp, c);
if ((pca->flags & TOCONS) && constty == 0 && c != '\0')
(*v_putc)(c);
if (pca->flags & TOSTR) {
}
int
-vprintf(const char *fmt, va_list ap)
+vprintf_log_locked(const char *fmt, va_list ap)
{
struct putchar_args pca;
- pca.flags = TOLOG | TOCONS;
+ pca.flags = TOLOGLOCKED;
pca.tty = NULL;
- __doprnt(fmt, &ap, putchar, &pca, 10);
+ __doprnt(fmt, ap, putchar, &pca, 10, TRUE);
return 0;
}
+#if !CONFIG_EMBEDDED
+
/*
* Scaled down version of vsprintf(3).
*
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_EMBEDDED */
/*
* Scaled down version of snprintf(3).
info.str = str;
info.remain = size;
- retval = __doprnt(format, &ap, snprintf_func, &info, 10);
+ retval = __doprnt(format, ap, snprintf_func, &info, 10, FALSE);
if (info.remain >= 1)
*info.str++ = '\0';
return retval;
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;
}