thr_printf.c revision 277317
172169Sphantom/*- 2116875Sphantom * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org> 372169Sphantom * All rights reserved. 472169Sphantom * 5227753Stheraven * Redistribution and use in source and binary forms, with or without 6227753Stheraven * modification, are permitted provided that the following conditions 7227753Stheraven * are met: 8227753Stheraven * 1. Redistributions of source code must retain the above copyright 9227753Stheraven * notice, this list of conditions and the following disclaimer. 1072169Sphantom * 2. Redistributions in binary form must reproduce the above copyright 1172169Sphantom * notice, this list of conditions and the following disclaimer in the 1272169Sphantom * documentation and/or other materials provided with the distribution. 1372169Sphantom * 1472169Sphantom * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1572169Sphantom * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1672169Sphantom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1772169Sphantom * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1872169Sphantom * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1972169Sphantom * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2072169Sphantom * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2172169Sphantom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2272169Sphantom * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2372169Sphantom * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2472169Sphantom * SUCH DAMAGE. 2572169Sphantom * 2672169Sphantom * $FreeBSD: stable/10/lib/libthr/thread/thr_printf.c 277317 2015-01-18 11:54:20Z kib $ 2772169Sphantom */ 2872169Sphantom 2972169Sphantom#include <stdarg.h> 3072169Sphantom#include <string.h> 3172169Sphantom#include <unistd.h> 3292986Sobrien#include <pthread.h> 3392986Sobrien 3492986Sobrien#include "libc_private.h" 3572263Sache#include "thr_private.h" 3672561Sache 37116875Sphantomstatic void pchar(int fd, char c); 3872561Sachestatic void pstr(int fd, const char *s); 3972263Sache 4087658Sphantom/* 4172169Sphantom * Write formatted output to stdout, in a thread-safe manner. 42116875Sphantom * 4372169Sphantom * Recognises the following conversions: 44116875Sphantom * %c -> char 4572169Sphantom * %d -> signed int (base 10) 4672169Sphantom * %s -> string 4772169Sphantom * %u -> unsigned int (base 10) 4872169Sphantom * %x -> unsigned int (base 16) 49227753Stheraven * %p -> unsigned int (base 16) 50116875Sphantom */ 51227753Stheravenvoid 52227753Stheraven_thread_printf(int fd, const char *fmt, ...) 53227753Stheraven{ 5472169Sphantom static const char digits[16] = "0123456789abcdef"; 5572169Sphantom va_list ap; 5672169Sphantom char buf[20]; 5772263Sache char *s; 58227753Stheraven unsigned long r, u; 59116134Sache int c; 6072263Sache long d; 61116134Sache int islong; 62116134Sache 6372263Sache va_start(ap, fmt); 6472263Sache while ((c = *fmt++)) { 6572169Sphantom islong = 0; 6672169Sphantom if (c == '%') { 67227753Stheravennext: c = *fmt++; 6872169Sphantom if (c == '\0') 6972169Sphantom goto out; 70227753Stheraven switch (c) { 7172169Sphantom case 'c': 7272169Sphantom pchar(fd, va_arg(ap, int)); 73227753Stheraven continue; 7472169Sphantom case 's': 7572169Sphantom pstr(fd, va_arg(ap, char *)); 76227753Stheraven continue; 7772169Sphantom case 'l': 7872169Sphantom islong = 1; 79227753Stheraven goto next; 8072169Sphantom case 'p': 8172169Sphantom islong = 1; 82227753Stheraven case 'd': 8372169Sphantom case 'u': 8472169Sphantom case 'x': 8572169Sphantom r = ((c == 'u') || (c == 'd')) ? 10 : 16; 86227753Stheraven if (c == 'd') { 8772169Sphantom if (islong) 8872169Sphantom d = va_arg(ap, unsigned long); 8972169Sphantom else 90227753Stheraven d = va_arg(ap, unsigned); 9172169Sphantom if (d < 0) { 9272169Sphantom pchar(fd, '-'); 9372169Sphantom u = (unsigned long)(d * -1); 9472169Sphantom } else 95227753Stheraven u = (unsigned long)d; 9672169Sphantom } else { 9772169Sphantom if (islong) 9872169Sphantom u = va_arg(ap, unsigned long); 9972169Sphantom else 100227753Stheraven u = va_arg(ap, unsigned); 10172169Sphantom } 102197765Sedwin s = buf; 103197765Sedwin do { 104197765Sedwin *s++ = digits[u % r]; 105197765Sedwin } while (u /= r); 106227753Stheraven while (--s >= buf) 107197765Sedwin pchar(fd, *s); 10872169Sphantom continue; 10972706Sphantom } 11072169Sphantom } 11172169Sphantom pchar(fd, c); 11272169Sphantom } 11372706Sphantomout: 11472169Sphantom va_end(ap); 11572169Sphantom} 11672169Sphantom 11772706Sphantom/* 11872169Sphantom * Write a single character to stdout, in a thread-safe manner. 11972169Sphantom */ 12072169Sphantomstatic void 12172706Sphantompchar(int fd, char c) 12272169Sphantom{ 12372169Sphantom 12472169Sphantom __sys_write(fd, &c, 1); 12572706Sphantom} 12672169Sphantom 12772169Sphantom/* 12872706Sphantom * Write a string to stdout, in a thread-safe manner. 129227753Stheraven */ 13072169Sphantomstatic void 13172706Sphantompstr(int fd, const char *s) 132227753Stheraven{ 13372169Sphantom 13472169Sphantom __sys_write(fd, s, strlen(s)); 135227753Stheraven} 13672169Sphantom 13772169Sphantom