1106191Smini/*- 2106191Smini * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org> 3106191Smini * All rights reserved. 4106191Smini * 5106191Smini * Redistribution and use in source and binary forms, with or without 6106191Smini * modification, are permitted provided that the following conditions 7106191Smini * are met: 8106191Smini * 1. Redistributions of source code must retain the above copyright 9106191Smini * notice, this list of conditions and the following disclaimer. 10106191Smini * 2. Redistributions in binary form must reproduce the above copyright 11106191Smini * notice, this list of conditions and the following disclaimer in the 12106191Smini * documentation and/or other materials provided with the distribution. 13106191Smini * 14106191Smini * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15106191Smini * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16106191Smini * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17106191Smini * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18106191Smini * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19106191Smini * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20106191Smini * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21106191Smini * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22106191Smini * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23106191Smini * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24106191Smini * SUCH DAMAGE. 25106191Smini */ 26106191Smini 27106191Smini#include <sys/cdefs.h> 28106191Smini__FBSDID("$FreeBSD: releng/10.3/lib/libkse/thread/thr_printf.c 125668 2004-02-10 20:42:33Z cperciva $"); 29106191Smini 30106191Smini#include <stdarg.h> 31113658Sdeischen#include <string.h> 32106191Smini#include <unistd.h> 33106191Smini 34106191Smini#include "thr_private.h" 35106191Smini 36106191Sministatic void pchar(int fd, char c); 37106191Sministatic void pstr(int fd, const char *s); 38106191Smini 39106191Smini/* 40106191Smini * Write formatted output to stdout, in a thread-safe manner. 41106191Smini * 42106191Smini * Recognises the following conversions: 43106191Smini * %c -> char 44106191Smini * %d -> signed int (base 10) 45106191Smini * %s -> string 46106191Smini * %u -> unsigned int (base 10) 47106191Smini * %x -> unsigned int (base 16) 48106191Smini * %p -> unsigned int (base 16) 49106191Smini */ 50106191Sminivoid 51106191Smini_thread_printf(int fd, const char *fmt, ...) 52106191Smini{ 53106191Smini static const char digits[16] = "0123456789abcdef"; 54106191Smini va_list ap; 55119117Sdavidxu char buf[20]; 56106191Smini char *s; 57119117Sdavidxu unsigned long r, u; 58119117Sdavidxu int c; 59119117Sdavidxu long d; 60119117Sdavidxu int islong; 61106191Smini 62106191Smini va_start(ap, fmt); 63106191Smini while ((c = *fmt++)) { 64119117Sdavidxu islong = 0; 65106191Smini if (c == '%') { 66119117Sdavidxunext: c = *fmt++; 67119117Sdavidxu if (c == '\0') 68119117Sdavidxu goto out; 69106191Smini switch (c) { 70106191Smini case 'c': 71106191Smini pchar(fd, va_arg(ap, int)); 72106191Smini continue; 73106191Smini case 's': 74106191Smini pstr(fd, va_arg(ap, char *)); 75106191Smini continue; 76119117Sdavidxu case 'l': 77119117Sdavidxu islong = 1; 78119117Sdavidxu goto next; 79119117Sdavidxu case 'p': 80119117Sdavidxu islong = 1; 81106191Smini case 'd': 82106191Smini case 'u': 83106191Smini case 'x': 84106191Smini r = ((c == 'u') || (c == 'd')) ? 10 : 16; 85106191Smini if (c == 'd') { 86119117Sdavidxu if (islong) 87119117Sdavidxu d = va_arg(ap, unsigned long); 88119117Sdavidxu else 89119117Sdavidxu d = va_arg(ap, unsigned); 90106191Smini if (d < 0) { 91106191Smini pchar(fd, '-'); 92119117Sdavidxu u = (unsigned long)(d * -1); 93106191Smini } else 94119117Sdavidxu u = (unsigned long)d; 95119117Sdavidxu } else { 96119117Sdavidxu if (islong) 97119117Sdavidxu u = va_arg(ap, unsigned long); 98119117Sdavidxu else 99119117Sdavidxu u = va_arg(ap, unsigned); 100119117Sdavidxu } 101106191Smini s = buf; 102106191Smini do { 103106191Smini *s++ = digits[u % r]; 104106191Smini } while (u /= r); 105106191Smini while (--s >= buf) 106106191Smini pchar(fd, *s); 107106191Smini continue; 108106191Smini } 109106191Smini } 110106191Smini pchar(fd, c); 111106191Smini } 112119117Sdavidxuout: 113106191Smini va_end(ap); 114106191Smini} 115106191Smini 116106191Smini/* 117106191Smini * Write a single character to stdout, in a thread-safe manner. 118106191Smini */ 119106191Sministatic void 120106191Sminipchar(int fd, char c) 121106191Smini{ 122106191Smini 123113658Sdeischen __sys_write(fd, &c, 1); 124106191Smini} 125106191Smini 126106191Smini/* 127106191Smini * Write a string to stdout, in a thread-safe manner. 128106191Smini */ 129106191Sministatic void 130106191Sminipstr(int fd, const char *s) 131106191Smini{ 132106191Smini 133113658Sdeischen __sys_write(fd, s, strlen(s)); 134106191Smini} 135106191Smini 136