1 1.203 andvar /* $NetBSD: subr_prf.c,v 1.203 2023/08/29 21:23:14 andvar Exp $ */ 2 1.15 cgd 3 1.12 cgd /*- 4 1.12 cgd * Copyright (c) 1986, 1988, 1991, 1993 5 1.12 cgd * The Regents of the University of California. All rights reserved. 6 1.12 cgd * (c) UNIX System Laboratories, Inc. 7 1.12 cgd * All or some portions of this file are derived from material licensed 8 1.12 cgd * to the University of California by American Telephone and Telegraph 9 1.12 cgd * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 1.12 cgd * the permission of UNIX System Laboratories, Inc. 11 1.12 cgd * 12 1.12 cgd * Redistribution and use in source and binary forms, with or without 13 1.12 cgd * modification, are permitted provided that the following conditions 14 1.12 cgd * are met: 15 1.12 cgd * 1. Redistributions of source code must retain the above copyright 16 1.12 cgd * notice, this list of conditions and the following disclaimer. 17 1.12 cgd * 2. Redistributions in binary form must reproduce the above copyright 18 1.12 cgd * notice, this list of conditions and the following disclaimer in the 19 1.12 cgd * documentation and/or other materials provided with the distribution. 20 1.93 agc * 3. Neither the name of the University nor the names of its contributors 21 1.12 cgd * may be used to endorse or promote products derived from this software 22 1.12 cgd * without specific prior written permission. 23 1.12 cgd * 24 1.12 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 1.12 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 1.12 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 1.12 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 1.12 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 1.12 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 1.12 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 1.12 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 1.12 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 1.12 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 1.12 cgd * SUCH DAMAGE. 35 1.12 cgd * 36 1.48 fvdl * @(#)subr_prf.c 8.4 (Berkeley) 5/4/95 37 1.12 cgd */ 38 1.82 lukem 39 1.82 lukem #include <sys/cdefs.h> 40 1.203 andvar __KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v 1.203 2023/08/29 21:23:14 andvar Exp $"); 41 1.54 thorpej 42 1.159 pooka #ifdef _KERNEL_OPT 43 1.49 jonathan #include "opt_ddb.h" 44 1.80 lukem #include "opt_kgdb.h" 45 1.90 atatat #include "opt_dump.h" 46 1.154 tls #include "opt_rnd_printf.h" 47 1.159 pooka #endif 48 1.12 cgd 49 1.12 cgd #include <sys/param.h> 50 1.78 kleink #include <sys/stdint.h> 51 1.12 cgd #include <sys/systm.h> 52 1.12 cgd #include <sys/buf.h> 53 1.109 he #include <sys/device.h> 54 1.12 cgd #include <sys/reboot.h> 55 1.12 cgd #include <sys/msgbuf.h> 56 1.12 cgd #include <sys/proc.h> 57 1.12 cgd #include <sys/ioctl.h> 58 1.12 cgd #include <sys/vnode.h> 59 1.12 cgd #include <sys/file.h> 60 1.12 cgd #include <sys/tty.h> 61 1.12 cgd #include <sys/tprintf.h> 62 1.137 dyoung #include <sys/spldebug.h> 63 1.12 cgd #include <sys/syslog.h> 64 1.87 thorpej #include <sys/kprintf.h> 65 1.115 ad #include <sys/atomic.h> 66 1.126 pooka #include <sys/kernel.h> 67 1.128 pooka #include <sys/cpu.h> 68 1.158 riastrad #include <sys/rndsource.h> 69 1.178 kre #include <sys/kmem.h> 70 1.12 cgd 71 1.20 christos #include <dev/cons.h> 72 1.20 christos 73 1.108 joerg #include <net/if.h> 74 1.108 joerg 75 1.126 pooka static kmutex_t kprintf_mtx; 76 1.126 pooka static bool kprintf_inited = false; 77 1.49 jonathan 78 1.22 christos #ifdef KGDB 79 1.42 thorpej #include <sys/kgdb.h> 80 1.12 cgd #endif 81 1.150 apb 82 1.45 chuck #ifdef DDB 83 1.150 apb #include <ddb/ddbvar.h> /* db_panic */ 84 1.45 chuck #include <ddb/db_output.h> /* db_printf, db_putchar prototypes */ 85 1.45 chuck #endif 86 1.45 chuck 87 1.45 chuck 88 1.45 chuck /* 89 1.45 chuck * defines 90 1.45 chuck */ 91 1.164 christos #define KLOG_PRI 0x80000000 92 1.45 chuck 93 1.45 chuck 94 1.45 chuck /* 95 1.45 chuck * local prototypes 96 1.45 chuck */ 97 1.45 chuck 98 1.94 junyoung static void putchar(int, int, struct tty *); 99 1.188 riastrad static void kprintf_internal(const char *, int, void *, char *, ...); 100 1.20 christos 101 1.12 cgd 102 1.37 thorpej /* 103 1.45 chuck * globals 104 1.37 thorpej */ 105 1.37 thorpej 106 1.45 chuck const char *panicstr; /* arg to first call to panic (used as a flag 107 1.45 chuck to indicate that panic has already been called). */ 108 1.187 andvar struct cpu_info *paniccpu; /* cpu that first panicked */ 109 1.79 simonb long panicstart, panicend; /* position in the msgbuf of the start and 110 1.79 simonb end of the formatted panicstr. */ 111 1.74 sommerfe int doing_shutdown; /* set to indicate shutdown in progress */ 112 1.45 chuck 113 1.154 tls #ifdef RND_PRINTF 114 1.183 riastrad static krndsource_t rnd_printf_source; 115 1.154 tls #endif 116 1.154 tls 117 1.90 atatat #ifndef DUMP_ON_PANIC 118 1.90 atatat #define DUMP_ON_PANIC 1 119 1.90 atatat #endif 120 1.90 atatat int dumponpanic = DUMP_ON_PANIC; 121 1.90 atatat 122 1.45 chuck /* 123 1.45 chuck * v_putc: routine to putc on virtual console 124 1.45 chuck * 125 1.45 chuck * the v_putc pointer can be used to redirect the console cnputc elsewhere 126 1.45 chuck * [e.g. to a "virtual console"]. 127 1.45 chuck */ 128 1.12 cgd 129 1.94 junyoung void (*v_putc)(int) = cnputc; /* start with cnputc (normal cons) */ 130 1.94 junyoung void (*v_flush)(void) = cnflush; /* start with cnflush (normal cons) */ 131 1.12 cgd 132 1.127 pooka const char hexdigits[] = "0123456789abcdef"; 133 1.127 pooka const char HEXDIGITS[] = "0123456789ABCDEF"; 134 1.127 pooka 135 1.12 cgd 136 1.45 chuck /* 137 1.45 chuck * functions 138 1.45 chuck */ 139 1.12 cgd 140 1.12 cgd /* 141 1.126 pooka * Locking is inited fairly early in MI bootstrap. Before that 142 1.126 pooka * prints are done unlocked. But that doesn't really matter, 143 1.126 pooka * since nothing can preempt us before interrupts are enabled. 144 1.126 pooka */ 145 1.126 pooka void 146 1.132 cegger kprintf_init(void) 147 1.126 pooka { 148 1.126 pooka 149 1.199 riastrad KASSERT(!kprintf_inited); /* not foolproof, but ... */ 150 1.199 riastrad KASSERT(cold); 151 1.183 riastrad mutex_init(&kprintf_mtx, MUTEX_DEFAULT, IPL_HIGH); 152 1.154 tls #ifdef RND_PRINTF 153 1.183 riastrad rnd_attach_source(&rnd_printf_source, "printf", RND_TYPE_UNKNOWN, 154 1.183 riastrad RND_FLAG_COLLECT_TIME|RND_FLAG_COLLECT_VALUE); 155 1.154 tls #endif 156 1.126 pooka kprintf_inited = true; 157 1.126 pooka } 158 1.126 pooka 159 1.126 pooka void 160 1.132 cegger kprintf_lock(void) 161 1.126 pooka { 162 1.126 pooka 163 1.126 pooka if (__predict_true(kprintf_inited)) 164 1.126 pooka mutex_enter(&kprintf_mtx); 165 1.126 pooka } 166 1.126 pooka 167 1.126 pooka void 168 1.132 cegger kprintf_unlock(void) 169 1.126 pooka { 170 1.126 pooka 171 1.126 pooka if (__predict_true(kprintf_inited)) { 172 1.126 pooka /* assert kprintf wasn't somehow inited while we were in */ 173 1.126 pooka KASSERT(mutex_owned(&kprintf_mtx)); 174 1.126 pooka mutex_exit(&kprintf_mtx); 175 1.126 pooka } 176 1.126 pooka } 177 1.126 pooka 178 1.126 pooka /* 179 1.89 thorpej * twiddle: spin a little propellor on the console. 180 1.89 thorpej */ 181 1.89 thorpej 182 1.89 thorpej void 183 1.89 thorpej twiddle(void) 184 1.89 thorpej { 185 1.89 thorpej static const char twiddle_chars[] = "|/-\\"; 186 1.89 thorpej static int pos; 187 1.89 thorpej 188 1.126 pooka kprintf_lock(); 189 1.89 thorpej 190 1.175 martin putchar(twiddle_chars[pos++ & 3], TOCONS|NOTSTAMP, NULL); 191 1.175 martin putchar('\b', TOCONS|NOTSTAMP, NULL); 192 1.89 thorpej 193 1.126 pooka kprintf_unlock(); 194 1.89 thorpej } 195 1.89 thorpej 196 1.89 thorpej /* 197 1.45 chuck * panic: handle an unresolvable fatal error 198 1.45 chuck * 199 1.45 chuck * prints "panic: <message>" and reboots. if called twice (i.e. recursive 200 1.138 he * call) we avoid trying to dump and just reboot (to avoid recursive panics). 201 1.12 cgd */ 202 1.45 chuck 203 1.14 cgd void 204 1.12 cgd panic(const char *fmt, ...) 205 1.12 cgd { 206 1.143 christos va_list ap; 207 1.143 christos 208 1.143 christos va_start(ap, fmt); 209 1.143 christos vpanic(fmt, ap); 210 1.143 christos va_end(ap); 211 1.143 christos } 212 1.143 christos 213 1.143 christos void 214 1.143 christos vpanic(const char *fmt, va_list ap) 215 1.143 christos { 216 1.115 ad CPU_INFO_ITERATOR cii; 217 1.115 ad struct cpu_info *ci, *oci; 218 1.14 cgd int bootopt; 219 1.160 skrll static char scratchstr[384]; /* stores panic message */ 220 1.12 cgd 221 1.137 dyoung spldebug_stop(); 222 1.137 dyoung 223 1.131 mlelstv if (lwp0.l_cpu && curlwp) { 224 1.131 mlelstv /* 225 1.189 gutterid * Disable preemption. If already panicking on another CPU, sit 226 1.131 mlelstv * here and spin until the system is rebooted. Allow the CPU that 227 1.187 andvar * first panicked to panic again. 228 1.131 mlelstv */ 229 1.131 mlelstv kpreempt_disable(); 230 1.131 mlelstv ci = curcpu(); 231 1.131 mlelstv oci = atomic_cas_ptr((void *)&paniccpu, NULL, ci); 232 1.131 mlelstv if (oci != NULL && oci != ci) { 233 1.131 mlelstv /* Give interrupts a chance to try and prevent deadlock. */ 234 1.131 mlelstv for (;;) { 235 1.130 pooka #ifndef _RUMPKERNEL /* XXXpooka: temporary build fix, see kern/40505 */ 236 1.131 mlelstv DELAY(10); 237 1.129 pooka #endif /* _RUMPKERNEL */ 238 1.131 mlelstv } 239 1.115 ad } 240 1.115 ad 241 1.131 mlelstv /* 242 1.131 mlelstv * Convert the current thread to a bound thread and prevent all 243 1.131 mlelstv * CPUs from scheduling unbound jobs. Do so without taking any 244 1.131 mlelstv * locks. 245 1.131 mlelstv */ 246 1.131 mlelstv curlwp->l_pflag |= LP_BOUND; 247 1.131 mlelstv for (CPU_INFO_FOREACH(cii, ci)) { 248 1.131 mlelstv ci->ci_schedstate.spc_flags |= SPCF_OFFLINE; 249 1.131 mlelstv } 250 1.115 ad } 251 1.115 ad 252 1.125 ad bootopt = RB_AUTOBOOT | RB_NOSYNC; 253 1.138 he if (!doing_shutdown) { 254 1.138 he if (dumponpanic) 255 1.138 he bootopt |= RB_DUMP; 256 1.138 he } else 257 1.138 he printf("Skipping crash dump on recursive panic\n"); 258 1.138 he 259 1.74 sommerfe doing_shutdown = 1; 260 1.79 simonb 261 1.163 christos if (logenabled(msgbufp)) 262 1.79 simonb panicstart = msgbufp->msg_bufx; 263 1.96 perry 264 1.188 riastrad kprintf_lock(); 265 1.188 riastrad kprintf_internal("panic: ", TOLOG|TOCONS, NULL, NULL); 266 1.142 jym if (panicstr == NULL) { 267 1.142 jym /* first time in panic - store fmt first for precaution */ 268 1.142 jym panicstr = fmt; 269 1.142 jym 270 1.142 jym vsnprintf(scratchstr, sizeof(scratchstr), fmt, ap); 271 1.188 riastrad kprintf_internal("%s", TOLOG|TOCONS, NULL, NULL, scratchstr); 272 1.142 jym panicstr = scratchstr; 273 1.142 jym } else { 274 1.188 riastrad kprintf(fmt, TOLOG|TOCONS, NULL, NULL, ap); 275 1.142 jym } 276 1.188 riastrad kprintf_internal("\n", TOLOG|TOCONS, NULL, NULL); 277 1.188 riastrad kprintf_unlock(); 278 1.79 simonb 279 1.163 christos if (logenabled(msgbufp)) 280 1.79 simonb panicend = msgbufp->msg_bufx; 281 1.12 cgd 282 1.12 cgd #ifdef KGDB 283 1.12 cgd kgdb_panic(); 284 1.12 cgd #endif 285 1.12 cgd #ifdef DDB 286 1.150 apb db_panic(); 287 1.12 cgd #endif 288 1.182 thorpej kern_reboot(bootopt, NULL); 289 1.12 cgd } 290 1.12 cgd 291 1.12 cgd /* 292 1.45 chuck * kernel logging functions: log, logpri, addlog 293 1.45 chuck */ 294 1.45 chuck 295 1.45 chuck /* 296 1.45 chuck * log: write to the log buffer 297 1.45 chuck * 298 1.45 chuck * => will not sleep [so safe to call from interrupt] 299 1.45 chuck * => will log to console if /dev/klog isn't open 300 1.45 chuck */ 301 1.45 chuck 302 1.45 chuck void 303 1.45 chuck log(int level, const char *fmt, ...) 304 1.45 chuck { 305 1.45 chuck va_list ap; 306 1.45 chuck 307 1.126 pooka kprintf_lock(); 308 1.54 thorpej 309 1.54 thorpej klogpri(level); /* log the level first */ 310 1.45 chuck va_start(ap, fmt); 311 1.45 chuck kprintf(fmt, TOLOG, NULL, NULL, ap); 312 1.45 chuck va_end(ap); 313 1.45 chuck if (!log_open) { 314 1.45 chuck va_start(ap, fmt); 315 1.45 chuck kprintf(fmt, TOCONS, NULL, NULL, ap); 316 1.45 chuck va_end(ap); 317 1.45 chuck } 318 1.64 thorpej 319 1.126 pooka kprintf_unlock(); 320 1.64 thorpej 321 1.64 thorpej logwakeup(); /* wake up anyone waiting for log msgs */ 322 1.64 thorpej } 323 1.64 thorpej 324 1.64 thorpej /* 325 1.149 dholland * vlog: write to the log buffer [already have va_list] 326 1.64 thorpej */ 327 1.64 thorpej 328 1.64 thorpej void 329 1.99 thorpej vlog(int level, const char *fmt, va_list ap) 330 1.64 thorpej { 331 1.145 christos va_list cap; 332 1.64 thorpej 333 1.145 christos va_copy(cap, ap); 334 1.126 pooka kprintf_lock(); 335 1.64 thorpej 336 1.64 thorpej klogpri(level); /* log the level first */ 337 1.64 thorpej kprintf(fmt, TOLOG, NULL, NULL, ap); 338 1.64 thorpej if (!log_open) 339 1.145 christos kprintf(fmt, TOCONS, NULL, NULL, cap); 340 1.54 thorpej 341 1.126 pooka kprintf_unlock(); 342 1.145 christos va_end(cap); 343 1.54 thorpej 344 1.45 chuck logwakeup(); /* wake up anyone waiting for log msgs */ 345 1.45 chuck } 346 1.45 chuck 347 1.45 chuck /* 348 1.45 chuck * logpri: log the priority level to the klog 349 1.45 chuck */ 350 1.45 chuck 351 1.54 thorpej void 352 1.99 thorpej logpri(int level) 353 1.45 chuck { 354 1.54 thorpej 355 1.126 pooka kprintf_lock(); 356 1.54 thorpej klogpri(level); 357 1.126 pooka kprintf_unlock(); 358 1.54 thorpej } 359 1.54 thorpej 360 1.54 thorpej /* 361 1.54 thorpej * Note: we must be in the mutex here! 362 1.54 thorpej */ 363 1.87 thorpej void 364 1.99 thorpej klogpri(int level) 365 1.54 thorpej { 366 1.164 christos KASSERT((level & KLOG_PRI) == 0); 367 1.45 chuck 368 1.164 christos putchar(level | KLOG_PRI, TOLOG, NULL); 369 1.45 chuck } 370 1.45 chuck 371 1.45 chuck /* 372 1.45 chuck * addlog: add info to previous log message 373 1.12 cgd */ 374 1.45 chuck 375 1.12 cgd void 376 1.45 chuck addlog(const char *fmt, ...) 377 1.45 chuck { 378 1.45 chuck va_list ap; 379 1.45 chuck 380 1.126 pooka kprintf_lock(); 381 1.54 thorpej 382 1.45 chuck va_start(ap, fmt); 383 1.45 chuck kprintf(fmt, TOLOG, NULL, NULL, ap); 384 1.45 chuck va_end(ap); 385 1.45 chuck if (!log_open) { 386 1.45 chuck va_start(ap, fmt); 387 1.45 chuck kprintf(fmt, TOCONS, NULL, NULL, ap); 388 1.45 chuck va_end(ap); 389 1.45 chuck } 390 1.54 thorpej 391 1.126 pooka kprintf_unlock(); 392 1.54 thorpej 393 1.45 chuck logwakeup(); 394 1.45 chuck } 395 1.45 chuck 396 1.45 chuck static void 397 1.164 christos putone(int c, int flags, struct tty *tp) 398 1.12 cgd { 399 1.194 riastrad struct tty *ctp; 400 1.194 riastrad int s; 401 1.198 macallan bool do_ps = !cold; 402 1.194 riastrad 403 1.196 simonb ctp = NULL; /* XXX gcc i386 -Os */ 404 1.196 simonb 405 1.194 riastrad /* 406 1.194 riastrad * Ensure whatever constty points to can't go away while we're 407 1.194 riastrad * trying to use it. 408 1.194 riastrad */ 409 1.197 mrg if (__predict_true(do_ps)) 410 1.197 mrg s = pserialize_read_enter(); 411 1.194 riastrad 412 1.45 chuck if (panicstr) 413 1.194 riastrad atomic_store_relaxed(&constty, NULL); 414 1.164 christos 415 1.194 riastrad if ((flags & TOCONS) && 416 1.194 riastrad (ctp = atomic_load_consume(&constty)) != NULL && 417 1.194 riastrad tp == NULL) { 418 1.194 riastrad tp = ctp; 419 1.45 chuck flags |= TOTTY; 420 1.45 chuck } 421 1.91 christos if ((flags & TOTTY) && tp && 422 1.91 christos tputchar(c, flags, tp) < 0 && 423 1.194 riastrad (flags & TOCONS)) 424 1.194 riastrad atomic_cas_ptr(&constty, tp, NULL); 425 1.45 chuck if ((flags & TOLOG) && 426 1.111 ad c != '\0' && c != '\r' && c != 0177) 427 1.111 ad logputchar(c); 428 1.194 riastrad if ((flags & TOCONS) && ctp == NULL && c != '\0') 429 1.45 chuck (*v_putc)(c); 430 1.194 riastrad 431 1.197 mrg if (__predict_true(do_ps)) 432 1.197 mrg pserialize_read_exit(s); 433 1.164 christos } 434 1.164 christos 435 1.164 christos static void 436 1.164 christos putlogpri(int level) 437 1.164 christos { 438 1.164 christos char *p; 439 1.164 christos char snbuf[KPRINTF_BUFSIZE]; 440 1.164 christos 441 1.164 christos putone('<', TOLOG, NULL); 442 1.164 christos snprintf(snbuf, sizeof(snbuf), "%d", level); 443 1.164 christos for (p = snbuf ; *p ; p++) 444 1.164 christos putone(*p, TOLOG, NULL); 445 1.164 christos putone('>', TOLOG, NULL); 446 1.164 christos } 447 1.164 christos 448 1.166 christos #ifndef KLOG_NOTIMESTAMP 449 1.165 christos static int needtstamp = 1; 450 1.170 kre int log_ts_prec = 7; 451 1.165 christos 452 1.165 christos static void 453 1.165 christos addtstamp(int flags, struct tty *tp) 454 1.165 christos { 455 1.165 christos char buf[64]; 456 1.165 christos struct timespec ts; 457 1.169 kre int n, prec; 458 1.169 kre long fsec; 459 1.169 kre 460 1.169 kre prec = log_ts_prec; 461 1.169 kre if (prec < 0) { 462 1.169 kre prec = 0; 463 1.169 kre log_ts_prec = prec; 464 1.169 kre } else if (prec > 9) { 465 1.169 kre prec = 9; 466 1.169 kre log_ts_prec = prec; 467 1.169 kre } 468 1.165 christos 469 1.165 christos getnanouptime(&ts); 470 1.169 kre 471 1.169 kre for (n = prec, fsec = ts.tv_nsec; n < 8; n++) 472 1.169 kre fsec /= 10; 473 1.169 kre if (n < 9) 474 1.169 kre fsec = (fsec / 10) + ((fsec % 10) >= 5); 475 1.169 kre 476 1.169 kre n = snprintf(buf, sizeof(buf), "[% 4jd.%.*ld] ", 477 1.169 kre (intmax_t)ts.tv_sec, prec, fsec); 478 1.165 christos 479 1.165 christos for (int i = 0; i < n; i++) 480 1.165 christos putone(buf[i], flags, tp); 481 1.165 christos } 482 1.165 christos #endif 483 1.165 christos 484 1.164 christos /* 485 1.164 christos * putchar: print a single character on console or user terminal. 486 1.164 christos * 487 1.164 christos * => if console, then the last MSGBUFS chars are saved in msgbuf 488 1.164 christos * for inspection later (e.g. dmesg/syslog) 489 1.164 christos * => we must already be in the mutex! 490 1.164 christos */ 491 1.164 christos static void 492 1.164 christos putchar(int c, int flags, struct tty *tp) 493 1.164 christos { 494 1.164 christos if (c & KLOG_PRI) { 495 1.164 christos putlogpri(c & ~KLOG_PRI); 496 1.164 christos return; 497 1.164 christos } 498 1.164 christos 499 1.166 christos #ifndef KLOG_NOTIMESTAMP 500 1.175 martin if (c != '\0' && c != '\n' && needtstamp && (flags & NOTSTAMP) == 0) { 501 1.165 christos addtstamp(flags, tp); 502 1.165 christos needtstamp = 0; 503 1.165 christos } 504 1.165 christos 505 1.165 christos if (c == '\n') 506 1.169 kre needtstamp = 1; 507 1.165 christos #endif 508 1.164 christos putone(c, flags, tp); 509 1.164 christos 510 1.45 chuck #ifdef DDB 511 1.154 tls if (flags & TODDB) { 512 1.45 chuck db_putchar(c); 513 1.154 tls return; 514 1.154 tls } 515 1.154 tls #endif 516 1.154 tls 517 1.154 tls #ifdef RND_PRINTF 518 1.154 tls if (__predict_true(kprintf_inited)) { 519 1.183 riastrad unsigned char ch = c; 520 1.202 riastrad rnd_add_data_intr(&rnd_printf_source, &ch, 1, 0); 521 1.154 tls } 522 1.45 chuck #endif 523 1.12 cgd } 524 1.12 cgd 525 1.127 pooka /* 526 1.127 pooka * tablefull: warn that a system table is full 527 1.127 pooka */ 528 1.127 pooka 529 1.127 pooka void 530 1.127 pooka tablefull(const char *tab, const char *hint) 531 1.127 pooka { 532 1.127 pooka if (hint) 533 1.127 pooka log(LOG_ERR, "%s: table is full - %s\n", tab, hint); 534 1.127 pooka else 535 1.127 pooka log(LOG_ERR, "%s: table is full\n", tab); 536 1.127 pooka } 537 1.127 pooka 538 1.45 chuck 539 1.12 cgd /* 540 1.45 chuck * uprintf: print to the controlling tty of the current process 541 1.45 chuck * 542 1.45 chuck * => we may block if the tty queue is full 543 1.45 chuck * => no message is printed if the queue doesn't clear in a reasonable 544 1.45 chuck * time 545 1.12 cgd */ 546 1.45 chuck 547 1.12 cgd void 548 1.12 cgd uprintf(const char *fmt, ...) 549 1.12 cgd { 550 1.69 augustss struct proc *p = curproc; 551 1.12 cgd va_list ap; 552 1.12 cgd 553 1.184 ad /* mutex_enter(&proc_lock); XXXSMP */ 554 1.104 ad 555 1.104 ad if (p->p_lflag & PL_CONTROLT && p->p_session->s_ttyvp) { 556 1.104 ad /* No mutex needed; going to process TTY. */ 557 1.104 ad va_start(ap, fmt); 558 1.104 ad kprintf(fmt, TOTTY, p->p_session->s_ttyp, NULL, ap); 559 1.104 ad va_end(ap); 560 1.104 ad } 561 1.104 ad 562 1.184 ad /* mutex_exit(&proc_lock); XXXSMP */ 563 1.104 ad } 564 1.104 ad 565 1.104 ad void 566 1.104 ad uprintf_locked(const char *fmt, ...) 567 1.104 ad { 568 1.104 ad struct proc *p = curproc; 569 1.104 ad va_list ap; 570 1.104 ad 571 1.104 ad if (p->p_lflag & PL_CONTROLT && p->p_session->s_ttyvp) { 572 1.54 thorpej /* No mutex needed; going to process TTY. */ 573 1.12 cgd va_start(ap, fmt); 574 1.45 chuck kprintf(fmt, TOTTY, p->p_session->s_ttyp, NULL, ap); 575 1.12 cgd va_end(ap); 576 1.12 cgd } 577 1.12 cgd } 578 1.12 cgd 579 1.45 chuck /* 580 1.45 chuck * tprintf functions: used to send messages to a specific process 581 1.45 chuck * 582 1.45 chuck * usage: 583 1.45 chuck * get a tpr_t handle on a process "p" by using "tprintf_open(p)" 584 1.45 chuck * use the handle when calling "tprintf" 585 1.45 chuck * when done, do a "tprintf_close" to drop the handle 586 1.45 chuck */ 587 1.45 chuck 588 1.45 chuck /* 589 1.45 chuck * tprintf_open: get a tprintf handle on a process "p" 590 1.45 chuck * 591 1.45 chuck * => returns NULL if process can't be printed to 592 1.45 chuck */ 593 1.45 chuck 594 1.12 cgd tpr_t 595 1.99 thorpej tprintf_open(struct proc *p) 596 1.12 cgd { 597 1.104 ad tpr_t cookie; 598 1.12 cgd 599 1.104 ad cookie = NULL; 600 1.104 ad 601 1.184 ad mutex_enter(&proc_lock); 602 1.104 ad if (p->p_lflag & PL_CONTROLT && p->p_session->s_ttyvp) { 603 1.133 rmind proc_sesshold(p->p_session); 604 1.104 ad cookie = (tpr_t)p->p_session; 605 1.12 cgd } 606 1.184 ad mutex_exit(&proc_lock); 607 1.104 ad 608 1.104 ad return cookie; 609 1.12 cgd } 610 1.12 cgd 611 1.45 chuck /* 612 1.45 chuck * tprintf_close: dispose of a tprintf handle obtained with tprintf_open 613 1.45 chuck */ 614 1.45 chuck 615 1.12 cgd void 616 1.99 thorpej tprintf_close(tpr_t sess) 617 1.12 cgd { 618 1.12 cgd 619 1.118 yamt if (sess) { 620 1.184 ad mutex_enter(&proc_lock); 621 1.133 rmind /* Releases proc_lock. */ 622 1.133 rmind proc_sessrele((struct session *)sess); 623 1.118 yamt } 624 1.12 cgd } 625 1.12 cgd 626 1.12 cgd /* 627 1.96 perry * tprintf: given tprintf handle to a process [obtained with tprintf_open], 628 1.45 chuck * send a message to the controlling tty for that process. 629 1.45 chuck * 630 1.45 chuck * => also sends message to /dev/klog 631 1.12 cgd */ 632 1.12 cgd void 633 1.12 cgd tprintf(tpr_t tpr, const char *fmt, ...) 634 1.12 cgd { 635 1.69 augustss struct session *sess = (struct session *)tpr; 636 1.12 cgd struct tty *tp = NULL; 637 1.126 pooka int flags = TOLOG; 638 1.12 cgd va_list ap; 639 1.12 cgd 640 1.184 ad /* mutex_enter(&proc_lock); XXXSMP */ 641 1.200 riastrad if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp)) { 642 1.12 cgd flags |= TOTTY; 643 1.12 cgd tp = sess->s_ttyp; 644 1.12 cgd } 645 1.54 thorpej 646 1.126 pooka kprintf_lock(); 647 1.54 thorpej 648 1.54 thorpej klogpri(LOG_INFO); 649 1.12 cgd va_start(ap, fmt); 650 1.45 chuck kprintf(fmt, flags, tp, NULL, ap); 651 1.12 cgd va_end(ap); 652 1.54 thorpej 653 1.126 pooka kprintf_unlock(); 654 1.184 ad /* mutex_exit(&proc_lock); XXXSMP */ 655 1.54 thorpej 656 1.12 cgd logwakeup(); 657 1.12 cgd } 658 1.12 cgd 659 1.45 chuck 660 1.12 cgd /* 661 1.45 chuck * ttyprintf: send a message to a specific tty 662 1.45 chuck * 663 1.45 chuck * => should be used only by tty driver or anything that knows the 664 1.52 mrg * underlying tty will not be revoked(2)'d away. [otherwise, 665 1.52 mrg * use tprintf] 666 1.12 cgd */ 667 1.12 cgd void 668 1.12 cgd ttyprintf(struct tty *tp, const char *fmt, ...) 669 1.12 cgd { 670 1.12 cgd va_list ap; 671 1.12 cgd 672 1.54 thorpej /* No mutex needed; going to process TTY. */ 673 1.12 cgd va_start(ap, fmt); 674 1.45 chuck kprintf(fmt, TOTTY, tp, NULL, ap); 675 1.12 cgd va_end(ap); 676 1.12 cgd } 677 1.12 cgd 678 1.45 chuck #ifdef DDB 679 1.12 cgd 680 1.12 cgd /* 681 1.45 chuck * db_printf: printf for DDB (via db_putchar) 682 1.12 cgd */ 683 1.45 chuck 684 1.12 cgd void 685 1.45 chuck db_printf(const char *fmt, ...) 686 1.12 cgd { 687 1.12 cgd va_list ap; 688 1.12 cgd 689 1.54 thorpej /* No mutex needed; DDB pauses all processors. */ 690 1.12 cgd va_start(ap, fmt); 691 1.45 chuck kprintf(fmt, TODDB, NULL, NULL, ap); 692 1.12 cgd va_end(ap); 693 1.95 reinoud 694 1.95 reinoud if (db_tee_msgbuf) { 695 1.95 reinoud va_start(ap, fmt); 696 1.95 reinoud kprintf(fmt, TOLOG, NULL, NULL, ap); 697 1.95 reinoud va_end(ap); 698 1.157 msaitoh } 699 1.84 drochner } 700 1.84 drochner 701 1.84 drochner void 702 1.99 thorpej db_vprintf(const char *fmt, va_list ap) 703 1.84 drochner { 704 1.145 christos va_list cap; 705 1.84 drochner 706 1.145 christos va_copy(cap, ap); 707 1.84 drochner /* No mutex needed; DDB pauses all processors. */ 708 1.84 drochner kprintf(fmt, TODDB, NULL, NULL, ap); 709 1.95 reinoud if (db_tee_msgbuf) 710 1.145 christos kprintf(fmt, TOLOG, NULL, NULL, cap); 711 1.145 christos va_end(cap); 712 1.12 cgd } 713 1.12 cgd 714 1.45 chuck #endif /* DDB */ 715 1.12 cgd 716 1.108 joerg static void 717 1.108 joerg kprintf_internal(const char *fmt, int oflags, void *vp, char *sbuf, ...) 718 1.108 joerg { 719 1.108 joerg va_list ap; 720 1.108 joerg 721 1.108 joerg va_start(ap, sbuf); 722 1.108 joerg (void)kprintf(fmt, oflags, vp, sbuf, ap); 723 1.108 joerg va_end(ap); 724 1.108 joerg } 725 1.108 joerg 726 1.88 thorpej /* 727 1.88 thorpej * Device autoconfiguration printf routines. These change their 728 1.88 thorpej * behavior based on the AB_* flags in boothowto. If AB_SILENT 729 1.88 thorpej * is set, messages never go to the console (but they still always 730 1.88 thorpej * go to the log). AB_VERBOSE overrides AB_SILENT. 731 1.88 thorpej */ 732 1.88 thorpej 733 1.88 thorpej /* 734 1.88 thorpej * aprint_normal: Send to console unless AB_QUIET. Always goes 735 1.88 thorpej * to the log. 736 1.88 thorpej */ 737 1.108 joerg static void 738 1.108 joerg aprint_normal_internal(const char *prefix, const char *fmt, va_list ap) 739 1.88 thorpej { 740 1.126 pooka int flags = TOLOG; 741 1.88 thorpej 742 1.88 thorpej if ((boothowto & (AB_SILENT|AB_QUIET)) == 0 || 743 1.88 thorpej (boothowto & AB_VERBOSE) != 0) 744 1.88 thorpej flags |= TOCONS; 745 1.96 perry 746 1.126 pooka kprintf_lock(); 747 1.88 thorpej 748 1.108 joerg if (prefix) 749 1.108 joerg kprintf_internal("%s: ", flags, NULL, NULL, prefix); 750 1.88 thorpej kprintf(fmt, flags, NULL, NULL, ap); 751 1.88 thorpej 752 1.126 pooka kprintf_unlock(); 753 1.96 perry 754 1.88 thorpej if (!panicstr) 755 1.88 thorpej logwakeup(); 756 1.88 thorpej } 757 1.88 thorpej 758 1.108 joerg void 759 1.108 joerg aprint_normal(const char *fmt, ...) 760 1.108 joerg { 761 1.108 joerg va_list ap; 762 1.108 joerg 763 1.108 joerg va_start(ap, fmt); 764 1.108 joerg aprint_normal_internal(NULL, fmt, ap); 765 1.108 joerg va_end(ap); 766 1.108 joerg } 767 1.108 joerg 768 1.108 joerg void 769 1.108 joerg aprint_normal_dev(device_t dv, const char *fmt, ...) 770 1.108 joerg { 771 1.108 joerg va_list ap; 772 1.108 joerg 773 1.176 jdolecek KASSERT(dv != NULL); 774 1.176 jdolecek 775 1.108 joerg va_start(ap, fmt); 776 1.108 joerg aprint_normal_internal(device_xname(dv), fmt, ap); 777 1.108 joerg va_end(ap); 778 1.108 joerg } 779 1.108 joerg 780 1.108 joerg void 781 1.108 joerg aprint_normal_ifnet(struct ifnet *ifp, const char *fmt, ...) 782 1.108 joerg { 783 1.108 joerg va_list ap; 784 1.108 joerg 785 1.176 jdolecek KASSERT(ifp != NULL); 786 1.176 jdolecek 787 1.108 joerg va_start(ap, fmt); 788 1.108 joerg aprint_normal_internal(ifp->if_xname, fmt, ap); 789 1.108 joerg va_end(ap); 790 1.108 joerg } 791 1.108 joerg 792 1.88 thorpej /* 793 1.89 thorpej * aprint_error: Send to console unless AB_QUIET. Always goes 794 1.89 thorpej * to the log. Also counts the number of times called so other 795 1.89 thorpej * parts of the kernel can report the number of errors during a 796 1.89 thorpej * given phase of system startup. 797 1.89 thorpej */ 798 1.89 thorpej static int aprint_error_count; 799 1.89 thorpej 800 1.89 thorpej int 801 1.89 thorpej aprint_get_error_count(void) 802 1.89 thorpej { 803 1.126 pooka int count; 804 1.89 thorpej 805 1.126 pooka kprintf_lock(); 806 1.89 thorpej 807 1.89 thorpej count = aprint_error_count; 808 1.89 thorpej aprint_error_count = 0; 809 1.89 thorpej 810 1.126 pooka kprintf_unlock(); 811 1.89 thorpej 812 1.89 thorpej return (count); 813 1.89 thorpej } 814 1.89 thorpej 815 1.108 joerg static void 816 1.108 joerg aprint_error_internal(const char *prefix, const char *fmt, va_list ap) 817 1.89 thorpej { 818 1.126 pooka int flags = TOLOG; 819 1.89 thorpej 820 1.89 thorpej if ((boothowto & (AB_SILENT|AB_QUIET)) == 0 || 821 1.89 thorpej (boothowto & AB_VERBOSE) != 0) 822 1.89 thorpej flags |= TOCONS; 823 1.96 perry 824 1.126 pooka kprintf_lock(); 825 1.89 thorpej 826 1.89 thorpej aprint_error_count++; 827 1.89 thorpej 828 1.108 joerg if (prefix) 829 1.108 joerg kprintf_internal("%s: ", flags, NULL, NULL, prefix); 830 1.181 christos kprintf_internal("autoconfiguration error: ", TOLOG, NULL, NULL); 831 1.89 thorpej kprintf(fmt, flags, NULL, NULL, ap); 832 1.89 thorpej 833 1.126 pooka kprintf_unlock(); 834 1.96 perry 835 1.89 thorpej if (!panicstr) 836 1.89 thorpej logwakeup(); 837 1.89 thorpej } 838 1.89 thorpej 839 1.108 joerg void 840 1.108 joerg aprint_error(const char *fmt, ...) 841 1.108 joerg { 842 1.108 joerg va_list ap; 843 1.108 joerg 844 1.108 joerg va_start(ap, fmt); 845 1.108 joerg aprint_error_internal(NULL, fmt, ap); 846 1.108 joerg va_end(ap); 847 1.108 joerg } 848 1.108 joerg 849 1.108 joerg void 850 1.108 joerg aprint_error_dev(device_t dv, const char *fmt, ...) 851 1.108 joerg { 852 1.108 joerg va_list ap; 853 1.108 joerg 854 1.176 jdolecek KASSERT(dv != NULL); 855 1.176 jdolecek 856 1.108 joerg va_start(ap, fmt); 857 1.108 joerg aprint_error_internal(device_xname(dv), fmt, ap); 858 1.108 joerg va_end(ap); 859 1.108 joerg } 860 1.108 joerg 861 1.108 joerg void 862 1.108 joerg aprint_error_ifnet(struct ifnet *ifp, const char *fmt, ...) 863 1.108 joerg { 864 1.108 joerg va_list ap; 865 1.108 joerg 866 1.176 jdolecek KASSERT(ifp != NULL); 867 1.176 jdolecek 868 1.108 joerg va_start(ap, fmt); 869 1.108 joerg aprint_error_internal(ifp->if_xname, fmt, ap); 870 1.108 joerg va_end(ap); 871 1.108 joerg } 872 1.108 joerg 873 1.89 thorpej /* 874 1.88 thorpej * aprint_naive: Send to console only if AB_QUIET. Never goes 875 1.88 thorpej * to the log. 876 1.88 thorpej */ 877 1.108 joerg static void 878 1.108 joerg aprint_naive_internal(const char *prefix, const char *fmt, va_list ap) 879 1.108 joerg { 880 1.108 joerg if ((boothowto & (AB_QUIET|AB_SILENT|AB_VERBOSE)) != AB_QUIET) 881 1.108 joerg return; 882 1.108 joerg 883 1.126 pooka kprintf_lock(); 884 1.108 joerg 885 1.108 joerg if (prefix) 886 1.108 joerg kprintf_internal("%s: ", TOCONS, NULL, NULL, prefix); 887 1.108 joerg kprintf(fmt, TOCONS, NULL, NULL, ap); 888 1.108 joerg 889 1.126 pooka kprintf_unlock(); 890 1.108 joerg } 891 1.108 joerg 892 1.88 thorpej void 893 1.88 thorpej aprint_naive(const char *fmt, ...) 894 1.88 thorpej { 895 1.88 thorpej va_list ap; 896 1.88 thorpej 897 1.108 joerg va_start(ap, fmt); 898 1.108 joerg aprint_naive_internal(NULL, fmt, ap); 899 1.108 joerg va_end(ap); 900 1.108 joerg } 901 1.108 joerg 902 1.108 joerg void 903 1.108 joerg aprint_naive_dev(device_t dv, const char *fmt, ...) 904 1.108 joerg { 905 1.108 joerg va_list ap; 906 1.108 joerg 907 1.176 jdolecek KASSERT(dv != NULL); 908 1.176 jdolecek 909 1.108 joerg va_start(ap, fmt); 910 1.108 joerg aprint_naive_internal(device_xname(dv), fmt, ap); 911 1.108 joerg va_end(ap); 912 1.108 joerg } 913 1.88 thorpej 914 1.108 joerg void 915 1.108 joerg aprint_naive_ifnet(struct ifnet *ifp, const char *fmt, ...) 916 1.108 joerg { 917 1.108 joerg va_list ap; 918 1.88 thorpej 919 1.176 jdolecek KASSERT(ifp != NULL); 920 1.176 jdolecek 921 1.108 joerg va_start(ap, fmt); 922 1.108 joerg aprint_naive_internal(ifp->if_xname, fmt, ap); 923 1.108 joerg va_end(ap); 924 1.88 thorpej } 925 1.88 thorpej 926 1.88 thorpej /* 927 1.88 thorpej * aprint_verbose: Send to console only if AB_VERBOSE. Always 928 1.88 thorpej * goes to the log. 929 1.88 thorpej */ 930 1.108 joerg static void 931 1.108 joerg aprint_verbose_internal(const char *prefix, const char *fmt, va_list ap) 932 1.88 thorpej { 933 1.126 pooka int flags = TOLOG; 934 1.88 thorpej 935 1.88 thorpej if (boothowto & AB_VERBOSE) 936 1.88 thorpej flags |= TOCONS; 937 1.96 perry 938 1.126 pooka kprintf_lock(); 939 1.88 thorpej 940 1.108 joerg if (prefix) 941 1.108 joerg kprintf_internal("%s: ", flags, NULL, NULL, prefix); 942 1.88 thorpej kprintf(fmt, flags, NULL, NULL, ap); 943 1.88 thorpej 944 1.126 pooka kprintf_unlock(); 945 1.96 perry 946 1.88 thorpej if (!panicstr) 947 1.88 thorpej logwakeup(); 948 1.88 thorpej } 949 1.88 thorpej 950 1.108 joerg void 951 1.108 joerg aprint_verbose(const char *fmt, ...) 952 1.108 joerg { 953 1.108 joerg va_list ap; 954 1.108 joerg 955 1.108 joerg va_start(ap, fmt); 956 1.108 joerg aprint_verbose_internal(NULL, fmt, ap); 957 1.108 joerg va_end(ap); 958 1.108 joerg } 959 1.108 joerg 960 1.108 joerg void 961 1.108 joerg aprint_verbose_dev(device_t dv, const char *fmt, ...) 962 1.108 joerg { 963 1.108 joerg va_list ap; 964 1.108 joerg 965 1.176 jdolecek KASSERT(dv != NULL); 966 1.176 jdolecek 967 1.108 joerg va_start(ap, fmt); 968 1.108 joerg aprint_verbose_internal(device_xname(dv), fmt, ap); 969 1.108 joerg va_end(ap); 970 1.108 joerg } 971 1.108 joerg 972 1.108 joerg void 973 1.108 joerg aprint_verbose_ifnet(struct ifnet *ifp, const char *fmt, ...) 974 1.108 joerg { 975 1.108 joerg va_list ap; 976 1.108 joerg 977 1.176 jdolecek KASSERT(ifp != NULL); 978 1.176 jdolecek 979 1.108 joerg va_start(ap, fmt); 980 1.108 joerg aprint_verbose_internal(ifp->if_xname, fmt, ap); 981 1.108 joerg va_end(ap); 982 1.108 joerg } 983 1.108 joerg 984 1.88 thorpej /* 985 1.88 thorpej * aprint_debug: Send to console and log only if AB_DEBUG. 986 1.88 thorpej */ 987 1.108 joerg static void 988 1.108 joerg aprint_debug_internal(const char *prefix, const char *fmt, va_list ap) 989 1.108 joerg { 990 1.108 joerg if ((boothowto & AB_DEBUG) == 0) 991 1.108 joerg return; 992 1.108 joerg 993 1.126 pooka kprintf_lock(); 994 1.108 joerg 995 1.108 joerg if (prefix) 996 1.108 joerg kprintf_internal("%s: ", TOCONS | TOLOG, NULL, NULL, prefix); 997 1.108 joerg kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap); 998 1.108 joerg 999 1.126 pooka kprintf_unlock(); 1000 1.108 joerg } 1001 1.108 joerg 1002 1.88 thorpej void 1003 1.88 thorpej aprint_debug(const char *fmt, ...) 1004 1.88 thorpej { 1005 1.88 thorpej va_list ap; 1006 1.88 thorpej 1007 1.108 joerg va_start(ap, fmt); 1008 1.108 joerg aprint_debug_internal(NULL, fmt, ap); 1009 1.108 joerg va_end(ap); 1010 1.108 joerg } 1011 1.108 joerg 1012 1.108 joerg void 1013 1.108 joerg aprint_debug_dev(device_t dv, const char *fmt, ...) 1014 1.108 joerg { 1015 1.108 joerg va_list ap; 1016 1.108 joerg 1017 1.176 jdolecek KASSERT(dv != NULL); 1018 1.176 jdolecek 1019 1.108 joerg va_start(ap, fmt); 1020 1.108 joerg aprint_debug_internal(device_xname(dv), fmt, ap); 1021 1.108 joerg va_end(ap); 1022 1.108 joerg } 1023 1.88 thorpej 1024 1.108 joerg void 1025 1.108 joerg aprint_debug_ifnet(struct ifnet *ifp, const char *fmt, ...) 1026 1.108 joerg { 1027 1.108 joerg va_list ap; 1028 1.88 thorpej 1029 1.176 jdolecek KASSERT(ifp != NULL); 1030 1.176 jdolecek 1031 1.108 joerg va_start(ap, fmt); 1032 1.108 joerg aprint_debug_internal(ifp->if_xname, fmt, ap); 1033 1.108 joerg va_end(ap); 1034 1.89 thorpej } 1035 1.89 thorpej 1036 1.123 dyoung void 1037 1.175 martin vprintf_flags(int flags, const char *fmt, va_list ap) 1038 1.175 martin { 1039 1.175 martin kprintf_lock(); 1040 1.175 martin kprintf(fmt, flags, NULL, NULL, ap); 1041 1.175 martin kprintf_unlock(); 1042 1.175 martin } 1043 1.175 martin 1044 1.175 martin void 1045 1.175 martin printf_flags(int flags, const char *fmt, ...) 1046 1.175 martin { 1047 1.175 martin va_list ap; 1048 1.175 martin 1049 1.175 martin va_start(ap, fmt); 1050 1.175 martin vprintf_flags(flags, fmt, ap); 1051 1.175 martin va_end(ap); 1052 1.175 martin } 1053 1.175 martin 1054 1.175 martin void 1055 1.123 dyoung printf_tolog(const char *fmt, ...) 1056 1.123 dyoung { 1057 1.123 dyoung va_list ap; 1058 1.123 dyoung 1059 1.123 dyoung va_start(ap, fmt); 1060 1.175 martin vprintf_flags(TOLOG, fmt, ap); 1061 1.123 dyoung va_end(ap); 1062 1.123 dyoung } 1063 1.123 dyoung 1064 1.89 thorpej /* 1065 1.89 thorpej * printf_nolog: Like printf(), but does not send message to the log. 1066 1.89 thorpej */ 1067 1.89 thorpej 1068 1.89 thorpej void 1069 1.89 thorpej printf_nolog(const char *fmt, ...) 1070 1.89 thorpej { 1071 1.89 thorpej va_list ap; 1072 1.89 thorpej 1073 1.89 thorpej va_start(ap, fmt); 1074 1.175 martin vprintf_flags(TOCONS, fmt, ap); 1075 1.89 thorpej va_end(ap); 1076 1.88 thorpej } 1077 1.12 cgd 1078 1.45 chuck /* 1079 1.186 simonb * printf_nostamp: Like printf(), but does not prepend a timestamp. 1080 1.186 simonb */ 1081 1.186 simonb 1082 1.186 simonb void 1083 1.186 simonb printf_nostamp(const char *fmt, ...) 1084 1.186 simonb { 1085 1.186 simonb va_list ap; 1086 1.186 simonb 1087 1.186 simonb va_start(ap, fmt); 1088 1.186 simonb vprintf_flags(TOCONS|NOTSTAMP, fmt, ap); 1089 1.186 simonb va_end(ap); 1090 1.186 simonb } 1091 1.186 simonb 1092 1.186 simonb /* 1093 1.76 tv * normal kernel printf functions: printf, vprintf, snprintf, vsnprintf 1094 1.45 chuck */ 1095 1.12 cgd 1096 1.45 chuck /* 1097 1.45 chuck * printf: print a message to the console and the log 1098 1.45 chuck */ 1099 1.162 joerg void 1100 1.30 christos printf(const char *fmt, ...) 1101 1.12 cgd { 1102 1.12 cgd va_list ap; 1103 1.54 thorpej 1104 1.12 cgd va_start(ap, fmt); 1105 1.175 martin vprintf_flags(TOCONS | TOLOG, fmt, ap); 1106 1.12 cgd va_end(ap); 1107 1.12 cgd } 1108 1.12 cgd 1109 1.45 chuck /* 1110 1.45 chuck * vprintf: print a message to the console and the log [already have 1111 1.149 dholland * va_list] 1112 1.45 chuck */ 1113 1.45 chuck 1114 1.40 thorpej void 1115 1.99 thorpej vprintf(const char *fmt, va_list ap) 1116 1.40 thorpej { 1117 1.175 martin vprintf_flags(TOCONS | TOLOG, fmt, ap); 1118 1.54 thorpej 1119 1.40 thorpej if (!panicstr) 1120 1.40 thorpej logwakeup(); 1121 1.40 thorpej } 1122 1.40 thorpej 1123 1.12 cgd /* 1124 1.58 msaitoh * snprintf: print a message to a buffer 1125 1.58 msaitoh */ 1126 1.58 msaitoh int 1127 1.98 christos snprintf(char *bf, size_t size, const char *fmt, ...) 1128 1.58 msaitoh { 1129 1.58 msaitoh int retval; 1130 1.58 msaitoh va_list ap; 1131 1.58 msaitoh 1132 1.58 msaitoh va_start(ap, fmt); 1133 1.145 christos retval = vsnprintf(bf, size, fmt, ap); 1134 1.58 msaitoh va_end(ap); 1135 1.145 christos 1136 1.144 christos return retval; 1137 1.58 msaitoh } 1138 1.58 msaitoh 1139 1.58 msaitoh /* 1140 1.149 dholland * vsnprintf: print a message to a buffer [already have va_list] 1141 1.58 msaitoh */ 1142 1.58 msaitoh int 1143 1.99 thorpej vsnprintf(char *bf, size_t size, const char *fmt, va_list ap) 1144 1.58 msaitoh { 1145 1.58 msaitoh int retval; 1146 1.58 msaitoh char *p; 1147 1.58 msaitoh 1148 1.144 christos p = bf + size; 1149 1.98 christos retval = kprintf(fmt, TOBUFONLY, &p, bf, ap); 1150 1.145 christos if (bf && size > 0) { 1151 1.145 christos /* nul terminate */ 1152 1.148 christos if (size <= (size_t)retval) 1153 1.147 christos bf[size - 1] = '\0'; 1154 1.145 christos else 1155 1.147 christos bf[retval] = '\0'; 1156 1.145 christos } 1157 1.144 christos return retval; 1158 1.58 msaitoh } 1159 1.58 msaitoh 1160 1.177 christos int 1161 1.177 christos vasprintf(char **bf, const char *fmt, va_list ap) 1162 1.177 christos { 1163 1.177 christos int retval; 1164 1.177 christos va_list cap; 1165 1.177 christos 1166 1.177 christos va_copy(cap, ap); 1167 1.179 christos retval = kprintf(fmt, TOBUFONLY, NULL, NULL, cap) + 1; 1168 1.179 christos va_end(cap); 1169 1.177 christos *bf = kmem_alloc(retval, KM_SLEEP); 1170 1.179 christos return vsnprintf(*bf, retval, fmt, ap); 1171 1.177 christos } 1172 1.177 christos 1173 1.58 msaitoh /* 1174 1.45 chuck * kprintf: scaled down version of printf(3). 1175 1.45 chuck * 1176 1.96 perry * this version based on vfprintf() from libc which was derived from 1177 1.45 chuck * software contributed to Berkeley by Chris Torek. 1178 1.45 chuck * 1179 1.76 tv * NOTE: The kprintf mutex must be held if we're going TOBUF or TOCONS! 1180 1.45 chuck */ 1181 1.45 chuck 1182 1.45 chuck /* 1183 1.45 chuck * macros for converting digits to letters and vice versa 1184 1.45 chuck */ 1185 1.45 chuck #define to_digit(c) ((c) - '0') 1186 1.45 chuck #define is_digit(c) ((unsigned)to_digit(c) <= 9) 1187 1.45 chuck #define to_char(n) ((n) + '0') 1188 1.45 chuck 1189 1.45 chuck /* 1190 1.45 chuck * flags used during conversion. 1191 1.45 chuck */ 1192 1.45 chuck #define ALT 0x001 /* alternate form */ 1193 1.45 chuck #define HEXPREFIX 0x002 /* add 0x or 0X prefix */ 1194 1.45 chuck #define LADJUST 0x004 /* left adjustment */ 1195 1.45 chuck #define LONGDBL 0x008 /* long double; unimplemented */ 1196 1.45 chuck #define LONGINT 0x010 /* long integer */ 1197 1.45 chuck #define QUADINT 0x020 /* quad integer */ 1198 1.45 chuck #define SHORTINT 0x040 /* short integer */ 1199 1.78 kleink #define MAXINT 0x080 /* intmax_t */ 1200 1.78 kleink #define PTRINT 0x100 /* intptr_t */ 1201 1.78 kleink #define SIZEINT 0x200 /* size_t */ 1202 1.78 kleink #define ZEROPAD 0x400 /* zero (as opposed to blank) pad */ 1203 1.78 kleink #define FPT 0x800 /* Floating point number */ 1204 1.45 chuck 1205 1.45 chuck /* 1206 1.45 chuck * To extend shorts properly, we need both signed and unsigned 1207 1.45 chuck * argument extraction methods. 1208 1.45 chuck */ 1209 1.45 chuck #define SARG() \ 1210 1.78 kleink (flags&MAXINT ? va_arg(ap, intmax_t) : \ 1211 1.78 kleink flags&PTRINT ? va_arg(ap, intptr_t) : \ 1212 1.78 kleink flags&SIZEINT ? va_arg(ap, ssize_t) : /* XXX */ \ 1213 1.78 kleink flags&QUADINT ? va_arg(ap, quad_t) : \ 1214 1.45 chuck flags&LONGINT ? va_arg(ap, long) : \ 1215 1.45 chuck flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ 1216 1.45 chuck (long)va_arg(ap, int)) 1217 1.45 chuck #define UARG() \ 1218 1.78 kleink (flags&MAXINT ? va_arg(ap, uintmax_t) : \ 1219 1.78 kleink flags&PTRINT ? va_arg(ap, uintptr_t) : \ 1220 1.78 kleink flags&SIZEINT ? va_arg(ap, size_t) : \ 1221 1.78 kleink flags&QUADINT ? va_arg(ap, u_quad_t) : \ 1222 1.45 chuck flags&LONGINT ? va_arg(ap, u_long) : \ 1223 1.45 chuck flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ 1224 1.45 chuck (u_long)va_arg(ap, u_int)) 1225 1.45 chuck 1226 1.60 explorer #define KPRINTF_PUTCHAR(C) { \ 1227 1.60 explorer if (oflags == TOBUFONLY) { \ 1228 1.148 christos if (sbuf && ((vp == NULL) || (sbuf < tailp))) \ 1229 1.144 christos *sbuf++ = (C); \ 1230 1.60 explorer } else { \ 1231 1.144 christos putchar((C), oflags, vp); \ 1232 1.60 explorer } \ 1233 1.58 msaitoh } 1234 1.45 chuck 1235 1.139 dyoung void 1236 1.139 dyoung device_printf(device_t dev, const char *fmt, ...) 1237 1.139 dyoung { 1238 1.139 dyoung va_list ap; 1239 1.139 dyoung 1240 1.201 riastrad kprintf_lock(); 1241 1.201 riastrad kprintf_internal("%s: ", TOCONS|TOLOG, NULL, NULL, device_xname(dev)); 1242 1.139 dyoung va_start(ap, fmt); 1243 1.201 riastrad kprintf(fmt, TOCONS|TOLOG, NULL, NULL, ap); 1244 1.139 dyoung va_end(ap); 1245 1.201 riastrad kprintf_unlock(); 1246 1.139 dyoung } 1247 1.139 dyoung 1248 1.54 thorpej /* 1249 1.54 thorpej * Guts of kernel printf. Note, we already expect to be in a mutex! 1250 1.54 thorpej */ 1251 1.87 thorpej int 1252 1.99 thorpej kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap) 1253 1.45 chuck { 1254 1.98 christos const char *fmt; /* format string */ 1255 1.45 chuck int ch; /* character from fmt */ 1256 1.45 chuck int n; /* handy integer (short term usage) */ 1257 1.45 chuck char *cp; /* handy char pointer (short term usage) */ 1258 1.45 chuck int flags; /* flags as above */ 1259 1.45 chuck int ret; /* return value accumulator */ 1260 1.45 chuck int width; /* width from format (%8d), or 0 */ 1261 1.45 chuck int prec; /* precision from format (%.3d), or -1 */ 1262 1.45 chuck char sign; /* sign prefix (' ', '+', '-', or \0) */ 1263 1.45 chuck 1264 1.45 chuck u_quad_t _uquad; /* integer arguments %[diouxX] */ 1265 1.45 chuck enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */ 1266 1.45 chuck int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 1267 1.45 chuck int realsz; /* field size expanded by dprec */ 1268 1.45 chuck int size; /* size of converted field or string */ 1269 1.97 christos const char *xdigs; /* digits for [xX] conversion */ 1270 1.98 christos char bf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */ 1271 1.61 explorer char *tailp; /* tail pointer for snprintf */ 1272 1.58 msaitoh 1273 1.60 explorer if (oflags == TOBUFONLY && (vp != NULL)) 1274 1.60 explorer tailp = *(char **)vp; 1275 1.144 christos else 1276 1.144 christos tailp = NULL; 1277 1.45 chuck 1278 1.45 chuck cp = NULL; /* XXX: shutup gcc */ 1279 1.45 chuck size = 0; /* XXX: shutup gcc */ 1280 1.45 chuck 1281 1.98 christos fmt = fmt0; 1282 1.45 chuck ret = 0; 1283 1.45 chuck 1284 1.45 chuck xdigs = NULL; /* XXX: shut up gcc warning */ 1285 1.45 chuck 1286 1.45 chuck /* 1287 1.45 chuck * Scan the format for conversions (`%' character). 1288 1.45 chuck */ 1289 1.45 chuck for (;;) { 1290 1.147 christos for (; *fmt != '%' && *fmt; fmt++) { 1291 1.58 msaitoh ret++; 1292 1.147 christos KPRINTF_PUTCHAR(*fmt); 1293 1.45 chuck } 1294 1.45 chuck if (*fmt == 0) 1295 1.45 chuck goto done; 1296 1.45 chuck 1297 1.45 chuck fmt++; /* skip over '%' */ 1298 1.45 chuck 1299 1.45 chuck flags = 0; 1300 1.45 chuck dprec = 0; 1301 1.45 chuck width = 0; 1302 1.45 chuck prec = -1; 1303 1.45 chuck sign = '\0'; 1304 1.45 chuck 1305 1.45 chuck rflag: ch = *fmt++; 1306 1.45 chuck reswitch: switch (ch) { 1307 1.45 chuck case ' ': 1308 1.45 chuck /* 1309 1.45 chuck * ``If the space and + flags both appear, the space 1310 1.45 chuck * flag will be ignored.'' 1311 1.45 chuck * -- ANSI X3J11 1312 1.45 chuck */ 1313 1.45 chuck if (!sign) 1314 1.45 chuck sign = ' '; 1315 1.45 chuck goto rflag; 1316 1.45 chuck case '#': 1317 1.45 chuck flags |= ALT; 1318 1.45 chuck goto rflag; 1319 1.45 chuck case '*': 1320 1.45 chuck /* 1321 1.45 chuck * ``A negative field width argument is taken as a 1322 1.45 chuck * - flag followed by a positive field width.'' 1323 1.45 chuck * -- ANSI X3J11 1324 1.45 chuck * They don't exclude field widths read from args. 1325 1.45 chuck */ 1326 1.45 chuck if ((width = va_arg(ap, int)) >= 0) 1327 1.45 chuck goto rflag; 1328 1.45 chuck width = -width; 1329 1.45 chuck /* FALLTHROUGH */ 1330 1.45 chuck case '-': 1331 1.45 chuck flags |= LADJUST; 1332 1.45 chuck goto rflag; 1333 1.45 chuck case '+': 1334 1.45 chuck sign = '+'; 1335 1.45 chuck goto rflag; 1336 1.45 chuck case '.': 1337 1.45 chuck if ((ch = *fmt++) == '*') { 1338 1.45 chuck n = va_arg(ap, int); 1339 1.45 chuck prec = n < 0 ? -1 : n; 1340 1.45 chuck goto rflag; 1341 1.45 chuck } 1342 1.45 chuck n = 0; 1343 1.45 chuck while (is_digit(ch)) { 1344 1.45 chuck n = 10 * n + to_digit(ch); 1345 1.45 chuck ch = *fmt++; 1346 1.45 chuck } 1347 1.45 chuck prec = n < 0 ? -1 : n; 1348 1.45 chuck goto reswitch; 1349 1.45 chuck case '0': 1350 1.45 chuck /* 1351 1.45 chuck * ``Note that 0 is taken as a flag, not as the 1352 1.45 chuck * beginning of a field width.'' 1353 1.45 chuck * -- ANSI X3J11 1354 1.45 chuck */ 1355 1.45 chuck flags |= ZEROPAD; 1356 1.45 chuck goto rflag; 1357 1.45 chuck case '1': case '2': case '3': case '4': 1358 1.45 chuck case '5': case '6': case '7': case '8': case '9': 1359 1.45 chuck n = 0; 1360 1.45 chuck do { 1361 1.45 chuck n = 10 * n + to_digit(ch); 1362 1.45 chuck ch = *fmt++; 1363 1.45 chuck } while (is_digit(ch)); 1364 1.45 chuck width = n; 1365 1.45 chuck goto reswitch; 1366 1.45 chuck case 'h': 1367 1.45 chuck flags |= SHORTINT; 1368 1.45 chuck goto rflag; 1369 1.78 kleink case 'j': 1370 1.78 kleink flags |= MAXINT; 1371 1.78 kleink goto rflag; 1372 1.45 chuck case 'l': 1373 1.45 chuck if (*fmt == 'l') { 1374 1.45 chuck fmt++; 1375 1.45 chuck flags |= QUADINT; 1376 1.45 chuck } else { 1377 1.45 chuck flags |= LONGINT; 1378 1.45 chuck } 1379 1.45 chuck goto rflag; 1380 1.45 chuck case 'q': 1381 1.45 chuck flags |= QUADINT; 1382 1.45 chuck goto rflag; 1383 1.78 kleink case 't': 1384 1.78 kleink flags |= PTRINT; 1385 1.78 kleink goto rflag; 1386 1.78 kleink case 'z': 1387 1.78 kleink flags |= SIZEINT; 1388 1.78 kleink goto rflag; 1389 1.45 chuck case 'c': 1390 1.98 christos *(cp = bf) = va_arg(ap, int); 1391 1.45 chuck size = 1; 1392 1.45 chuck sign = '\0'; 1393 1.45 chuck break; 1394 1.45 chuck case 'D': 1395 1.45 chuck flags |= LONGINT; 1396 1.45 chuck /*FALLTHROUGH*/ 1397 1.45 chuck case 'd': 1398 1.45 chuck case 'i': 1399 1.45 chuck _uquad = SARG(); 1400 1.45 chuck if ((quad_t)_uquad < 0) { 1401 1.45 chuck _uquad = -_uquad; 1402 1.45 chuck sign = '-'; 1403 1.45 chuck } 1404 1.45 chuck base = DEC; 1405 1.45 chuck goto number; 1406 1.45 chuck case 'n': 1407 1.185 maxv /* no %n support in the kernel, consume and skip */ 1408 1.78 kleink if (flags & MAXINT) 1409 1.185 maxv (void)va_arg(ap, intmax_t *); 1410 1.78 kleink else if (flags & PTRINT) 1411 1.185 maxv (void)va_arg(ap, intptr_t *); 1412 1.78 kleink else if (flags & SIZEINT) 1413 1.185 maxv (void)va_arg(ap, ssize_t *); 1414 1.78 kleink else if (flags & QUADINT) 1415 1.185 maxv (void)va_arg(ap, quad_t *); 1416 1.45 chuck else if (flags & LONGINT) 1417 1.185 maxv (void)va_arg(ap, long *); 1418 1.45 chuck else if (flags & SHORTINT) 1419 1.185 maxv (void)va_arg(ap, short *); 1420 1.45 chuck else 1421 1.185 maxv (void)va_arg(ap, int *); 1422 1.45 chuck continue; /* no output */ 1423 1.45 chuck case 'O': 1424 1.45 chuck flags |= LONGINT; 1425 1.45 chuck /*FALLTHROUGH*/ 1426 1.45 chuck case 'o': 1427 1.45 chuck _uquad = UARG(); 1428 1.45 chuck base = OCT; 1429 1.45 chuck goto nosign; 1430 1.45 chuck case 'p': 1431 1.45 chuck /* 1432 1.45 chuck * ``The argument shall be a pointer to void. The 1433 1.45 chuck * value of the pointer is converted to a sequence 1434 1.45 chuck * of printable characters, in an implementation- 1435 1.45 chuck * defined manner.'' 1436 1.45 chuck * -- ANSI X3J11 1437 1.45 chuck */ 1438 1.45 chuck /* NOSTRICT */ 1439 1.45 chuck _uquad = (u_long)va_arg(ap, void *); 1440 1.45 chuck base = HEX; 1441 1.97 christos xdigs = hexdigits; 1442 1.45 chuck flags |= HEXPREFIX; 1443 1.45 chuck ch = 'x'; 1444 1.45 chuck goto nosign; 1445 1.45 chuck case 's': 1446 1.45 chuck if ((cp = va_arg(ap, char *)) == NULL) 1447 1.98 christos /*XXXUNCONST*/ 1448 1.98 christos cp = __UNCONST("(null)"); 1449 1.45 chuck if (prec >= 0) { 1450 1.45 chuck /* 1451 1.45 chuck * can't use strlen; can only look for the 1452 1.45 chuck * NUL in the first `prec' characters, and 1453 1.45 chuck * strlen() will go further. 1454 1.45 chuck */ 1455 1.45 chuck char *p = memchr(cp, 0, prec); 1456 1.45 chuck 1457 1.45 chuck if (p != NULL) { 1458 1.45 chuck size = p - cp; 1459 1.45 chuck if (size > prec) 1460 1.45 chuck size = prec; 1461 1.45 chuck } else 1462 1.45 chuck size = prec; 1463 1.45 chuck } else 1464 1.45 chuck size = strlen(cp); 1465 1.45 chuck sign = '\0'; 1466 1.45 chuck break; 1467 1.45 chuck case 'U': 1468 1.45 chuck flags |= LONGINT; 1469 1.45 chuck /*FALLTHROUGH*/ 1470 1.45 chuck case 'u': 1471 1.45 chuck _uquad = UARG(); 1472 1.45 chuck base = DEC; 1473 1.45 chuck goto nosign; 1474 1.45 chuck case 'X': 1475 1.103 martin xdigs = HEXDIGITS; 1476 1.45 chuck goto hex; 1477 1.45 chuck case 'x': 1478 1.97 christos xdigs = hexdigits; 1479 1.45 chuck hex: _uquad = UARG(); 1480 1.45 chuck base = HEX; 1481 1.45 chuck /* leading 0x/X only if non-zero */ 1482 1.45 chuck if (flags & ALT && _uquad != 0) 1483 1.45 chuck flags |= HEXPREFIX; 1484 1.45 chuck 1485 1.45 chuck /* unsigned conversions */ 1486 1.45 chuck nosign: sign = '\0'; 1487 1.45 chuck /* 1488 1.45 chuck * ``... diouXx conversions ... if a precision is 1489 1.45 chuck * specified, the 0 flag will be ignored.'' 1490 1.45 chuck * -- ANSI X3J11 1491 1.45 chuck */ 1492 1.45 chuck number: if ((dprec = prec) >= 0) 1493 1.45 chuck flags &= ~ZEROPAD; 1494 1.45 chuck 1495 1.45 chuck /* 1496 1.45 chuck * ``The result of converting a zero value with an 1497 1.45 chuck * explicit precision of zero is no characters.'' 1498 1.45 chuck * -- ANSI X3J11 1499 1.45 chuck */ 1500 1.98 christos cp = bf + KPRINTF_BUFSIZE; 1501 1.45 chuck if (_uquad != 0 || prec != 0) { 1502 1.45 chuck /* 1503 1.45 chuck * Unsigned mod is hard, and unsigned mod 1504 1.45 chuck * by a constant is easier than that by 1505 1.45 chuck * a variable; hence this switch. 1506 1.45 chuck */ 1507 1.45 chuck switch (base) { 1508 1.45 chuck case OCT: 1509 1.45 chuck do { 1510 1.45 chuck *--cp = to_char(_uquad & 7); 1511 1.45 chuck _uquad >>= 3; 1512 1.45 chuck } while (_uquad); 1513 1.45 chuck /* handle octal leading 0 */ 1514 1.45 chuck if (flags & ALT && *cp != '0') 1515 1.45 chuck *--cp = '0'; 1516 1.45 chuck break; 1517 1.45 chuck 1518 1.45 chuck case DEC: 1519 1.45 chuck /* many numbers are 1 digit */ 1520 1.45 chuck while (_uquad >= 10) { 1521 1.45 chuck *--cp = to_char(_uquad % 10); 1522 1.45 chuck _uquad /= 10; 1523 1.45 chuck } 1524 1.45 chuck *--cp = to_char(_uquad); 1525 1.45 chuck break; 1526 1.45 chuck 1527 1.45 chuck case HEX: 1528 1.45 chuck do { 1529 1.45 chuck *--cp = xdigs[_uquad & 15]; 1530 1.45 chuck _uquad >>= 4; 1531 1.45 chuck } while (_uquad); 1532 1.45 chuck break; 1533 1.45 chuck 1534 1.45 chuck default: 1535 1.98 christos /*XXXUNCONST*/ 1536 1.98 christos cp = __UNCONST("bug in kprintf: bad base"); 1537 1.45 chuck size = strlen(cp); 1538 1.45 chuck goto skipsize; 1539 1.45 chuck } 1540 1.45 chuck } 1541 1.98 christos size = bf + KPRINTF_BUFSIZE - cp; 1542 1.45 chuck skipsize: 1543 1.45 chuck break; 1544 1.45 chuck default: /* "%?" prints ?, unless ? is NUL */ 1545 1.45 chuck if (ch == '\0') 1546 1.45 chuck goto done; 1547 1.45 chuck /* pretend it was %c with argument ch */ 1548 1.98 christos cp = bf; 1549 1.45 chuck *cp = ch; 1550 1.45 chuck size = 1; 1551 1.45 chuck sign = '\0'; 1552 1.45 chuck break; 1553 1.45 chuck } 1554 1.45 chuck 1555 1.45 chuck /* 1556 1.45 chuck * All reasonable formats wind up here. At this point, `cp' 1557 1.45 chuck * points to a string which (if not flags&LADJUST) should be 1558 1.45 chuck * padded out to `width' places. If flags&ZEROPAD, it should 1559 1.45 chuck * first be prefixed by any sign or other prefix; otherwise, 1560 1.45 chuck * it should be blank padded before the prefix is emitted. 1561 1.45 chuck * After any left-hand padding and prefixing, emit zeroes 1562 1.45 chuck * required by a decimal [diouxX] precision, then print the 1563 1.45 chuck * string proper, then emit zeroes required by any leftover 1564 1.45 chuck * floating precision; finally, if LADJUST, pad with blanks. 1565 1.45 chuck * 1566 1.45 chuck * Compute actual size, so we know how much to pad. 1567 1.45 chuck * size excludes decimal prec; realsz includes it. 1568 1.45 chuck */ 1569 1.45 chuck realsz = dprec > size ? dprec : size; 1570 1.45 chuck if (sign) 1571 1.45 chuck realsz++; 1572 1.45 chuck else if (flags & HEXPREFIX) 1573 1.45 chuck realsz+= 2; 1574 1.45 chuck 1575 1.58 msaitoh /* adjust ret */ 1576 1.58 msaitoh ret += width > realsz ? width : realsz; 1577 1.58 msaitoh 1578 1.45 chuck /* right-adjusting blank padding */ 1579 1.45 chuck if ((flags & (LADJUST|ZEROPAD)) == 0) { 1580 1.45 chuck n = width - realsz; 1581 1.45 chuck while (n-- > 0) 1582 1.45 chuck KPRINTF_PUTCHAR(' '); 1583 1.45 chuck } 1584 1.45 chuck 1585 1.45 chuck /* prefix */ 1586 1.45 chuck if (sign) { 1587 1.45 chuck KPRINTF_PUTCHAR(sign); 1588 1.45 chuck } else if (flags & HEXPREFIX) { 1589 1.45 chuck KPRINTF_PUTCHAR('0'); 1590 1.45 chuck KPRINTF_PUTCHAR(ch); 1591 1.45 chuck } 1592 1.45 chuck 1593 1.45 chuck /* right-adjusting zero padding */ 1594 1.45 chuck if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) { 1595 1.45 chuck n = width - realsz; 1596 1.45 chuck while (n-- > 0) 1597 1.45 chuck KPRINTF_PUTCHAR('0'); 1598 1.45 chuck } 1599 1.45 chuck 1600 1.45 chuck /* leading zeroes from decimal precision */ 1601 1.45 chuck n = dprec - size; 1602 1.45 chuck while (n-- > 0) 1603 1.45 chuck KPRINTF_PUTCHAR('0'); 1604 1.45 chuck 1605 1.45 chuck /* the string or number proper */ 1606 1.147 christos for (; size--; cp++) 1607 1.147 christos KPRINTF_PUTCHAR(*cp); 1608 1.45 chuck /* left-adjusting padding (always blank) */ 1609 1.45 chuck if (flags & LADJUST) { 1610 1.45 chuck n = width - realsz; 1611 1.45 chuck while (n-- > 0) 1612 1.45 chuck KPRINTF_PUTCHAR(' '); 1613 1.45 chuck } 1614 1.58 msaitoh } 1615 1.45 chuck 1616 1.45 chuck done: 1617 1.58 msaitoh if ((oflags == TOBUFONLY) && (vp != NULL)) 1618 1.58 msaitoh *(char **)vp = sbuf; 1619 1.92 matt (*v_flush)(); 1620 1.154 tls 1621 1.154 tls #ifdef RND_PRINTF 1622 1.183 riastrad if (__predict_true(kprintf_inited)) 1623 1.202 riastrad rnd_add_data_intr(&rnd_printf_source, NULL, 0, 0); 1624 1.154 tls #endif 1625 1.144 christos return ret; 1626 1.12 cgd } 1627