thr_printf.c revision 276630
1181344Sdfr/*-
2181344Sdfr * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org>
3181344Sdfr * All rights reserved.
4181344Sdfr *
5181344Sdfr * Redistribution and use in source and binary forms, with or without
6181344Sdfr * modification, are permitted provided that the following conditions
7181344Sdfr * are met:
8181344Sdfr * 1. Redistributions of source code must retain the above copyright
9181344Sdfr *    notice, this list of conditions and the following disclaimer.
10181344Sdfr * 2. Redistributions in binary form must reproduce the above copyright
11181344Sdfr *    notice, this list of conditions and the following disclaimer in the
12181344Sdfr *    documentation and/or other materials provided with the distribution.
13181344Sdfr *
14181344Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15181344Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16181344Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17181344Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18181344Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19181344Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20181344Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21181344Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22181344Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23181344Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24181344Sdfr * SUCH DAMAGE.
25181344Sdfr *
26181344Sdfr * $FreeBSD: head/lib/libthr/thread/thr_printf.c 276630 2015-01-03 18:38:46Z kib $
27181344Sdfr */
28181344Sdfr
29181344Sdfr#include <stdarg.h>
30181344Sdfr#include <string.h>
31181344Sdfr#include <unistd.h>
32181344Sdfr#include <pthread.h>
33181344Sdfr
34181344Sdfr#include "libc_private.h"
35181344Sdfr#include "thr_private.h"
36181344Sdfr
37181344Sdfrstatic void	pchar(int fd, char c);
38181344Sdfrstatic void	pstr(int fd, const char *s);
39181344Sdfr
40181344Sdfr/*
41181344Sdfr * Write formatted output to stdout, in a thread-safe manner.
42181344Sdfr *
43181344Sdfr * Recognises the following conversions:
44181344Sdfr *	%c	-> char
45181344Sdfr *	%d	-> signed int (base 10)
46181344Sdfr *	%s	-> string
47181344Sdfr *	%u	-> unsigned int (base 10)
48181344Sdfr *	%x	-> unsigned int (base 16)
49181344Sdfr *	%p	-> unsigned int (base 16)
50181344Sdfr */
51181344Sdfrvoid
52181344Sdfr_thread_printf(int fd, const char *fmt, ...)
53181344Sdfr{
54181344Sdfr	static const char digits[16] = "0123456789abcdef";
55181344Sdfr	va_list	 ap;
56181344Sdfr	char buf[20];
57181344Sdfr	char *s;
58181344Sdfr	unsigned long r, u;
59181344Sdfr	int c;
60181344Sdfr	long d;
61181344Sdfr	int islong;
62181344Sdfr
63181344Sdfr	va_start(ap, fmt);
64181344Sdfr	while ((c = *fmt++)) {
65181344Sdfr		islong = 0;
66181344Sdfr		if (c == '%') {
67181344Sdfrnext:			c = *fmt++;
68181344Sdfr			if (c == '\0')
69181344Sdfr				goto out;
70181344Sdfr			switch (c) {
71181344Sdfr			case 'c':
72181344Sdfr				pchar(fd, va_arg(ap, int));
73181344Sdfr				continue;
74181344Sdfr			case 's':
75181344Sdfr				pstr(fd, va_arg(ap, char *));
76181344Sdfr				continue;
77181344Sdfr			case 'l':
78181344Sdfr				islong = 1;
79181344Sdfr				goto next;
80181344Sdfr			case 'p':
81181344Sdfr				islong = 1;
82181344Sdfr			case 'd':
83181344Sdfr			case 'u':
84181344Sdfr			case 'x':
85181344Sdfr				r = ((c == 'u') || (c == 'd')) ? 10 : 16;
86181344Sdfr				if (c == 'd') {
87181344Sdfr					if (islong)
88181344Sdfr						d = va_arg(ap, unsigned long);
89181344Sdfr					else
90181344Sdfr						d = va_arg(ap, unsigned);
91181344Sdfr					if (d < 0) {
92181344Sdfr						pchar(fd, '-');
93181344Sdfr						u = (unsigned long)(d * -1);
94181344Sdfr					} else
95181344Sdfr						u = (unsigned long)d;
96				} else {
97					if (islong)
98						u = va_arg(ap, unsigned long);
99					else
100						u = va_arg(ap, unsigned);
101				}
102				s = buf;
103				do {
104					*s++ = digits[u % r];
105				} while (u /= r);
106				while (--s >= buf)
107					pchar(fd, *s);
108				continue;
109			}
110		}
111		pchar(fd, c);
112	}
113out:
114	va_end(ap);
115}
116
117/*
118 * Write a single character to stdout, in a thread-safe manner.
119 */
120static void
121pchar(int fd, char c)
122{
123
124	__sys_write(fd, &c, 1);
125}
126
127/*
128 * Write a string to stdout, in a thread-safe manner.
129 */
130static void
131pstr(int fd, const char *s)
132{
133
134	__sys_write(fd, s, strlen(s));
135}
136
137