xref: /titanic_52/usr/src/cmd/sgs/rtld.4.x/rtsubrs.c (revision 4a5d661a82b942b6538acd26209d959ce98b593a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 #pragma ident	"%Z%%M%	%I%	%E% SMI"
23 
24 /*
25  * Copyright (c) 1987, 1988, 1989, 1990 by Sun Microsystems, Inc.
26  */
27 
28 /*	Copyright (c) 1988 AT&T	*/
29 /*	All Rights Reserved	*/
30 
31 /*
32  * Subroutines for the 4.0 compatibility run-time link editor.
33  */
34 #include <varargs.h>
35 #include <sys/types.h>
36 
37 /*
38  * Local "printf" & stdio facilities.
39  */
40 int	stdout = 1;			/* File descriptor for output */
41 int	stderr = 2;			/* File descriptor for errors */
42 
43 static char *printn();
44 static void prf();
45 static void doprf();
46 static int _write();
47 
48 /*
49  * printf
50  */
51 /*VARARGS1*/
52 printf(fmt, va_alist)
53 	char *fmt;
54 	va_dcl
55 {
56 	va_list x1;
57 
58 	va_start(x1);
59 	prf(stdout, fmt, x1);
60 	va_end(x1);
61 }
62 
63 /*
64  * fprintf
65  */
66 /*VARARGS2*/
67 fprintf(fd, fmt, va_alist)
68 	int fd;
69 	char *fmt;
70 	va_dcl
71 {
72 	va_list x1;
73 
74 	va_start(x1);
75 	prf(fd, fmt, x1);
76 	va_end(x1);
77 }
78 
79 /*
80  * panic
81  */
82 /*VARARGS2*/
83 panic(fmt, va_alist)
84 	char *fmt;
85 	va_dcl
86 {
87 	va_list x1;
88 	extern char *program_name;
89 
90 	va_start(x1);
91 	prf(stderr, "%s (4.x.ld.so): ", program_name);
92 	prf(stderr, fmt, x1);
93 	prf(stderr, "\n", x1);
94 	va_end(x1);
95 	_exit(127);
96 	/* NOTREACHED */
97 }
98 
99 /*
100  * sprintf
101  */
102 /*VARARGS2*/
103 sprintf(cp, fmt, va_alist)
104 	char *cp;
105 	char *fmt;
106 	va_dcl
107 {
108 	va_list x1;
109 
110 	va_start(x1);
111 	doprf(-1, fmt, x1, cp);
112 	va_end(x1);
113 }
114 
115 /*
116  * printf worker functions
117  */
118 static void
119 prf(fd, fmt, adx)
120 	int fd;
121 	char *fmt;
122 	va_list adx;
123 {
124 	char linebuf[128];
125 
126 	doprf(fd, fmt, adx, linebuf);
127 }
128 
129 static void
130 doprf(fd, fmt, adx, linebuf)
131 	int fd;
132 	register char *fmt;
133 	register va_list adx;
134 	char *linebuf;
135 {
136 	register int c;			/* Character temporary */
137 	register char *lbp;		/* Pointer into stack buffer */
138 	register char *s;		/* %s temporary */
139 	int i;				/* General integer temporary */
140 	int b;				/* Conversion base */
141 
142 #define	PUTCHAR(c)	{ \
143 			if (lbp >= &linebuf[128]) { \
144 				_write(fd, linebuf, lbp - &linebuf[0]); \
145 				lbp = &linebuf[0]; \
146 			} \
147 			*lbp++ = (c); \
148 			}
149 
150 	lbp = &linebuf[0];
151 loop:
152 	while ((c = *fmt++) != '%') {
153 		if (c == '\0') {
154 			_write(fd, linebuf, lbp - &linebuf[0]);
155 			return;
156 		}
157 		PUTCHAR(c);
158 	}
159 again:
160 	c = *fmt++;
161 	/* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
162 	switch (c) {
163 
164 	case 'x': case 'X':
165 		b = 16;
166 		goto number;
167 	case 'd': case 'D':
168 	case 'u':		/* what a joke */
169 		b = 10;
170 		goto number;
171 	case 'o': case 'O':
172 		b = 8;
173 number:
174 		lbp = printn(fd, va_arg(adx, u_long), b, &linebuf[0], lbp,
175 		    &linebuf[128]);
176 		break;
177 
178 	case 'c':
179 		b = va_arg(adx, int);
180 		for (i = 24; i >= 0; i -= 8)
181 			if (c = (b >> i) & 0x7f) {
182 				PUTCHAR(c);
183 			}
184 		break;
185 
186 	case 's':
187 		s = va_arg(adx, char *);
188 		while (c = *s++) {
189 			PUTCHAR(c);
190 		}
191 		break;
192 
193 	case '%':
194 		PUTCHAR('%');
195 		break;
196 	}
197 	goto loop;
198 }
199 
200 /*
201  * Printn prints a number n in base b.
202  */
203 static char *
204 printn(fd, n, b, linebufp, lbp, linebufend)
205 	int fd;				/* File descriptor to get output */
206 	u_long n;			/* Number */
207 	int b;				/* Base */
208 	char *linebufp;			/* Buffer location */
209 	register char *lbp;		/* Current offset in buffer */
210 	char *linebufend;		/* Where buffer ends */
211 {
212 	char prbuf[11];			/* Local result accumulator */
213 	register char *cp;
214 
215 #undef PUTCHAR
216 #define	PUTCHAR(c)	{ \
217 			if (lbp >= linebufend) { \
218 				_write(fd, linebufp, lbp - linebufp); \
219 				lbp = linebufp; \
220 			} \
221 			*lbp++ = (c); \
222 			}
223 
224 	if (b == 10 && (int)n < 0) {
225 		PUTCHAR('-');
226 		n = (unsigned)(-(int)n);
227 	}
228 	cp = prbuf;
229 	do {
230 		*cp++ = "0123456789abcdef"[n%b];
231 		n /= b;
232 	} while (n);
233 	do {
234 		PUTCHAR(*--cp);
235 	} while (cp > prbuf);
236 	return (lbp);
237 }
238 
239 static int
240 _write(fd, buf, len)
241 	int fd;
242 	char *buf;
243 	int len;
244 {
245 
246 	if (fd == -1) {
247 		*(buf + len) = '\0';
248 		return (0);
249 	}
250 	return (write(fd, buf, len));
251 }
252