]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/subr_prf.c
xnu-4570.20.62.tar.gz
[apple/xnu.git] / bsd / kern / subr_prf.c
index 4a186049678699cee0eff374f3316c6b0fac338f..840fd1e7576f6fd2406e88abd06de162256021a3 100644 (file)
@@ -98,8 +98,8 @@
 #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);
@@ -116,10 +116,10 @@ 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 */
@@ -127,21 +127,17 @@ 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
@@ -165,22 +161,23 @@ uprintf(const char *fmt, ...)
        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
@@ -209,109 +206,102 @@ tprintf_close(tpr_t sessp)
 /*
  * 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
@@ -319,88 +309,33 @@ _printf(int flags, struct tty *ttyp, const char *format, ...)
 {
        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.
@@ -414,6 +349,9 @@ void tablefull(const char *tab)
  * 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
@@ -422,7 +360,7 @@ 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;
@@ -434,7 +372,7 @@ putchar(int c, void *arg)
        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) {
@@ -444,16 +382,18 @@ putchar(int c, void *arg)
 }
 
 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).
  *
@@ -469,12 +409,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_EMBEDDED */
 
 /*
  * Scaled down version of snprintf(3).
@@ -502,7 +443,7 @@ 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);
+       retval = __doprnt(format, ap, snprintf_func, &info, 10, FALSE);
        if (info.remain >= 1)
                *info.str++ = '\0';
        return retval;
@@ -522,7 +463,7 @@ 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;
 }