thr_printf.c revision 115260
1261363Sgshapiro/*-
290792Sgshapiro * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org>
390792Sgshapiro * All rights reserved.
490792Sgshapiro *
590792Sgshapiro * Redistribution and use in source and binary forms, with or without
690792Sgshapiro * modification, are permitted provided that the following conditions
790792Sgshapiro * are met:
8266692Sgshapiro * 1. Redistributions of source code must retain the above copyright
990792Sgshapiro *    notice, this list of conditions and the following disclaimer.
1090792Sgshapiro * 2. Redistributions in binary form must reproduce the above copyright
1190792Sgshapiro *    notice, this list of conditions and the following disclaimer in the
1290792Sgshapiro *    documentation and/or other materials provided with the distribution.
1390792Sgshapiro *
1490792Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1590792Sgshapiro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1690792Sgshapiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1790792Sgshapiro * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1890792Sgshapiro * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1990792Sgshapiro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2090792Sgshapiro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2190792Sgshapiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2290792Sgshapiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2390792Sgshapiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2490792Sgshapiro * SUCH DAMAGE.
2590792Sgshapiro *
2690792Sgshapiro * $FreeBSD: head/lib/libthr/thread/thr_printf.c 115260 2003-05-23 09:48:20Z mtm $
2790792Sgshapiro */
2890792Sgshapiro
2990792Sgshapiro#include <sys/cdefs.h>
3090792Sgshapiro__FBSDID("$FreeBSD: head/lib/libthr/thread/thr_printf.c 115260 2003-05-23 09:48:20Z mtm $");
3190792Sgshapiro
3290792Sgshapiro#include <sys/types.h>
3390792Sgshapiro#include <sys/fcntl.h>
3490792Sgshapiro#include <sys/uio.h>
3590792Sgshapiro#include <errno.h>
3690792Sgshapiro#include <stdarg.h>
3790792Sgshapiro#include <string.h>
3890792Sgshapiro#include <unistd.h>
3990792Sgshapiro#include <pthread.h>
4090792Sgshapiro
4190792Sgshapiro#include "thr_private.h"
4290792Sgshapiro
4390792Sgshapirostatic void	pchar(int fd, char c);
4490792Sgshapirostatic void	pstr(int fd, const char *s);
4590792Sgshapiro
4690792Sgshapiro/*
4790792Sgshapiro * Write formatted output to stdout, in a thread-safe manner.
4890792Sgshapiro *
4990792Sgshapiro * Recognises the following conversions:
5090792Sgshapiro *	%c	-> char
5190792Sgshapiro *	%d	-> signed int (base 10)
5290792Sgshapiro *	%s	-> string
5390792Sgshapiro *	%u	-> unsigned int (base 10)
5490792Sgshapiro *	%x	-> unsigned int (base 16)
5590792Sgshapiro *	%p	-> unsigned int (base 16)
5690792Sgshapiro */
5790792Sgshapirovoid
5890792Sgshapiro_thread_printf(int fd, const char *fmt, ...)
5990792Sgshapiro{
6090792Sgshapiro	static const char digits[16] = "0123456789abcdef";
6190792Sgshapiro	va_list	 ap;
6290792Sgshapiro	char buf[10];
6390792Sgshapiro	char *s;
6494334Sgshapiro	unsigned r, u;
6594334Sgshapiro	int c, d;
6694334Sgshapiro
6790792Sgshapiro	va_start(ap, fmt);
6890792Sgshapiro	while ((c = *fmt++)) {
6990792Sgshapiro		if (c == '%') {
7090792Sgshapiro			c = *fmt++;
7190792Sgshapiro			switch (c) {
7290792Sgshapiro			case 'c':
7390792Sgshapiro				pchar(fd, va_arg(ap, int));
7490792Sgshapiro				continue;
7590792Sgshapiro			case 's':
7690792Sgshapiro				pstr(fd, va_arg(ap, char *));
7790792Sgshapiro				continue;
7890792Sgshapiro			case 'd':
7990792Sgshapiro			case 'u':
8090792Sgshapiro			case 'p':
8190792Sgshapiro			case 'x':
8290792Sgshapiro				r = ((c == 'u') || (c == 'd')) ? 10 : 16;
8390792Sgshapiro				if (c == 'd') {
8490792Sgshapiro					d = va_arg(ap, unsigned);
8590792Sgshapiro					if (d < 0) {
8690792Sgshapiro						pchar(fd, '-');
8790792Sgshapiro						u = (unsigned)(d * -1);
8890792Sgshapiro					} else
8990792Sgshapiro						u = (unsigned)d;
9090792Sgshapiro				} else
9190792Sgshapiro					u = va_arg(ap, unsigned);
9290792Sgshapiro				s = buf;
9390792Sgshapiro				do {
9490792Sgshapiro					*s++ = digits[u % r];
9590792Sgshapiro				} while (u /= r);
9690792Sgshapiro				while (--s >= buf)
9790792Sgshapiro					pchar(fd, *s);
9890792Sgshapiro				continue;
9990792Sgshapiro			}
10090792Sgshapiro		}
10190792Sgshapiro		pchar(fd, c);
10290792Sgshapiro	}
10390792Sgshapiro	va_end(ap);
10490792Sgshapiro}
10590792Sgshapiro
10690792Sgshapiro/*
10790792Sgshapiro * Write a single character to stdout, in a thread-safe manner.
10890792Sgshapiro */
10990792Sgshapirostatic void
11090792Sgshapiropchar(int fd, char c)
11190792Sgshapiro{
11290792Sgshapiro
11390792Sgshapiro	write(fd, &c, 1);
11490792Sgshapiro}
11590792Sgshapiro
11690792Sgshapiro/*
11790792Sgshapiro * Write a string to stdout, in a thread-safe manner.
11890792Sgshapiro */
11990792Sgshapirostatic void
12090792Sgshapiropstr(int fd, const char *s)
12190792Sgshapiro{
12290792Sgshapiro
12390792Sgshapiro	write(fd, s, strlen(s));
12490792Sgshapiro}
12590792Sgshapiro
12690792Sgshapiro