Annotation of kernel/bsd/kern/subr_prf.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     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 ([email protected])
                     67:  *     Cleaned up m68k crud. Fixed vlog() to do logpri() for ppc, too.
                     68:  *
                     69:  * 17-July-97  Umesh Vaishampayan ([email protected])
                     70:  *     Eliminated multiple definition of constty which is defined
                     71:  *     in bsd/dev/XXX/cons.c
                     72:  *
                     73:  * 26-MAR-1997 Umesh Vaishampayan ([email protected]
                     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 <cpus.h>
                     82: #include <cputypes.h>
                     83: 
                     84: #include <sys/param.h>
                     85: #include <sys/systm.h>
                     86: #include <sys/buf.h>
                     87: #include <sys/conf.h>
                     88: #include <sys/reboot.h>
                     89: #include <sys/msgbuf.h>
                     90: #include <sys/proc.h>
                     91: #include <sys/ioctl.h>
                     92: #include <sys/tty.h>
                     93: #include <sys/file.h>
                     94: #include <sys/tprintf.h>
                     95: #include <sys/syslog.h>
                     96: #include <stdarg.h>
                     97: #include <sys/malloc.h>
                     98: #include <kern/lock.h>
                     99: #include <kern/parallel.h>
                    100: #import <sys/subr_prf.h>
                    101: 
                    102: #include <machine/cpu.h>       /* for cpu_number() */
                    103: #include <machine/spl.h>
                    104: 
                    105: /*
                    106:  * In case console is off,
                    107:  * panicstr contains argument to last
                    108:  * call to panic.
                    109:  */
                    110: const char     *panicstr;
                    111: 
                    112: extern cnputc();                       /* standard console putc */
                    113: int    (*v_putc)() = cnputc;           /* routine to putc on virtual console */
                    114: 
                    115: extern struct tty cons;                /* standard console tty */
                    116: extern struct  tty *constty;           /* pointer to console "window" tty */
                    117: 
                    118: /*
                    119:  *     Record cpu that panic'd and lock around panic data
                    120:  */
                    121: decl_simple_lock_data(,panic_lock)
                    122: int paniccpu;
                    123: 
                    124: static void puts(const char *s, int flags, struct tty *ttyp);
                    125: static void printn(u_long n, int b, int flags, struct tty *ttyp, int zf, int fld_size);
                    126: 
                    127: /* MP printf stuff */
                    128: decl_simple_lock_data(,printf_lock)
                    129: #if    NCPUS > 1
                    130: boolean_t new_printf_cpu_number;  /* do we need to output who we are */
                    131: #endif
                    132: 
                    133: extern void logwakeup();
                    134: extern void halt_cpu();
                    135: #if    NeXT
                    136: extern void mini_mon();
                    137: #endif /* NeXT */
                    138: extern boot();
                    139: int    putchar();
                    140: 
                    141: 
                    142: /*
                    143:  * Scaled down version of C Library printf.
                    144:  * Used to print diagnostic information directly on console tty.
                    145:  * Since it is not interrupt driven, all system activities are
                    146:  * suspended.  Printf should not be used for chit-chat.
                    147:  *
                    148:  * One additional format: %b is supported to decode error registers.
                    149:  * Usage is:
                    150:  *     printf("reg=%b\n", regval, "<base><arg>*");
                    151:  * Where <base> is the output base expressed as a control character,
                    152:  * e.g. \10 gives octal; \20 gives hex.  Each arg is a sequence of
                    153:  * characters, the first of which gives the bit number to be inspected
                    154:  * (origin 1), and the next characters (up to a control character, i.e.
                    155:  * a character <= 32), give the name of the register.  Thus
                    156:  *     printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
                    157:  * would produce output:
                    158:  *     reg=3<BITTWO,BITONE>
                    159:  *
                    160:  */
                    161: 
                    162: void printf(const char *format, ...)
                    163: {
                    164:        va_list         ap;
                    165:        
                    166:        va_start(ap, format);
                    167:        prf(format, ap, TOCONS | TOLOG, (struct tty *)0);
                    168:        va_end(ap);
                    169:        
                    170:        if (!panicstr)
                    171:                logwakeup();
                    172: }
                    173: 
                    174: int sprintf(char *s, const char *format, ...)
                    175: {
                    176:        char *sptr = s;
                    177:        char *s0 = s;
                    178:        va_list ap;
                    179:        
                    180:        va_start(ap, format);
                    181:        prf(format, ap, TOSTR, (struct tty *)&sptr);
                    182:        va_end(ap);
                    183:        *sptr = 0;
                    184:        return sptr - s0;
                    185: }
                    186: 
                    187: /*
                    188:  * Uprintf prints to the controlling terminal for the current process.
                    189:  * It may block if the tty queue is overfull.  No message is printed if
                    190:  * the queue does not clear in a reasonable time.
                    191:  */
                    192: void
                    193: uprintf(const char *fmt, ...)
                    194: {
                    195:        register struct proc *p = current_proc();
                    196:        va_list ap;
                    197: 
                    198:        unix_master();          /* sessions, sigh */
                    199:        if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
                    200:                va_start(ap, fmt);
                    201:                prf(fmt, ap, TOTTY, (struct tty *)p->p_session->s_ttyvp);
                    202:                va_end(ap);
                    203:        }
                    204:        unix_release();
                    205: }
                    206: 
                    207: tpr_t
                    208: tprintf_open(p)
                    209:        register struct proc *p;
                    210: {
                    211:        unix_master();          /* sessions, sigh */
                    212:        if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
                    213:                SESSHOLD(p->p_session);
                    214:                unix_release();
                    215:                return ((tpr_t) p->p_session);
                    216:        }
                    217:        unix_release();
                    218:        return ((tpr_t) NULL);
                    219: }
                    220: 
                    221: void
                    222: tprintf_close(sess)
                    223:        tpr_t sess;
                    224: {
                    225:        unix_master();          /* sessions, sigh */
                    226:        if (sess)
                    227:                SESSRELE((struct session *) sess);
                    228:        unix_release();
                    229: }
                    230: 
                    231: /*
                    232:  * tprintf prints on the controlling terminal associated
                    233:  * with the given session.
                    234:  */
                    235: void
                    236: tprintf(tpr_t tpr, const char *fmt, ...)
                    237: {
                    238:        register struct session *sess = (struct session *)tpr;
                    239:        struct tty *tp = NULL;
                    240:        int flags = TOLOG;
                    241:        va_list ap;
                    242: 
                    243:        logpri(LOG_INFO);
                    244:        unix_master();          /* sessions, sigh */
                    245:        if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
                    246:                flags |= TOTTY;
                    247:                tp = sess->s_ttyp;
                    248:        }
                    249:        if (tp != NULL) {
                    250:                va_start(ap, fmt);
                    251:                prf(fmt, ap, TOTTY, tp);
                    252:                va_end(ap);
                    253:        }
                    254:        unix_release();
                    255:        logwakeup();
                    256: }
                    257: 
                    258: /*
                    259:  * Ttyprintf displays a message on a tty; it should be used only by
                    260:  * the tty driver, or anything that knows the underlying tty will not
                    261:  * be revoke(2)'d away.  Other callers should use tprintf.
                    262:  */
                    263: void
                    264: ttyprintf(struct tty *tp, const char *fmt, ...)
                    265: {
                    266:        va_list ap;
                    267: 
                    268:        if (tp != NULL) {
                    269:                va_start(ap, fmt);
                    270:                prf(fmt, ap, TOTTY, tp);
                    271:                va_end(ap);
                    272:        }
                    273: }
                    274: 
                    275: extern int log_open;
                    276: 
                    277: /*
                    278:  * Log writes to the log buffer,
                    279:  * and guarantees not to sleep (so can be called by interrupt routines).
                    280:  * If there is no process reading the log yet, it writes to the console also.
                    281:  */
                    282: void
                    283: log(int level, const char *fmt, ...)
                    284: {
                    285:        extern void vlog();
                    286:        va_list ap;
                    287: 
                    288:        va_start(ap, fmt);
                    289:        vlog(level, fmt, ap);
                    290:        va_end(ap);
                    291: }
                    292: 
                    293: /*
                    294:  * driverkit needs vlog to be called from IOLog
                    295:  */
                    296: void
                    297: vlog(int level, const char *fmt, va_list ap)
                    298: {
                    299:        register s = splhigh();
                    300: 
                    301: #if !NeXT
                    302:        logpri(level);
                    303: #endif
                    304:        prf(fmt, ap, TOLOG, (struct tty *)0);
                    305:        splx(s);
                    306:        if (!log_open)
                    307:                prf(fmt, ap, TOCONS, (struct tty *)0);
                    308:        logwakeup();
                    309: }
                    310: 
                    311: void
                    312: logpri(level)
                    313:        int level;
                    314: {
                    315: 
                    316:        putchar('<', TOLOG, (struct tty *)0);
                    317:        printn((u_long)level, 10, TOLOG, (struct tty *)0, 0, 0);
                    318:        putchar('>', TOLOG, (struct tty *)0);
                    319: }
                    320: 
                    321: void
                    322: addlog(const char *fmt, ...)
                    323: {
                    324:        register s = splhigh();
                    325:        va_list ap;
                    326: 
                    327:        va_start(ap, fmt);
                    328:        prf(fmt, ap, TOLOG, (struct tty *)0);
                    329:        splx(s);
                    330:        if (!log_open)
                    331:                prf(fmt, ap, TOCONS, (struct tty *)0);
                    332:        va_end(ap);
                    333:        logwakeup();
                    334: }
                    335: #warning pulled in from mksparc check encumbered or not
                    336: void _printf(int flags, struct tty *ttyp, const char *format, ...)
                    337: {
                    338:        va_list ap;
                    339:        
                    340:        va_start(ap, format);
                    341:        prf(format, ap, flags, ttyp);
                    342:        va_end(ap);
                    343: }
                    344: 
                    345: int prf(const char *fmt, va_list ap, int flags, struct tty *ttyp)
                    346: {
                    347:        register int b, c, i;
                    348:        char *s;
                    349:        int any;
                    350:        int zf = 0, fld_size;
                    351:        
                    352: #if    NCPUS > 1
                    353:        int cpun = cpu_number();
                    354: 
                    355:        if(ttyp == 0) {
                    356:                simple_lock(&printf_lock);
                    357:        } else
                    358:                TTY_LOCK(ttyp);
                    359:                
                    360:        if (cpun != master_cpu)
                    361:                new_printf_cpu_number = TRUE;
                    362: 
                    363:        if (new_printf_cpu_number) {
                    364:                putchar('{', flags, ttyp);
                    365:                printn((u_long)cpun, 10, flags, ttyp, 0, 0);
                    366:                putchar('}', flags, ttyp);
                    367:        }
                    368: #endif /* NCPUS > 1 */ 
                    369: loop:
                    370:        while ((c = *fmt++) != '%') {
                    371:                if (c == '\0') {
                    372: #if    NCPUS > 1
                    373:                        if(ttyp == 0) {
                    374:                                simple_unlock(&printf_lock);
                    375:                        } else
                    376:                                TTY_UNLOCK(ttyp);
                    377: #endif
                    378:                        return 0;
                    379:                }
                    380:                putchar(c, flags, ttyp);
                    381:        }
                    382: again:
                    383:        zf = 0;
                    384:        fld_size = 0;
                    385:        c = *fmt++;
                    386:        if (c == '0')
                    387:                zf = '0';
                    388:        fld_size = 0;
                    389:        for (;c <= '9' && c >= '0'; c = *fmt++)
                    390:                fld_size = fld_size * 10 + c - '0';
                    391:        
                    392:        /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
                    393:        switch (c) {
                    394: 
                    395:        case 'l':
                    396:                goto again;
                    397:        case 'x': case 'X':
                    398:                b = 16;
                    399:                goto number;
                    400:        case 'd': case 'D':
                    401:        case 'u':               /* what a joke */
                    402:                b = 10;
                    403:                goto number;
                    404:        case 'o': case 'O':
                    405:                b = 8;
                    406: number:
                    407:                printn(va_arg(ap, unsigned), b, flags, ttyp, zf, fld_size);
                    408:                break;
                    409:        case 'c':
                    410:                b = va_arg(ap, unsigned);
                    411: #if BYTE_ORDER == LITTLE_ENDIAN
                    412:                for (i = 24; i >= 0; i -= 8)
                    413:                        if (c = (b >> i) & 0x7f)
                    414:                                putchar(c, flags, ttyp);
                    415: #endif
                    416: #if BYTE_ORDER == BIG_ENDIAN
                    417:                if ((c = (b & 0x7f)))
                    418:                        putchar(c, flags, ttyp);
                    419: #endif
                    420:                break;
                    421:        case 'b':
                    422:                b = va_arg(ap, unsigned);
                    423:                s = va_arg(ap, char *);
                    424:                printn((u_long)b, *s++, flags, ttyp, 0, 0);
                    425:                any = 0;
                    426:                if (b) {
                    427:                        while ((i = *s++)) {
                    428:                                if (*s <= 32) {
                    429:                                        register int j;
                    430: 
                    431:                                        if (any++)
                    432:                                                putchar(',', flags, ttyp);
                    433:                                        j = *s++ ;
                    434:                                        for (; (c = *s) > 32 ; s++)
                    435:                                                putchar(c, flags, ttyp);
                    436:                                        printn( (u_long)( (b >> (j-1)) &
                    437:                                                         ( (2 << (i-j)) -1)),
                    438:                                                 8, flags, ttyp, 0, 0);
                    439:                                } else if (b & (1 << (i-1))) {
                    440:                                        putchar(any? ',' : '<', flags, ttyp);
                    441:                                        any = 1;
                    442:                                        for (; (c = *s) > 32; s++)
                    443:                                                putchar(c, flags, ttyp);
                    444:                                } else
                    445:                                        for (; *s > 32; s++)
                    446:                                                ;
                    447:                        }
                    448:                        putchar('>', flags, ttyp);
                    449:                }
                    450:                break;
                    451: 
                    452:        case 's':
                    453:                s = va_arg(ap, char *);
                    454: #ifdef DEBUG
                    455:                if (fld_size) {
                    456:                        while (fld_size-- > 0)
                    457:                                putchar((c = *s++)? c : '_', flags, ttyp);
                    458:                } else {
                    459:                        while ((c = *s++))
                    460:                                putchar(c, flags, ttyp);
                    461:                }
                    462: #else  
                    463:                while (c = *s++)
                    464:                        putchar(c, flags, ttyp);
                    465: #endif
                    466:                break;
                    467: 
                    468:        case '%':
                    469:                putchar('%', flags, ttyp);
                    470:                goto loop;
                    471:        case 'C':
                    472:                b = va_arg(ap, unsigned);
                    473: #if BYTE_ORDER == LITTLE_ENDIAN
                    474:                for (i = 24; i >= 0; i -= 8)
                    475:                        if (c = (b >> i) & 0x7f)
                    476:                                putchar(c, flags, ttyp);
                    477: #endif
                    478: #if BYTE_ORDER == BIG_ENDIAN
                    479:                if ((c = (b & 0x7f)))
                    480:                        putchar(c, flags, ttyp);
                    481: #endif
                    482: 
                    483:        case 'r':
                    484:        case 'R':
                    485:                b = va_arg(ap, unsigned);
                    486:                s = va_arg(ap, char *);
                    487:                if (c == 'R') {
                    488:                        puts("0x", flags, ttyp);
                    489:                        printn((u_long)b, 16, flags, ttyp, 0, 0);
                    490:                }
                    491:                any = 0;
                    492:                if (c == 'r' || b) {
                    493:                        register struct reg_desc *rd;
                    494:                        register struct reg_values *rv;
                    495:                        unsigned field;
                    496: 
                    497:                        putchar('<', flags, ttyp);
                    498:                        for (rd = (struct reg_desc *)s; rd->rd_mask; rd++) {
                    499:                                field = b & rd->rd_mask;
                    500:                                field = (rd->rd_shift > 0)
                    501:                                    ? field << rd->rd_shift
                    502:                                    : field >> -rd->rd_shift;
                    503:                                if (any &&
                    504:                                      (rd->rd_format || rd->rd_values
                    505:                                         || (rd->rd_name && field)
                    506:                                      )
                    507:                                )
                    508:                                        putchar(',', flags, ttyp);
                    509:                                if (rd->rd_name) {
                    510:                                        if (rd->rd_format || rd->rd_values
                    511:                                            || field) {
                    512:                                                puts(rd->rd_name, flags, ttyp);
                    513:                                                any = 1;
                    514:                                        }
                    515:                                        if (rd->rd_format || rd->rd_values) {
                    516:                                                putchar('=', flags, ttyp);
                    517:                                                any = 1;
                    518:                                        }
                    519:                                }
                    520:                                if (rd->rd_format) {
                    521:                                        _printf(flags, ttyp, rd->rd_format,
                    522:                                          field);
                    523:                                        any = 1;
                    524:                                        if (rd->rd_values)
                    525:                                                putchar(':', flags, ttyp);
                    526:                                }
                    527:                                if (rd->rd_values) {
                    528:                                        any = 1;
                    529:                                        for (rv = rd->rd_values;
                    530:                                            rv->rv_name;
                    531:                                            rv++) {
                    532:                                                if (field == rv->rv_value) {
                    533:                                                        puts(rv->rv_name, flags,
                    534:                                                            ttyp);
                    535:                                                        break;
                    536:                                                }
                    537:                                        }
                    538:                                        if (rv->rv_name == NULL)
                    539:                                                puts("???", flags, ttyp);
                    540:                                }
                    541:                        }
                    542:                        putchar('>', flags, ttyp);
                    543:                }
                    544:                break;
                    545: 
                    546:        case 'n':
                    547:        case 'N':
                    548:                {
                    549:                        register struct reg_values *rv;
                    550: 
                    551:                        b = va_arg(ap, unsigned);
                    552:                        s = va_arg(ap,char *);
                    553:                        for (rv = (struct reg_values *)s; rv->rv_name; rv++) {
                    554:                                if (b == rv->rv_value) {
                    555:                                        puts(rv->rv_name, flags, ttyp);
                    556:                                        break;
                    557:                                }
                    558:                        }
                    559:                        if (rv->rv_name == NULL)
                    560:                                puts("???", flags, ttyp);
                    561:                        if (c == 'N' || rv->rv_name == NULL) {
                    562:                                putchar(':', flags, ttyp);
                    563:                                printn((u_long)b, 10, flags, ttyp, 0, 0);
                    564:                        }
                    565:                }
                    566:                break;
                    567:        }
                    568:        goto loop;
                    569: }
                    570: 
                    571: static void puts(const char *s, int flags, struct tty *ttyp)
                    572: {
                    573:        register char c;
                    574: 
                    575:        while ((c = *s++))
                    576:                putchar(c, flags, ttyp);
                    577: }
                    578: 
                    579: /*
                    580:  * Printn prints a number n in base b.
                    581:  * We don't use recursion to avoid deep kernel stacks.
                    582:  */
                    583: static void printn(u_long n, int b, int flags, struct tty *ttyp, int zf, int fld_size)
                    584: {
                    585:        char prbuf[11];
                    586:        register char *cp;
                    587: 
                    588:        if (b == 10 && (int)n < 0) {
                    589:                putchar('-', flags, ttyp);
                    590:                n = (unsigned)(-(int)n);
                    591:        }
                    592:        cp = prbuf;
                    593:        do {
                    594:                *cp++ = "0123456789abcdef"[n%b];
                    595:                n /= b;
                    596:        } while (n);
                    597:        if (fld_size) {
                    598:                for (fld_size -= cp - prbuf; fld_size > 0; fld_size--)
                    599:                        if (zf)
                    600:                                putchar('0', flags, ttyp);
                    601:                        else
                    602:                                putchar(' ', flags, ttyp);
                    603:        }
                    604:        do
                    605:                putchar(*--cp, flags, ttyp);
                    606:        while (cp > prbuf);
                    607: }
                    608: 
                    609: void panic_init()
                    610: {
                    611:        simple_lock_init(&panic_lock);
                    612: }
                    613: 
                    614: /*
                    615:  * Panic is called on unresolvable fatal errors.  It prints "panic: mesg",
                    616:  * and then reboots.  If we are called twice, then we avoid trying to sync
                    617:  * the disks as this often leads to recursive panics.
                    618:  */
                    619: #ifdef __GNUC__
                    620: volatile
                    621: #endif
                    622: void
                    623: panic(const char *fmt, ...)
                    624: {
                    625: #if    MACH_LDEBUG
                    626:        extern int mach_ldebug;
                    627: #endif /* MACH_LDEBUG */
                    628:        int bootopt;
                    629:        va_list ap;
                    630:        char buffer[256];
                    631: 
                    632:        simple_lock(&panic_lock);
                    633:        bootopt = RB_AUTOBOOT;
                    634:        if (panicstr) {
                    635:                if (cpu_number() == paniccpu) {
                    636:                        bootopt |= RB_NOSYNC;
                    637:                } else {
                    638:                        simple_unlock(&panic_lock);
                    639:                halt_cpu();
                    640:                /* NOTREACHED */
                    641:            }
                    642:        } else {
                    643:                panicstr = fmt;
                    644:            paniccpu = cpu_number();
                    645:        }
                    646:        
                    647:        simple_unlock(&panic_lock);
                    648: 
                    649: #if    MACH_LDEBUG
                    650:        mach_ldebug = 0;                // turn off simple lock debugging.
                    651: #endif /* MACH_LDEBUG */
                    652: 
                    653:        va_start(ap, fmt);
                    654:        sprintf(buffer, "panic: %s", fmt);
                    655:        prf(buffer, ap, TOCONS, (struct tty *)0);
                    656:        va_end(ap);
                    657: 
                    658: #if    NeXT
                    659:        if( panicstr == fmt) {
                    660:            // make panicstr for minimon
                    661:            char * strOut = buffer;
                    662:            va_start(ap, fmt);
                    663:            prf(fmt, ap, TOSTR, (struct tty *)&strOut );
                    664:            va_end(ap);
                    665:            *strOut = 0;
                    666:            panicstr = buffer;
                    667:        }
                    668:        mini_mon ("panic", "System Panic", current_thread()->pcb);
                    669: #endif /* NeXT */
                    670:        boot(RB_PANIC, bootopt, "");
                    671: }
                    672: 
                    673: /*
                    674:  * Warn that a system table is full.
                    675:  */
                    676: void tablefull(const char *tab)
                    677: {
                    678:        log(LOG_ERR, "%s: table is full\n", tab);
                    679: }
                    680: 
                    681: /*
                    682:  * Hard error is the preface to plaintive error messages
                    683:  * about failing disk transfers.
                    684:  */
                    685: void harderr(struct buf *bp, const char *cp)
                    686: {
                    687: 
                    688:        printf("%s%d%c: hard error sn%d ", cp,
                    689:            minor(bp->b_dev) >> 3, 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
                    690: }
                    691: 
                    692: /*
                    693:  * Print a character on console or users terminal.
                    694:  * If destination is console then the last MSGBUFS characters
                    695:  * are saved in msgbuf for inspection later.
                    696:  */
                    697: /*ARGSUSED*/
                    698: int
                    699: putchar(c, flags, tp)
                    700:        register int c;
                    701:        struct tty *tp;
                    702: {
                    703:        register struct msgbuf *mbp;
                    704:        char **sp = (char**) tp;
                    705: 
                    706:        if (panicstr)
                    707:                constty = 0;
                    708:        if ((flags & TOCONS) && tp == NULL && constty) {
                    709:                tp = constty;
                    710:                flags |= TOTTY;
                    711:        }
                    712:        if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 &&
                    713:            (flags & TOCONS) && tp == constty)
                    714:                constty = 0;
                    715:        if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177) {
                    716:                mbp = msgbufp;
                    717:                if (mbp-> msg_magic != MSG_MAGIC) {
                    718:                        register int i;
                    719: 
                    720:                        mbp->msg_magic = MSG_MAGIC;
                    721:                        mbp->msg_bufx = mbp->msg_bufr = 0;
                    722:                        for (i=0; i < MSG_BSIZE; i++)
                    723:                                mbp->msg_bufc[i] = 0;
                    724:                }
                    725:                mbp->msg_bufc[mbp->msg_bufx++] = c;
                    726:                if (mbp->msg_bufx < 0 || mbp->msg_bufx >= MSG_BSIZE)
                    727:                        mbp->msg_bufx = 0;
                    728:        }
                    729:        if ((flags & TOCONS) && constty == 0 && c != '\0')
                    730:                (*v_putc)(c);
                    731:        if (flags & TOSTR) {
                    732:                **sp = c;
                    733:                (*sp)++;
                    734:        }
                    735:        return 0;
                    736: }
                    737: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.