xref: /DragonStub/apps/lib/vsprintf.c (revision 78b790fa8bc8298f8bdfd5bd1945781650dbf361)
1 
2 #include <dragonstub/dragonstub.h>
3 #include <dragonstub/linux/stdarg.h>
4 #include <dragonstub/bug.h>
5 #include <dragonstub/minmax.h>
6 #include <dragonstub/limits.h>
7 #include <dragonstub/compiler_types.h>
8 #include <dragonstub/linux/err.h>
9 #include <dragonstub/linux/byteorder.h>
10 #include <dragonstub/linux/div64.h>
11 
12 struct printf_spec {
13 	unsigned int type : 8; /* format_type enum */
14 	signed int field_width : 24; /* width of output field */
15 	unsigned int flags : 8; /* flags to number() */
16 	unsigned int base : 8; /* number base, 8, 10 or 16 only */
17 	signed int precision : 16; /* # of digits/chars */
18 } __packed;
19 
20 #define SIGN 1 /* unsigned/signed, must be 1 */
21 #define LEFT 2 /* left justified */
22 #define PLUS 4 /* show plus */
23 #define SPACE 8 /* space if plus */
24 #define ZEROPAD 16 /* pad with zero, must be 16 == '0' - ' ' */
25 #define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */
26 #define SPECIAL 64 /* prefix hex with "0x", octal with "0" */
27 
28 static_assert(SIGN == 1);
29 static_assert(ZEROPAD == ('0' - ' '));
30 static_assert(SMALL == ('a' ^ 'A'));
31 
32 enum format_type {
33 	FORMAT_TYPE_NONE, /* Just a string part */
34 	FORMAT_TYPE_WIDTH,
35 	FORMAT_TYPE_PRECISION,
36 	FORMAT_TYPE_CHAR,
37 	FORMAT_TYPE_STR,
38 	FORMAT_TYPE_PTR,
39 	FORMAT_TYPE_PERCENT_CHAR,
40 	FORMAT_TYPE_INVALID,
41 	FORMAT_TYPE_LONG_LONG,
42 	FORMAT_TYPE_ULONG,
43 	FORMAT_TYPE_LONG,
44 	FORMAT_TYPE_UBYTE,
45 	FORMAT_TYPE_BYTE,
46 	FORMAT_TYPE_USHORT,
47 	FORMAT_TYPE_SHORT,
48 	FORMAT_TYPE_UINT,
49 	FORMAT_TYPE_INT,
50 	FORMAT_TYPE_SIZE_T,
51 	FORMAT_TYPE_PTRDIFF
52 };
53 
skip_atoi(const char ** s)54 static noinline_for_stack int skip_atoi(const char **s)
55 {
56 	int i = 0;
57 
58 	do {
59 		i = i * 10 + *((*s)++) - '0';
60 	} while (isdigit(**s));
61 
62 	return i;
63 }
64 
65 /*
66  * Decimal conversion is by far the most typical, and is used for
67  * /proc and /sys data. This directly impacts e.g. top performance
68  * with many processes running. We optimize it for speed by emitting
69  * two characters at a time, using a 200 byte lookup table. This
70  * roughly halves the number of multiplications compared to computing
71  * the digits one at a time. Implementation strongly inspired by the
72  * previous version, which in turn used ideas described at
73  * <http://www.cs.uiowa.edu/~jones/bcd/divide.html> (with permission
74  * from the author, Douglas W. Jones).
75  *
76  * It turns out there is precisely one 26 bit fixed-point
77  * approximation a of 64/100 for which x/100 == (x * (u64)a) >> 32
78  * holds for all x in [0, 10^8-1], namely a = 0x28f5c29. The actual
79  * range happens to be somewhat larger (x <= 1073741898), but that's
80  * irrelevant for our purpose.
81  *
82  * For dividing a number in the range [10^4, 10^6-1] by 100, we still
83  * need a 32x32->64 bit multiply, so we simply use the same constant.
84  *
85  * For dividing a number in the range [100, 10^4-1] by 100, there are
86  * several options. The simplest is (x * 0x147b) >> 19, which is valid
87  * for all x <= 43698.
88  */
89 
90 static const u16 decpair[100] = {
91 #define _(x) (__force u16) cpu_to_le16(((x % 10) | ((x / 10) << 8)) + 0x3030)
92 	_(0),  _(1),  _(2),  _(3),  _(4),  _(5),  _(6),	 _(7),	_(8),  _(9),
93 	_(10), _(11), _(12), _(13), _(14), _(15), _(16), _(17), _(18), _(19),
94 	_(20), _(21), _(22), _(23), _(24), _(25), _(26), _(27), _(28), _(29),
95 	_(30), _(31), _(32), _(33), _(34), _(35), _(36), _(37), _(38), _(39),
96 	_(40), _(41), _(42), _(43), _(44), _(45), _(46), _(47), _(48), _(49),
97 	_(50), _(51), _(52), _(53), _(54), _(55), _(56), _(57), _(58), _(59),
98 	_(60), _(61), _(62), _(63), _(64), _(65), _(66), _(67), _(68), _(69),
99 	_(70), _(71), _(72), _(73), _(74), _(75), _(76), _(77), _(78), _(79),
100 	_(80), _(81), _(82), _(83), _(84), _(85), _(86), _(87), _(88), _(89),
101 	_(90), _(91), _(92), _(93), _(94), _(95), _(96), _(97), _(98), _(99),
102 #undef _
103 };
104 
105 /*
106  * This will print a single '0' even if r == 0, since we would
107  * immediately jump to out_r where two 0s would be written but only
108  * one of them accounted for in buf. This is needed by ip4_string
109  * below. All other callers pass a non-zero value of r.
110 */
put_dec_trunc8(char * buf,unsigned r)111 static noinline_for_stack char *put_dec_trunc8(char *buf, unsigned r)
112 {
113 	unsigned q;
114 
115 	/* 1 <= r < 10^8 */
116 	if (r < 100)
117 		goto out_r;
118 
119 	/* 100 <= r < 10^8 */
120 	q = (r * (u64)0x28f5c29) >> 32;
121 	*((u16 *)buf) = decpair[r - 100 * q];
122 	buf += 2;
123 
124 	/* 1 <= q < 10^6 */
125 	if (q < 100)
126 		goto out_q;
127 
128 	/*  100 <= q < 10^6 */
129 	r = (q * (u64)0x28f5c29) >> 32;
130 	*((u16 *)buf) = decpair[q - 100 * r];
131 	buf += 2;
132 
133 	/* 1 <= r < 10^4 */
134 	if (r < 100)
135 		goto out_r;
136 
137 	/* 100 <= r < 10^4 */
138 	q = (r * 0x147b) >> 19;
139 	*((u16 *)buf) = decpair[r - 100 * q];
140 	buf += 2;
141 out_q:
142 	/* 1 <= q < 100 */
143 	r = q;
144 out_r:
145 	/* 1 <= r < 100 */
146 	*((u16 *)buf) = decpair[r];
147 	buf += r < 10 ? 1 : 2;
148 	return buf;
149 }
150 
151 #if BITS_PER_LONG == 64 && BITS_PER_LONG_LONG == 64
put_dec_full8(char * buf,unsigned r)152 static noinline_for_stack char *put_dec_full8(char *buf, unsigned r)
153 {
154 	unsigned q;
155 
156 	/* 0 <= r < 10^8 */
157 	q = (r * (u64)0x28f5c29) >> 32;
158 	*((u16 *)buf) = decpair[r - 100 * q];
159 	buf += 2;
160 
161 	/* 0 <= q < 10^6 */
162 	r = (q * (u64)0x28f5c29) >> 32;
163 	*((u16 *)buf) = decpair[q - 100 * r];
164 	buf += 2;
165 
166 	/* 0 <= r < 10^4 */
167 	q = (r * 0x147b) >> 19;
168 	*((u16 *)buf) = decpair[r - 100 * q];
169 	buf += 2;
170 
171 	/* 0 <= q < 100 */
172 	*((u16 *)buf) = decpair[q];
173 	buf += 2;
174 	return buf;
175 }
176 
put_dec(char * buf,unsigned long long n)177 static noinline_for_stack char *put_dec(char *buf, unsigned long long n)
178 {
179 	if (n >= 100 * 1000 * 1000)
180 		buf = put_dec_full8(buf, do_div(n, 100 * 1000 * 1000));
181 	/* 1 <= n <= 1.6e11 */
182 	if (n >= 100 * 1000 * 1000)
183 		buf = put_dec_full8(buf, do_div(n, 100 * 1000 * 1000));
184 	/* 1 <= n < 1e8 */
185 	return put_dec_trunc8(buf, n);
186 }
187 
188 #elif BITS_PER_LONG == 32 && BITS_PER_LONG_LONG == 64
189 
put_dec_full4(char * buf,unsigned r)190 static void put_dec_full4(char *buf, unsigned r)
191 {
192 	unsigned q;
193 
194 	/* 0 <= r < 10^4 */
195 	q = (r * 0x147b) >> 19;
196 	*((u16 *)buf) = decpair[r - 100 * q];
197 	buf += 2;
198 	/* 0 <= q < 100 */
199 	*((u16 *)buf) = decpair[q];
200 }
201 
202 /*
203  * Call put_dec_full4 on x % 10000, return x / 10000.
204  * The approximation x/10000 == (x * 0x346DC5D7) >> 43
205  * holds for all x < 1,128,869,999.  The largest value this
206  * helper will ever be asked to convert is 1,125,520,955.
207  * (second call in the put_dec code, assuming n is all-ones).
208  */
put_dec_helper4(char * buf,unsigned x)209 static noinline_for_stack unsigned put_dec_helper4(char *buf, unsigned x)
210 {
211 	uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43;
212 
213 	put_dec_full4(buf, x - q * 10000);
214 	return q;
215 }
216 
217 /* Based on code by Douglas W. Jones found at
218  * <http://www.cs.uiowa.edu/~jones/bcd/decimal.html#sixtyfour>
219  * (with permission from the author).
220  * Performs no 64-bit division and hence should be fast on 32-bit machines.
221  */
put_dec(char * buf,unsigned long long n)222 static char *put_dec(char *buf, unsigned long long n)
223 {
224 	uint32_t d3, d2, d1, q, h;
225 
226 	if (n < 100 * 1000 * 1000)
227 		return put_dec_trunc8(buf, n);
228 
229 	d1 = ((uint32_t)n >> 16); /* implicit "& 0xffff" */
230 	h = (n >> 32);
231 	d2 = (h)&0xffff;
232 	d3 = (h >> 16); /* implicit "& 0xffff" */
233 
234 	/* n = 2^48 d3 + 2^32 d2 + 2^16 d1 + d0
235 	     = 281_4749_7671_0656 d3 + 42_9496_7296 d2 + 6_5536 d1 + d0 */
236 	q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff);
237 	q = put_dec_helper4(buf, q);
238 
239 	q += 7671 * d3 + 9496 * d2 + 6 * d1;
240 	q = put_dec_helper4(buf + 4, q);
241 
242 	q += 4749 * d3 + 42 * d2;
243 	q = put_dec_helper4(buf + 8, q);
244 
245 	q += 281 * d3;
246 	buf += 12;
247 	if (q)
248 		buf = put_dec_trunc8(buf, q);
249 	else
250 		while (buf[-1] == '0')
251 			--buf;
252 
253 	return buf;
254 }
255 
256 #endif
257 
258 #define FIELD_WIDTH_MAX ((1 << 23) - 1)
259 #define PRECISION_MAX ((1 << 15) - 1)
260 
set_field_width(struct printf_spec * spec,int width)261 static void set_field_width(struct printf_spec *spec, int width)
262 {
263 	spec->field_width = width;
264 	if (WARN_ONCE(spec->field_width != width, "field width %d too large",
265 		      width)) {
266 		spec->field_width =
267 			clamp(width, -FIELD_WIDTH_MAX, FIELD_WIDTH_MAX);
268 	}
269 }
270 
set_precision(struct printf_spec * spec,int prec)271 static void set_precision(struct printf_spec *spec, int prec)
272 {
273 	spec->precision = prec;
274 	if (WARN_ONCE(spec->precision != prec, "precision %d too large",
275 		      prec)) {
276 		spec->precision = clamp(prec, 0, PRECISION_MAX);
277 	}
278 }
279 
280 static noinline_for_stack char *
number(char * buf,char * end,unsigned long long num,struct printf_spec spec)281 number(char *buf, char *end, unsigned long long num, struct printf_spec spec)
282 {
283 	/* put_dec requires 2-byte alignment of the buffer. */
284 	char tmp[3 * sizeof(num)] __aligned(2);
285 	char sign;
286 	char locase;
287 	int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
288 	int i;
289 	bool is_zero = num == 0LL;
290 	int field_width = spec.field_width;
291 	int precision = spec.precision;
292 
293 	/* locase = 0 or 0x20. ORing digits or letters with 'locase'
294 	 * produces same digits or (maybe lowercased) letters */
295 	locase = (spec.flags & SMALL);
296 	if (spec.flags & LEFT)
297 		spec.flags &= ~ZEROPAD;
298 	sign = 0;
299 	if (spec.flags & SIGN) {
300 		if ((signed long long)num < 0) {
301 			sign = '-';
302 			num = -(signed long long)num;
303 			field_width--;
304 		} else if (spec.flags & PLUS) {
305 			sign = '+';
306 			field_width--;
307 		} else if (spec.flags & SPACE) {
308 			sign = ' ';
309 			field_width--;
310 		}
311 	}
312 	if (need_pfx) {
313 		if (spec.base == 16)
314 			field_width -= 2;
315 		else if (!is_zero)
316 			field_width--;
317 	}
318 
319 	/* generate full string in tmp[], in reverse order */
320 	i = 0;
321 	if (num < spec.base)
322 		tmp[i++] = hex_asc_upper[num] | locase;
323 	else if (spec.base != 10) { /* 8 or 16 */
324 		int mask = spec.base - 1;
325 		int shift = 3;
326 
327 		if (spec.base == 16)
328 			shift = 4;
329 		do {
330 			tmp[i++] = (hex_asc_upper[((unsigned char)num) & mask] |
331 				    locase);
332 			num >>= shift;
333 		} while (num);
334 	} else { /* base 10 */
335 		i = put_dec(tmp, num) - tmp;
336 	}
337 
338 	/* printing 100 using %2d gives "100", not "00" */
339 	if (i > precision)
340 		precision = i;
341 	/* leading space padding */
342 	field_width -= precision;
343 	if (!(spec.flags & (ZEROPAD | LEFT))) {
344 		while (--field_width >= 0) {
345 			if (buf < end)
346 				*buf = ' ';
347 			++buf;
348 		}
349 	}
350 	/* sign */
351 	if (sign) {
352 		if (buf < end)
353 			*buf = sign;
354 		++buf;
355 	}
356 	/* "0x" / "0" prefix */
357 	if (need_pfx) {
358 		if (spec.base == 16 || !is_zero) {
359 			if (buf < end)
360 				*buf = '0';
361 			++buf;
362 		}
363 		if (spec.base == 16) {
364 			if (buf < end)
365 				*buf = ('X' | locase);
366 			++buf;
367 		}
368 	}
369 	/* zero or space padding */
370 	if (!(spec.flags & LEFT)) {
371 		char c = ' ' + (spec.flags & ZEROPAD);
372 
373 		while (--field_width >= 0) {
374 			if (buf < end)
375 				*buf = c;
376 			++buf;
377 		}
378 	}
379 	/* hmm even more zero padding? */
380 	while (i <= --precision) {
381 		if (buf < end)
382 			*buf = '0';
383 		++buf;
384 	}
385 	/* actual digits of result */
386 	while (--i >= 0) {
387 		if (buf < end)
388 			*buf = tmp[i];
389 		++buf;
390 	}
391 	/* trailing space padding */
392 	while (--field_width >= 0) {
393 		if (buf < end)
394 			*buf = ' ';
395 		++buf;
396 	}
397 
398 	return buf;
399 }
400 
401 static noinline_for_stack char *
special_hex_number(char * buf,char * end,unsigned long long num,int size)402 special_hex_number(char *buf, char *end, unsigned long long num, int size)
403 {
404 	struct printf_spec spec;
405 
406 	spec.type = FORMAT_TYPE_PTR;
407 	spec.field_width = 2 + 2 * size; /* 0x + hex */
408 	spec.flags = SPECIAL | SMALL | ZEROPAD;
409 	spec.base = 16;
410 	spec.precision = -1;
411 
412 	return number(buf, end, num, spec);
413 }
414 
move_right(char * buf,char * end,unsigned len,unsigned spaces)415 static void move_right(char *buf, char *end, unsigned len, unsigned spaces)
416 {
417 	size_t size;
418 	if (buf >= end) /* nowhere to put anything */
419 		return;
420 	size = end - buf;
421 	if (size <= spaces) {
422 		memset(buf, ' ', size);
423 		return;
424 	}
425 	if (len) {
426 		if (len > size - spaces)
427 			len = size - spaces;
428 		memmove(buf + spaces, buf, len);
429 	}
430 	memset(buf, ' ', spaces);
431 }
432 
433 /*
434  * Handle field width padding for a string.
435  * @buf: current buffer position
436  * @n: length of string
437  * @end: end of output buffer
438  * @spec: for field width and flags
439  * Returns: new buffer position after padding.
440  */
widen_string(char * buf,int n,char * end,struct printf_spec spec)441 static noinline_for_stack char *widen_string(char *buf, int n, char *end,
442 					     struct printf_spec spec)
443 {
444 	unsigned spaces;
445 
446 	if (likely(n >= spec.field_width))
447 		return buf;
448 	/* we want to pad the sucker */
449 	spaces = spec.field_width - n;
450 	if (!(spec.flags & LEFT)) {
451 		move_right(buf - n, end, n, spaces);
452 		return buf + spaces;
453 	}
454 	while (spaces--) {
455 		if (buf < end)
456 			*buf = ' ';
457 		++buf;
458 	}
459 	return buf;
460 }
461 
462 /* Handle string from a well known address. */
string_nocheck(char * buf,char * end,const char * s,struct printf_spec spec)463 static char *string_nocheck(char *buf, char *end, const char *s,
464 			    struct printf_spec spec)
465 {
466 	int len = 0;
467 	int lim = spec.precision;
468 
469 	while (lim--) {
470 		char c = *s++;
471 		if (!c)
472 			break;
473 		if (buf < end)
474 			*buf = c;
475 		++buf;
476 		++len;
477 	}
478 	return widen_string(buf, len, end, spec);
479 }
480 
481 /* Be careful: error messages must fit into the given buffer. */
error_string(char * buf,char * end,const char * s,struct printf_spec spec)482 static char *error_string(char *buf, char *end, const char *s,
483 			  struct printf_spec spec)
484 {
485 	/*
486 	 * Hard limit to avoid a completely insane messages. It actually
487 	 * works pretty well because most error messages are in
488 	 * the many pointer format modifiers.
489 	 */
490 	if (spec.precision == -1)
491 		spec.precision = 2 * sizeof(void *);
492 
493 	return string_nocheck(buf, end, s, spec);
494 }
495 
496 /*
497  * Do not call any complex external code here. Nested printk()/vsprintf()
498  * might cause infinite loops. Failures might break printk() and would
499  * be hard to debug.
500  */
check_pointer_msg(const void * ptr)501 static const char *check_pointer_msg(const void *ptr)
502 {
503 	if (!ptr)
504 		return "(null)";
505 
506 	if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr))
507 		return "(efault)";
508 
509 	return NULL;
510 }
511 
check_pointer(char ** buf,char * end,const void * ptr,struct printf_spec spec)512 static int check_pointer(char **buf, char *end, const void *ptr,
513 			 struct printf_spec spec)
514 {
515 	const char *err_msg;
516 
517 	err_msg = check_pointer_msg(ptr);
518 	if (err_msg) {
519 		*buf = error_string(*buf, end, err_msg, spec);
520 		return -EFAULT;
521 	}
522 
523 	return 0;
524 }
525 
string(char * buf,char * end,const char * s,struct printf_spec spec)526 static noinline_for_stack char *string(char *buf, char *end, const char *s,
527 				       struct printf_spec spec)
528 {
529 	if (check_pointer(&buf, end, s, spec))
530 		return buf;
531 
532 	return string_nocheck(buf, end, s, spec);
533 }
534 
pointer_string(char * buf,char * end,const void * ptr,struct printf_spec spec)535 static char *pointer_string(char *buf, char *end, const void *ptr,
536 			    struct printf_spec spec)
537 {
538 	spec.base = 16;
539 	spec.flags |= SMALL;
540 	if (spec.field_width == -1) {
541 		spec.field_width = 2 * sizeof(ptr);
542 		spec.flags |= ZEROPAD;
543 	}
544 
545 	return number(buf, end, (unsigned long int)ptr, spec);
546 }
547 
hex_string(char * buf,char * end,u8 * addr,struct printf_spec spec,const char * fmt)548 static noinline_for_stack char *hex_string(char *buf, char *end, u8 *addr,
549 					   struct printf_spec spec,
550 					   const char *fmt)
551 {
552 	int i, len = 1; /* if we pass '%ph[CDN]', field width remains
553 				   negative value, fallback to the default */
554 	char separator;
555 
556 	if (spec.field_width == 0)
557 		/* nothing to print */
558 		return buf;
559 
560 	if (check_pointer(&buf, end, addr, spec))
561 		return buf;
562 
563 	switch (fmt[1]) {
564 	case 'C':
565 		separator = ':';
566 		break;
567 	case 'D':
568 		separator = '-';
569 		break;
570 	case 'N':
571 		separator = 0;
572 		break;
573 	default:
574 		separator = ' ';
575 		break;
576 	}
577 
578 	if (spec.field_width > 0)
579 		len = min_t(int, spec.field_width, 64);
580 
581 	for (i = 0; i < len; ++i) {
582 		if (buf < end)
583 			*buf = hex_asc_hi(addr[i]);
584 		++buf;
585 		if (buf < end)
586 			*buf = hex_asc_lo(addr[i]);
587 		++buf;
588 
589 		if (separator && i != len - 1) {
590 			if (buf < end)
591 				*buf = separator;
592 			++buf;
593 		}
594 	}
595 
596 	return buf;
597 }
598 
mac_address_string(char * buf,char * end,u8 * addr,struct printf_spec spec,const char * fmt)599 static noinline_for_stack char *mac_address_string(char *buf, char *end,
600 						   u8 *addr,
601 						   struct printf_spec spec,
602 						   const char *fmt)
603 {
604 	char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
605 	char *p = mac_addr;
606 	int i;
607 	char separator;
608 	bool reversed = false;
609 
610 	if (check_pointer(&buf, end, addr, spec))
611 		return buf;
612 
613 	switch (fmt[1]) {
614 	case 'F':
615 		separator = '-';
616 		break;
617 
618 	case 'R':
619 		reversed = true;
620 		fallthrough;
621 
622 	default:
623 		separator = ':';
624 		break;
625 	}
626 
627 	for (i = 0; i < 6; i++) {
628 		if (reversed)
629 			p = hex_byte_pack(p, addr[5 - i]);
630 		else
631 			p = hex_byte_pack(p, addr[i]);
632 
633 		if (fmt[0] == 'M' && i != 5)
634 			*p++ = separator;
635 	}
636 	*p = '\0';
637 
638 	return string_nocheck(buf, end, mac_addr, spec);
639 }
640 
default_pointer(char * buf,char * end,const void * ptr,struct printf_spec spec)641 static char *default_pointer(char *buf, char *end, const void *ptr,
642 			     struct printf_spec spec)
643 {
644 	return pointer_string(buf, end, ptr, spec);
645 }
646 
err_ptr(char * buf,char * end,void * ptr,struct printf_spec spec)647 static char *err_ptr(char *buf, char *end, void *ptr, struct printf_spec spec)
648 {
649 	int err = PTR_ERR(ptr);
650 	// const char *sym = errname(err);
651 
652 	// if (sym)
653 	// 	return string_nocheck(buf, end, sym, spec);
654 
655 	/*
656 	 * Somebody passed ERR_PTR(-1234) or some other non-existing
657 	 * Efoo - or perhaps CONFIG_SYMBOLIC_ERRNAME=n. Fall back to
658 	 * printing it as its decimal representation.
659 	 */
660 	spec.flags |= SIGN;
661 	spec.base = 10;
662 	return number(buf, end, err, spec);
663 }
664 
665 /*
666  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
667  * by an extra set of alphanumeric characters that are extended format
668  * specifiers.
669  *
670  * Please update scripts/checkpatch.pl when adding/removing conversion
671  * characters.  (Search for "check for vsprintf extension").
672  *
673  * Right now we handle:
674  *
675  * - 'S' For symbolic direct pointers (or function descriptors) with offset
676  * - 's' For symbolic direct pointers (or function descriptors) without offset
677  * - '[Ss]R' as above with __builtin_extract_return_addr() translation
678  * - 'S[R]b' as above with module build ID (for use in backtraces)
679  * - '[Ff]' %pf and %pF were obsoleted and later removed in favor of
680  *	    %ps and %pS. Be careful when re-using these specifiers.
681  * - 'B' For backtraced symbolic direct pointers with offset
682  * - 'Bb' as above with module build ID (for use in backtraces)
683  * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
684  * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
685  * - 'b[l]' For a bitmap, the number of bits is determined by the field
686  *       width which must be explicitly specified either as part of the
687  *       format string '%32b[l]' or through '%*b[l]', [l] selects
688  *       range-list format instead of hex format
689  * - 'M' For a 6-byte MAC address, it prints the address in the
690  *       usual colon-separated hex notation
691  * - 'm' For a 6-byte MAC address, it prints the hex address without colons
692  * - 'MF' For a 6-byte MAC FDDI address, it prints the address
693  *       with a dash-separated hex notation
694  * - '[mM]R' For a 6-byte MAC address, Reverse order (Bluetooth)
695  * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
696  *       IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
697  *       IPv6 uses colon separated network-order 16 bit hex with leading 0's
698  *       [S][pfs]
699  *       Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
700  *       [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
701  * - 'i' [46] for 'raw' IPv4/IPv6 addresses
702  *       IPv6 omits the colons (01020304...0f)
703  *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
704  *       [S][pfs]
705  *       Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
706  *       [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
707  * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order
708  * - 'I[6S]c' for IPv6 addresses printed as specified by
709  *       https://tools.ietf.org/html/rfc5952
710  * - 'E[achnops]' For an escaped buffer, where rules are defined by combination
711  *                of the following flags (see string_escape_mem() for the
712  *                details):
713  *                  a - ESCAPE_ANY
714  *                  c - ESCAPE_SPECIAL
715  *                  h - ESCAPE_HEX
716  *                  n - ESCAPE_NULL
717  *                  o - ESCAPE_OCTAL
718  *                  p - ESCAPE_NP
719  *                  s - ESCAPE_SPACE
720  *                By default ESCAPE_ANY_NP is used.
721  * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
722  *       "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
723  *       Options for %pU are:
724  *         b big endian lower case hex (default)
725  *         B big endian UPPER case hex
726  *         l little endian lower case hex
727  *         L little endian UPPER case hex
728  *           big endian output byte order is:
729  *             [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
730  *           little endian output byte order is:
731  *             [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
732  * - 'V' For a struct va_format which contains a format string * and va_list *,
733  *       call vsnprintf(->format, *->va_list).
734  *       Implements a "recursive vsnprintf".
735  *       Do not use this feature without some mechanism to verify the
736  *       correctness of the format string and va_list arguments.
737  * - 'K' For a kernel pointer that should be hidden from unprivileged users.
738  *       Use only for procfs, sysfs and similar files, not printk(); please
739  *       read the documentation (path below) first.
740  * - 'NF' For a netdev_features_t
741  * - '4cc' V4L2 or DRM FourCC code, with endianness and raw numerical value.
742  * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with
743  *            a certain separator (' ' by default):
744  *              C colon
745  *              D dash
746  *              N no separator
747  *            The maximum supported length is 64 bytes of the input. Consider
748  *            to use print_hex_dump() for the larger input.
749  * - 'a[pd]' For address types [p] phys_addr_t, [d] dma_addr_t and derivatives
750  *           (default assumed to be phys_addr_t, passed by reference)
751  * - 'd[234]' For a dentry name (optionally 2-4 last components)
752  * - 'D[234]' Same as 'd' but for a struct file
753  * - 'g' For block_device name (gendisk + partition number)
754  * - 't[RT][dt][r][s]' For time and date as represented by:
755  *      R    struct rtc_time
756  *      T    time64_t
757  * - 'C' For a clock, it prints the name (Common Clock Framework) or address
758  *       (legacy clock framework) of the clock
759  * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address
760  *        (legacy clock framework) of the clock
761  * - 'G' For flags to be printed as a collection of symbolic strings that would
762  *       construct the specific value. Supported flags given by option:
763  *       p page flags (see struct page) given as pointer to unsigned long
764  *       g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t
765  *       v vma flags (VM_*) given as pointer to unsigned long
766  * - 'OF[fnpPcCF]'  For a device tree object
767  *                  Without any optional arguments prints the full_name
768  *                  f device node full_name
769  *                  n device node name
770  *                  p device node phandle
771  *                  P device node path spec (name + @unit)
772  *                  F device node flags
773  *                  c major compatible string
774  *                  C full compatible string
775  * - 'fw[fP]'	For a firmware node (struct fwnode_handle) pointer
776  *		Without an option prints the full name of the node
777  *		f full name
778  *		P node name, including a possible unit address
779  * - 'x' For printing the address unmodified. Equivalent to "%lx".
780  *       Please read the documentation (path below) before using!
781  * - '[ku]s' For a BPF/tracing related format specifier, e.g. used out of
782  *           bpf_trace_printk() where [ku] prefix specifies either kernel (k)
783  *           or user (u) memory to probe, and:
784  *              s a string, equivalent to "%s" on direct vsnprintf() use
785  *
786  * ** When making changes please also update:
787  *	Documentation/core-api/printk-formats.rst
788  *
789  * Note: The default behaviour (unadorned %p) is to hash the address,
790  * rendering it useful as a unique identifier.
791  *
792  * There is also a '%pA' format specifier, but it is only intended to be used
793  * from Rust code to format core::fmt::Arguments. Do *not* use it from C.
794  * See rust/kernel/print.rs for details.
795  */
pointer(const char * fmt,char * buf,char * end,void * ptr,struct printf_spec spec)796 static noinline_for_stack char *pointer(const char *fmt, char *buf, char *end,
797 					void *ptr, struct printf_spec spec)
798 {
799 	switch (*fmt) {
800 	// case 'S':
801 	// case 's':
802 	// 	ptr = dereference_symbol_descriptor(ptr);
803 	// 	fallthrough;
804 	// case 'B':
805 	// 	return symbol_string(buf, end, ptr, spec, fmt);
806 	// case 'R':
807 	// case 'r':
808 	// 	return resource_string(buf, end, ptr, spec, fmt);
809 	case 'h':
810 		return hex_string(buf, end, ptr, spec, fmt);
811 	// case 'b':
812 	// 	switch (fmt[1]) {
813 	// 	case 'l':
814 	// 		return bitmap_list_string(buf, end, ptr, spec, fmt);
815 	// 	default:
816 	// 		return bitmap_string(buf, end, ptr, spec, fmt);
817 	// 	}
818 	case 'M': /* Colon separated: 00:01:02:03:04:05 */
819 	case 'm': /* Contiguous: 000102030405 */
820 		/* [mM]F (FDDI) */
821 		/* [mM]R (Reverse order; Bluetooth) */
822 		return mac_address_string(buf, end, ptr, spec, fmt);
823 		// case 'I': /* Formatted IP supported
824 		// 				 * 4:	1.2.3.4
825 		// 				 * 6:	0001:0203:...:0708
826 		// 				 * 6c:	1::708 or 1::1.2.3.4
827 		// 				 */
828 		// case 'i': /* Contiguous:
829 		// 				 * 4:	001.002.003.004
830 		// 				 * 6:   000102...0f
831 		// 				 */
832 		// 	return ip_addr_string(buf, end, ptr, spec, fmt);
833 		// case 'E':
834 		// 	return escaped_string(buf, end, ptr, spec, fmt);
835 		// case 'U':
836 		// 	return uuid_string(buf, end, ptr, spec, fmt);
837 		// case 'V':
838 		// 	return va_format(buf, end, ptr, spec, fmt);
839 		// case 'K':
840 		// 	return restricted_pointer(buf, end, ptr, spec);
841 		// case 'N':
842 		// 	return netdev_bits(buf, end, ptr, spec, fmt);
843 		// case '4':
844 		// 	return fourcc_string(buf, end, ptr, spec, fmt);
845 		// case 'a':
846 		// 	return address_val(buf, end, ptr, spec, fmt);
847 		// case 'd':
848 		// 	return dentry_name(buf, end, ptr, spec, fmt);
849 		// case 't':
850 		// 	return time_and_date(buf, end, ptr, spec, fmt);
851 		// case 'C':
852 		// 	return clock(buf, end, ptr, spec, fmt);
853 		// case 'D':
854 		// 	return file_dentry_name(buf, end, ptr, spec, fmt);
855 #ifdef CONFIG_BLOCK
856 	case 'g':
857 		return bdev_name(buf, end, ptr, spec, fmt);
858 #endif
859 
860 	// case 'G':
861 	// 	return flags_string(buf, end, ptr, spec, fmt);
862 	// case 'O':
863 	// 	return device_node_string(buf, end, ptr, spec, fmt + 1);
864 	// case 'f':
865 	// 	return fwnode_string(buf, end, ptr, spec, fmt + 1);
866 	// case 'A':
867 	// 	if (!IS_ENABLED(CONFIG_RUST)) {
868 	// 		WARN_ONCE(1, "Please remove %%pA from non-Rust code\n");
869 	// 		return error_string(buf, end, "(%pA?)", spec);
870 	// 	}
871 	// 	return rust_fmt_argument(buf, end, ptr);
872 	case 'x':
873 		return pointer_string(buf, end, ptr, spec);
874 	case 'e':
875 		/* %pe with a non-ERR_PTR gets treated as plain %p */
876 		if (!IS_ERR(ptr))
877 			return default_pointer(buf, end, ptr, spec);
878 		return err_ptr(buf, end, ptr, spec);
879 	case 'u':
880 	case 'k':
881 		switch (fmt[1]) {
882 		case 's':
883 			return string(buf, end, ptr, spec);
884 		default:
885 			return error_string(buf, end, "(einval)", spec);
886 		}
887 	default:
888 		return default_pointer(buf, end, ptr, spec);
889 	}
890 }
891 
892 /*
893  * Helper function to decode printf style format.
894  * Each call decode a token from the format and return the
895  * number of characters read (or likely the delta where it wants
896  * to go on the next call).
897  * The decoded token is returned through the parameters
898  *
899  * 'h', 'l', or 'L' for integer fields
900  * 'z' support added 23/7/1999 S.H.
901  * 'z' changed to 'Z' --davidm 1/25/99
902  * 'Z' changed to 'z' --adobriyan 2017-01-25
903  * 't' added for ptrdiff_t
904  *
905  * @fmt: the format string
906  * @type of the token returned
907  * @flags: various flags such as +, -, # tokens..
908  * @field_width: overwritten width
909  * @base: base of the number (octal, hex, ...)
910  * @precision: precision of a number
911  * @qualifier: qualifier of a number (long, size_t, ...)
912  */
format_decode(const char * fmt,struct printf_spec * spec)913 static noinline_for_stack int format_decode(const char *fmt,
914 					    struct printf_spec *spec)
915 {
916 	const char *start = fmt;
917 	char qualifier;
918 
919 	/* we finished early by reading the field width */
920 	if (spec->type == FORMAT_TYPE_WIDTH) {
921 		if (spec->field_width < 0) {
922 			spec->field_width = -spec->field_width;
923 			spec->flags |= LEFT;
924 		}
925 		spec->type = FORMAT_TYPE_NONE;
926 		goto precision;
927 	}
928 
929 	/* we finished early by reading the precision */
930 	if (spec->type == FORMAT_TYPE_PRECISION) {
931 		if (spec->precision < 0)
932 			spec->precision = 0;
933 
934 		spec->type = FORMAT_TYPE_NONE;
935 		goto qualifier;
936 	}
937 
938 	/* By default */
939 	spec->type = FORMAT_TYPE_NONE;
940 
941 	for (; *fmt; ++fmt) {
942 		if (*fmt == '%')
943 			break;
944 	}
945 
946 	/* Return the current non-format string */
947 	if (fmt != start || !*fmt)
948 		return fmt - start;
949 
950 	/* Process flags */
951 	spec->flags = 0;
952 
953 	while (1) { /* this also skips first '%' */
954 		bool found = true;
955 
956 		++fmt;
957 
958 		switch (*fmt) {
959 		case '-':
960 			spec->flags |= LEFT;
961 			break;
962 		case '+':
963 			spec->flags |= PLUS;
964 			break;
965 		case ' ':
966 			spec->flags |= SPACE;
967 			break;
968 		case '#':
969 			spec->flags |= SPECIAL;
970 			break;
971 		case '0':
972 			spec->flags |= ZEROPAD;
973 			break;
974 		default:
975 			found = false;
976 		}
977 
978 		if (!found)
979 			break;
980 	}
981 
982 	/* get field width */
983 	spec->field_width = -1;
984 
985 	if (isdigit(*fmt))
986 		spec->field_width = skip_atoi(&fmt);
987 	else if (*fmt == '*') {
988 		/* it's the next argument */
989 		spec->type = FORMAT_TYPE_WIDTH;
990 		return ++fmt - start;
991 	}
992 
993 precision:
994 	/* get the precision */
995 	spec->precision = -1;
996 	if (*fmt == '.') {
997 		++fmt;
998 		if (isdigit(*fmt)) {
999 			spec->precision = skip_atoi(&fmt);
1000 			if (spec->precision < 0)
1001 				spec->precision = 0;
1002 		} else if (*fmt == '*') {
1003 			/* it's the next argument */
1004 			spec->type = FORMAT_TYPE_PRECISION;
1005 			return ++fmt - start;
1006 		}
1007 	}
1008 
1009 qualifier:
1010 	/* get the conversion qualifier */
1011 	qualifier = 0;
1012 	if (*fmt == 'h' || _tolower(*fmt) == 'l' || *fmt == 'z' ||
1013 	    *fmt == 't') {
1014 		qualifier = *fmt++;
1015 		if (unlikely(qualifier == *fmt)) {
1016 			if (qualifier == 'l') {
1017 				qualifier = 'L';
1018 				++fmt;
1019 			} else if (qualifier == 'h') {
1020 				qualifier = 'H';
1021 				++fmt;
1022 			}
1023 		}
1024 	}
1025 
1026 	/* default base */
1027 	spec->base = 10;
1028 	switch (*fmt) {
1029 	case 'c':
1030 		spec->type = FORMAT_TYPE_CHAR;
1031 		return ++fmt - start;
1032 
1033 	case 's':
1034 		spec->type = FORMAT_TYPE_STR;
1035 		return ++fmt - start;
1036 
1037 	case 'p':
1038 		spec->type = FORMAT_TYPE_PTR;
1039 		return ++fmt - start;
1040 
1041 	case '%':
1042 		spec->type = FORMAT_TYPE_PERCENT_CHAR;
1043 		return ++fmt - start;
1044 
1045 	/* integer number formats - set up the flags and "break" */
1046 	case 'o':
1047 		spec->base = 8;
1048 		break;
1049 
1050 	case 'x':
1051 		spec->flags |= SMALL;
1052 		fallthrough;
1053 
1054 	case 'X':
1055 		spec->base = 16;
1056 		break;
1057 
1058 	case 'd':
1059 	case 'i':
1060 		spec->flags |= SIGN;
1061 		break;
1062 	case 'u':
1063 		break;
1064 
1065 	case 'n':
1066 		/*
1067 		 * Since %n poses a greater security risk than
1068 		 * utility, treat it as any other invalid or
1069 		 * unsupported format specifier.
1070 		 */
1071 		fallthrough;
1072 
1073 	default:
1074 		WARN_ONCE(1,
1075 			  "Please remove unsupported %%%c in format string\n",
1076 			  *fmt);
1077 		spec->type = FORMAT_TYPE_INVALID;
1078 		return fmt - start;
1079 	}
1080 
1081 	if (qualifier == 'L')
1082 		spec->type = FORMAT_TYPE_LONG_LONG;
1083 	else if (qualifier == 'l') {
1084 		BUILD_BUG_ON(FORMAT_TYPE_ULONG + SIGN != FORMAT_TYPE_LONG);
1085 		spec->type = FORMAT_TYPE_ULONG + (spec->flags & SIGN);
1086 	} else if (qualifier == 'z') {
1087 		spec->type = FORMAT_TYPE_SIZE_T;
1088 	} else if (qualifier == 't') {
1089 		spec->type = FORMAT_TYPE_PTRDIFF;
1090 	} else if (qualifier == 'H') {
1091 		BUILD_BUG_ON(FORMAT_TYPE_UBYTE + SIGN != FORMAT_TYPE_BYTE);
1092 		spec->type = FORMAT_TYPE_UBYTE + (spec->flags & SIGN);
1093 	} else if (qualifier == 'h') {
1094 		BUILD_BUG_ON(FORMAT_TYPE_USHORT + SIGN != FORMAT_TYPE_SHORT);
1095 		spec->type = FORMAT_TYPE_USHORT + (spec->flags & SIGN);
1096 	} else {
1097 		BUILD_BUG_ON(FORMAT_TYPE_UINT + SIGN != FORMAT_TYPE_INT);
1098 		spec->type = FORMAT_TYPE_UINT + (spec->flags & SIGN);
1099 	}
1100 
1101 	return ++fmt - start;
1102 }
1103 
1104 /**
1105  * vsnprintf - Format a string and place it in a buffer
1106  * @buf: The buffer to place the result into
1107  * @size: The size of the buffer, including the trailing null space
1108  * @fmt: The format string to use
1109  * @args: Arguments for the format string
1110  *
1111  * This function generally follows C99 vsnprintf, but has some
1112  * extensions and a few limitations:
1113  *
1114  *  - ``%n`` is unsupported
1115  *  - ``%p*`` is handled by pointer()
1116  *
1117  * See pointer() or Documentation/core-api/printk-formats.rst for more
1118  * extensive description.
1119  *
1120  * **Please update the documentation in both places when making changes**
1121  *
1122  * The return value is the number of characters which would
1123  * be generated for the given input, excluding the trailing
1124  * '\0', as per ISO C99. If you want to have the exact
1125  * number of characters written into @buf as return value
1126  * (not including the trailing '\0'), use vscnprintf(). If the
1127  * return is greater than or equal to @size, the resulting
1128  * string is truncated.
1129  *
1130  * If you're not already dealing with a va_list consider using snprintf().
1131  */
vsnprintf(char * buf,size_t size,const char * fmt,va_list args)1132 int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
1133 {
1134 	unsigned long long num;
1135 	char *str, *end;
1136 	struct printf_spec spec = { 0 };
1137 
1138 	/* Reject out-of-range values early.  Large positive sizes are
1139 	   used for unknown buffer sizes. */
1140 	if (WARN_ON_ONCE(size > INT_MAX))
1141 		return 0;
1142 
1143 	str = buf;
1144 	end = buf + size;
1145 
1146 	/* Make sure end is always >= buf */
1147 	if (end < buf) {
1148 		end = ((void *)-1);
1149 		size = end - buf;
1150 	}
1151 
1152 	while (*fmt) {
1153 		const char *old_fmt = fmt;
1154 		int read = format_decode(fmt, &spec);
1155 
1156 		fmt += read;
1157 
1158 		switch (spec.type) {
1159 		case FORMAT_TYPE_NONE: {
1160 			int copy = read;
1161 			if (str < end) {
1162 				if (copy > end - str)
1163 					copy = end - str;
1164 				memcpy(str, old_fmt, copy);
1165 			}
1166 			str += read;
1167 			break;
1168 		}
1169 
1170 		case FORMAT_TYPE_WIDTH:
1171 			set_field_width(&spec, va_arg(args, int));
1172 			break;
1173 
1174 		case FORMAT_TYPE_PRECISION:
1175 			set_precision(&spec, va_arg(args, int));
1176 			break;
1177 
1178 		case FORMAT_TYPE_CHAR: {
1179 			char c;
1180 
1181 			if (!(spec.flags & LEFT)) {
1182 				while (--spec.field_width > 0) {
1183 					if (str < end)
1184 						*str = ' ';
1185 					++str;
1186 				}
1187 			}
1188 			c = (unsigned char)va_arg(args, int);
1189 			if (str < end)
1190 				*str = c;
1191 			++str;
1192 			while (--spec.field_width > 0) {
1193 				if (str < end)
1194 					*str = ' ';
1195 				++str;
1196 			}
1197 			break;
1198 		}
1199 
1200 		case FORMAT_TYPE_STR:
1201 			str = string(str, end, va_arg(args, char *), spec);
1202 			break;
1203 
1204 		case FORMAT_TYPE_PTR:
1205 			str = pointer(fmt, str, end, va_arg(args, void *),
1206 				      spec);
1207 			while (isalnum(*fmt))
1208 				fmt++;
1209 			break;
1210 
1211 		case FORMAT_TYPE_PERCENT_CHAR:
1212 			if (str < end)
1213 				*str = '%';
1214 			++str;
1215 			break;
1216 
1217 		case FORMAT_TYPE_INVALID:
1218 			/*
1219 			 * Presumably the arguments passed gcc's type
1220 			 * checking, but there is no safe or sane way
1221 			 * for us to continue parsing the format and
1222 			 * fetching from the va_list; the remaining
1223 			 * specifiers and arguments would be out of
1224 			 * sync.
1225 			 */
1226 			goto out;
1227 
1228 		default:
1229 			switch (spec.type) {
1230 			case FORMAT_TYPE_LONG_LONG:
1231 				num = va_arg(args, long long);
1232 				break;
1233 			case FORMAT_TYPE_ULONG:
1234 				num = va_arg(args, unsigned long);
1235 				break;
1236 			case FORMAT_TYPE_LONG:
1237 				num = va_arg(args, long);
1238 				break;
1239 			case FORMAT_TYPE_SIZE_T:
1240 				if (spec.flags & SIGN)
1241 					num = va_arg(args, ssize_t);
1242 				else
1243 					num = va_arg(args, size_t);
1244 				break;
1245 			case FORMAT_TYPE_PTRDIFF:
1246 				num = va_arg(args, ptrdiff_t);
1247 				break;
1248 			case FORMAT_TYPE_UBYTE:
1249 				num = (unsigned char)va_arg(args, int);
1250 				break;
1251 			case FORMAT_TYPE_BYTE:
1252 				num = (signed char)va_arg(args, int);
1253 				break;
1254 			case FORMAT_TYPE_USHORT:
1255 				num = (unsigned short)va_arg(args, int);
1256 				break;
1257 			case FORMAT_TYPE_SHORT:
1258 				num = (short)va_arg(args, int);
1259 				break;
1260 			case FORMAT_TYPE_INT:
1261 				num = (int)va_arg(args, int);
1262 				break;
1263 			default:
1264 				num = va_arg(args, unsigned int);
1265 			}
1266 
1267 			str = number(str, end, num, spec);
1268 		}
1269 	}
1270 
1271 out:
1272 	if (size > 0) {
1273 		if (str < end)
1274 			*str = '\0';
1275 		else
1276 			end[-1] = '\0';
1277 	}
1278 
1279 	/* the trailing null byte doesn't count towards the total */
1280 	return str - buf;
1281 }
1282 
1283 /**
1284  * snprintf - Format a string and place it in a buffer
1285  * @buf: The buffer to place the result into
1286  * @size: The size of the buffer, including the trailing null space
1287  * @fmt: The format string to use
1288  * @...: Arguments for the format string
1289  *
1290  * The return value is the number of characters which would be
1291  * generated for the given input, excluding the trailing null,
1292  * as per ISO C99.  If the return is greater than or equal to
1293  * @size, the resulting string is truncated.
1294  *
1295  * See the vsnprintf() documentation for format string extensions over C99.
1296  */
snprintf(char * buf,size_t size,const char * fmt,...)1297 int snprintf(char *buf, size_t size, const char *fmt, ...)
1298 {
1299 	va_list args;
1300 	int i;
1301 
1302 	va_start(args, fmt);
1303 	i = vsnprintf(buf, size, fmt, args);
1304 	va_end(args);
1305 
1306 	return i;
1307 }