The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/bsd/kern/subr_prf.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
   26 /*-
   27  * Copyright (c) 1986, 1988, 1991, 1993
   28  *      The Regents of the University of California.  All rights reserved.
   29  * (c) UNIX System Laboratories, Inc.
   30  * All or some portions of this file are derived from material licensed
   31  * to the University of California by American Telephone and Telegraph
   32  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   33  * the permission of UNIX System Laboratories, Inc.
   34  *
   35  * Redistribution and use in source and binary forms, with or without
   36  * modification, are permitted provided that the following conditions
   37  * are met:
   38  * 1. Redistributions of source code must retain the above copyright
   39  *    notice, this list of conditions and the following disclaimer.
   40  * 2. Redistributions in binary form must reproduce the above copyright
   41  *    notice, this list of conditions and the following disclaimer in the
   42  *    documentation and/or other materials provided with the distribution.
   43  * 3. All advertising materials mentioning features or use of this software
   44  *    must display the following acknowledgement:
   45  *      This product includes software developed by the University of
   46  *      California, Berkeley and its contributors.
   47  * 4. Neither the name of the University nor the names of its contributors
   48  *    may be used to endorse or promote products derived from this software
   49  *    without specific prior written permission.
   50  *
   51  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   54  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   55  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   58  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   59  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   60  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   61  * SUCH DAMAGE.
   62  *
   63  *      @(#)subr_prf.c  8.4 (Berkeley) 5/4/95
   64  */
   65 /* HISTORY
   66  * 22-Sep-1997 Umesh Vaishampayan (umeshv@apple.com)
   67  *      Cleaned up m68k crud. Fixed vlog() to do logpri() for ppc, too.
   68  *
   69  * 17-July-97  Umesh Vaishampayan (umeshv@apple.com)
   70  *      Eliminated multiple definition of constty which is defined
   71  *      in bsd/dev/XXX/cons.c
   72  *
   73  * 26-MAR-1997 Umesh Vaishampayan (umeshv@NeXT.com
   74  *      Fixed tharshing format in many functions. Cleanup.
   75  * 
   76  * 17-Jun-1995 Mac Gillon (mgillon) at NeXT
   77  *      Purged old history
   78  *      New version based on 4.4 and NS3.3
   79  */
   80 
   81 #include <sys/param.h>
   82 #include <sys/systm.h>
   83 #include <sys/buf.h>
   84 #include <sys/conf.h>
   85 #include <sys/reboot.h>
   86 #include <sys/msgbuf.h>
   87 #include <sys/proc.h>
   88 #include <sys/ioctl.h>
   89 #include <sys/tty.h>
   90 #include <sys/file.h>
   91 #include <sys/tprintf.h>
   92 #include <sys/syslog.h>
   93 #include <stdarg.h>
   94 #include <sys/malloc.h>
   95 #include <sys/lock.h>
   96 #include <sys/subr_prf.h>
   97 
   98 #include <kern/cpu_number.h>    /* for cpu_number() */
   99 #include <machine/spl.h>
  100 #include <libkern/libkern.h>
  101 
  102 struct snprintf_arg {
  103         char *str;
  104         size_t remain;
  105 };
  106 
  107 
  108 /*
  109  * In case console is off,
  110  * panicstr contains argument to last
  111  * call to panic.
  112  */
  113 extern const char       *panicstr;
  114 
  115 extern  cnputc();                       /* standard console putc */
  116 int     (*v_putc)() = cnputc;           /* routine to putc on virtual console */
  117 
  118 extern  struct tty cons;                /* standard console tty */
  119 extern struct   tty *constty;           /* pointer to console "window" tty */
  120 extern int  __doprnt(const char *fmt,
  121                                          va_list    *argp,
  122                                          void       (*putc)(int, void *arg),
  123                                          void       *arg,
  124                                          int        radix);
  125 
  126 /*
  127  *      Record cpu that panic'd and lock around panic data
  128  */
  129 
  130 static void puts(const char *s, int flags, struct tty *ttyp);
  131 static void printn(u_long n, int b, int flags, struct tty *ttyp, int zf, int fld_size);
  132 
  133 /* MP printf stuff */
  134 decl_simple_lock_data(,printf_lock)
  135 #if     NCPUS > 1
  136 boolean_t new_printf_cpu_number;  /* do we need to output who we are */
  137 #endif
  138 
  139 extern  void logwakeup();
  140 extern  void halt_cpu();
  141 extern  boot();
  142 
  143 
  144 static void
  145 snprintf_func(int ch, void *arg);
  146 
  147 struct putchar_args {
  148         int flags;
  149         struct tty *tty;
  150 };
  151 static void putchar(int c, void *arg);
  152 
  153 
  154 /*
  155  * Uprintf prints to the controlling terminal for the current process.
  156  * It may block if the tty queue is overfull.  No message is printed if
  157  * the queue does not clear in a reasonable time.
  158  */
  159 void
  160 uprintf(const char *fmt, ...)
  161 {
  162         register struct proc *p = current_proc();
  163         struct putchar_args pca;
  164         va_list ap;
  165         
  166         pca.flags = TOTTY;
  167         pca.tty   = (struct tty *)p->p_session->s_ttyp;
  168 
  169         if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
  170                 va_start(ap, fmt);
  171                 __doprnt(fmt, &ap, putchar, &pca, 10);
  172                 va_end(ap);
  173         }
  174 }
  175 
  176 tpr_t
  177 tprintf_open(p)
  178         register struct proc *p;
  179 {
  180         if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
  181                 SESSHOLD(p->p_session);
  182                 return ((tpr_t) p->p_session);
  183         }
  184         return ((tpr_t) NULL);
  185 }
  186 
  187 void
  188 tprintf_close(sess)
  189         tpr_t sess;
  190 {
  191         if (sess)
  192                 SESSRELE((struct session *) sess);
  193 }
  194 
  195 /*
  196  * tprintf prints on the controlling terminal associated
  197  * with the given session.
  198  */
  199 void
  200 tprintf(tpr_t tpr, const char *fmt, ...)
  201 {
  202         register struct session *sess = (struct session *)tpr;
  203         struct tty *tp = NULL;
  204         int flags = TOLOG;
  205         va_list ap;
  206         struct putchar_args pca;
  207 
  208         logpri(LOG_INFO);
  209         if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
  210                 flags |= TOTTY;
  211                 tp = sess->s_ttyp;
  212         }
  213         
  214         pca.flags = flags;
  215         pca.tty   = tp;
  216         va_start(ap, fmt);
  217         __doprnt(fmt, &ap, putchar, &pca, 10);
  218         va_end(ap);
  219 
  220         logwakeup();
  221 }
  222 
  223 /*
  224  * Ttyprintf displays a message on a tty; it should be used only by
  225  * the tty driver, or anything that knows the underlying tty will not
  226  * be revoke(2)'d away.  Other callers should use tprintf.
  227  */
  228 void
  229 ttyprintf(struct tty *tp, const char *fmt, ...)
  230 {
  231         va_list ap;
  232 
  233         if (tp != NULL) {
  234                 struct putchar_args pca;
  235                 pca.flags = TOTTY;
  236                 pca.tty   = tp;
  237                 
  238                 va_start(ap, fmt);
  239                 __doprnt(fmt, &ap, putchar, &pca, 10);
  240                 va_end(ap);
  241         }
  242 }
  243 
  244 extern  int log_open;
  245 
  246 
  247 void
  248 logpri(level)
  249         int level;
  250 {
  251         struct putchar_args pca;
  252         pca.flags = TOLOG;
  253         pca.tty   = NULL;
  254         
  255         putchar('<', &pca);
  256         printn((u_long)level, 10, TOLOG, (struct tty *)0, 0, 0);
  257         putchar('>', &pca);
  258 }
  259 
  260 void
  261 addlog(const char *fmt, ...)
  262 {
  263         register s = splhigh();
  264         va_list ap;
  265         struct putchar_args pca;
  266 
  267         pca.flags = TOLOG;
  268         pca.tty   = NULL;
  269 
  270         va_start(ap, fmt);
  271         __doprnt(fmt, &ap, putchar, &pca, 10);
  272         
  273         splx(s);
  274         if (!log_open) {
  275                 pca.flags = TOCONS;
  276                 __doprnt(fmt, &ap, putchar, &pca, 10);
  277         }
  278         va_end(ap);
  279         logwakeup();
  280 }
  281 void _printf(int flags, struct tty *ttyp, const char *format, ...)
  282 {
  283         va_list ap;
  284         struct putchar_args pca;
  285 
  286         pca.flags = flags;
  287         pca.tty   = ttyp;
  288         
  289         va_start(ap, format);
  290         __doprnt(format, &ap, putchar, &pca, 10);
  291         va_end(ap);
  292 }
  293 
  294 int prf(const char *fmt, va_list ap, int flags, struct tty *ttyp)
  295 {
  296         struct putchar_args pca;
  297 
  298         pca.flags = flags;
  299         pca.tty   = ttyp;
  300 
  301 #if    NCPUS > 1
  302     int cpun = cpu_number();
  303 
  304     if(ttyp == 0) {
  305             simple_lock(&printf_lock);
  306         } else
  307                 TTY_LOCK(ttyp);
  308 
  309         if (cpun != master_cpu)
  310             new_printf_cpu_number = TRUE;
  311 
  312         if (new_printf_cpu_number) {
  313                 putchar('{', flags, ttyp);
  314                 printn((u_long)cpun, 10, flags, ttyp, 0, 0);
  315                 putchar('}', flags, ttyp);
  316         }
  317 #endif /* NCPUS > 1 */
  318           
  319         __doprnt(fmt, &ap, putchar, &pca, 10);
  320 
  321 #if    NCPUS > 1
  322         if(ttyp == 0) {
  323                 simple_unlock(&printf_lock);
  324         } else
  325                 TTY_UNLOCK(ttyp);
  326 #endif
  327  
  328         return 0;
  329 }
  330 
  331 static void puts(const char *s, int flags, struct tty *ttyp)
  332 {
  333         register char c;
  334         struct putchar_args pca;
  335 
  336         pca.flags = flags;
  337         pca.tty   = ttyp;
  338 
  339         while ((c = *s++))
  340                 putchar(c, &pca);
  341 }
  342 
  343 /*
  344  * Printn prints a number n in base b.
  345  * We don't use recursion to avoid deep kernel stacks.
  346  */
  347 static void printn(u_long n, int b, int flags, struct tty *ttyp, int zf, int fld_size)
  348 {
  349         char prbuf[11];
  350         register char *cp;
  351         struct putchar_args pca;
  352 
  353         pca.flags = flags;
  354         pca.tty   = ttyp;
  355 
  356         if (b == 10 && (int)n < 0) {
  357                 putchar('-', &pca);
  358                 n = (unsigned)(-(int)n);
  359         }
  360         cp = prbuf;
  361         do {
  362                 *cp++ = "0123456789abcdef"[n%b];
  363                 n /= b;
  364         } while (n);
  365         if (fld_size) {
  366                 for (fld_size -= cp - prbuf; fld_size > 0; fld_size--)
  367                         if (zf)
  368                                 putchar('', &pca);
  369                         else
  370                                 putchar(' ', &pca);
  371         }
  372         do
  373                 putchar(*--cp, &pca);
  374         while (cp > prbuf);
  375 }
  376 
  377 
  378 
  379 /*
  380  * Warn that a system table is full.
  381  */
  382 void tablefull(const char *tab)
  383 {
  384         log(LOG_ERR, "%s: table is full\n", tab);
  385 }
  386 
  387 /*
  388  * Print a character on console or users terminal.
  389  * If destination is console then the last MSGBUFS characters
  390  * are saved in msgbuf for inspection later.
  391  */
  392 /*ARGSUSED*/
  393 void
  394 putchar(int c, void *arg)
  395 {
  396         struct putchar_args *pca = arg;
  397         register struct msgbuf *mbp;
  398         char **sp = (char**) pca->tty;
  399 
  400         if (panicstr)
  401                 constty = 0;
  402         if ((pca->flags & TOCONS) && pca->tty == NULL && constty) {
  403                 pca->tty = constty;
  404                 pca->flags |= TOTTY;
  405         }
  406         if ((pca->flags & TOTTY) && pca->tty && tputchar(c, pca->tty) < 0 &&
  407             (pca->flags & TOCONS) && pca->tty == constty)
  408                 constty = 0;
  409         if ((pca->flags & TOLOG) && c != '\0' && c != '\r' && c != 0177)
  410                 log_putc(c);
  411         if ((pca->flags & TOCONS) && constty == 0 && c != '\0')
  412                 (*v_putc)(c);
  413         if (pca->flags & TOSTR) {
  414                 **sp = c;
  415                 (*sp)++;
  416         }
  417 }
  418 
  419 
  420 
  421 /*
  422  * Scaled down version of vsprintf(3).
  423  */
  424 int
  425 vsprintf(char *buf, const char *cfmt, va_list ap)
  426 {
  427         int retval;
  428         struct snprintf_arg info;
  429 
  430         info.str = buf;
  431         info.remain = 999999;
  432 
  433         retval = __doprnt(cfmt, &ap, snprintf_func, &info, 10);
  434         if (info.remain >= 1) {
  435                 *info.str++ = '\0';
  436         }
  437         return 0;
  438 }
  439 
  440 /*
  441  * Scaled down version of snprintf(3).
  442  */
  443 int
  444 snprintf(char *str, size_t size, const char *format, ...)
  445 {
  446         int retval;
  447         va_list ap;
  448 
  449         va_start(ap, format);
  450         retval = vsnprintf(str, size, format, ap);
  451         va_end(ap);
  452         return(retval);
  453 }
  454 
  455 /*
  456  * Scaled down version of vsnprintf(3).
  457  */
  458 int
  459 vsnprintf(char *str, size_t size, const char *format, va_list ap)
  460 {
  461         struct snprintf_arg info;
  462         int retval;
  463 
  464         info.str = str;
  465         info.remain = size;
  466         retval = __doprnt(format, &ap, snprintf_func, &info, 10);
  467         if (info.remain >= 1)
  468                 *info.str++ = '\0';
  469         return retval;
  470 }
  471 
  472 static void
  473 snprintf_func(int ch, void *arg)
  474 {
  475         struct snprintf_arg *const info = arg;
  476 
  477         if (info->remain >= 2) {
  478                 *info->str++ = ch;
  479                 info->remain--;
  480         }
  481 }
  482 
  483 int
  484 kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
  485 {
  486         __doprnt(fmt, &ap, func, arg, radix);
  487         return 0;
  488 }
  489 

Cache object: 25261946fc1c02897d08ca598c207539


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.