|
17 | 17 | #include <linux/kernel.h>
|
18 | 18 | #include <linux/limits.h>
|
19 | 19 | #include <linux/string.h>
|
| 20 | +#include <linux/types.h> |
20 | 21 |
|
21 | 22 | static
|
22 | 23 | int skip_atoi(const char **s)
|
@@ -237,16 +238,22 @@ char get_sign(long long *num, int flags)
|
237 | 238 | return 0;
|
238 | 239 | }
|
239 | 240 |
|
240 |
| -int vsprintf(char *buf, const char *fmt, va_list ap) |
| 241 | +#define PUTC(c) \ |
| 242 | +do { \ |
| 243 | + if (pos < size) \ |
| 244 | + buf[pos] = (c); \ |
| 245 | + ++pos; \ |
| 246 | +} while (0); |
| 247 | + |
| 248 | +int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap) |
241 | 249 | {
|
242 | 250 | /* The maximum space required is to print a 64-bit number in octal */
|
243 | 251 | char tmp[(sizeof(unsigned long long) * 8 + 2) / 3];
|
244 | 252 | char *tmp_end = &tmp[ARRAY_SIZE(tmp)];
|
245 | 253 | long long num;
|
246 | 254 | int base;
|
247 |
| - char *str; |
248 | 255 | const char *s;
|
249 |
| - int len; |
| 256 | + size_t len, pos; |
250 | 257 | char sign;
|
251 | 258 |
|
252 | 259 | int flags; /* flags to number() */
|
@@ -274,9 +281,9 @@ int vsprintf(char *buf, const char *fmt, va_list ap)
|
274 | 281 | */
|
275 | 282 | va_copy(args, ap);
|
276 | 283 |
|
277 |
| - for (str = buf; *fmt; ++fmt) { |
| 284 | + for (pos = 0; *fmt; ++fmt) { |
278 | 285 | if (*fmt != '%' || *++fmt == '%') {
|
279 |
| - *str++ = *fmt; |
| 286 | + PUTC(*fmt); |
280 | 287 | continue;
|
281 | 288 | }
|
282 | 289 |
|
@@ -416,40 +423,41 @@ int vsprintf(char *buf, const char *fmt, va_list ap)
|
416 | 423 | /* Leading padding with ' ' */
|
417 | 424 | if (!(flags & LEFT))
|
418 | 425 | while (field_width-- > 0)
|
419 |
| - *str++ = ' '; |
| 426 | + PUTC(' '); |
420 | 427 | /* sign */
|
421 | 428 | if (sign)
|
422 |
| - *str++ = sign; |
| 429 | + PUTC(sign); |
423 | 430 | /* 0x/0X for hexadecimal */
|
424 | 431 | if (flags & SPECIAL) {
|
425 |
| - *str++ = '0'; |
426 |
| - *str++ = 'X' | (flags & SMALL); |
| 432 | + PUTC('0'); |
| 433 | + PUTC( 'X' | (flags & SMALL)); |
427 | 434 | }
|
428 | 435 | /* Zero padding and excess precision */
|
429 | 436 | while (precision-- > len)
|
430 |
| - *str++ = '0'; |
| 437 | + PUTC('0'); |
431 | 438 | /* Actual output */
|
432 | 439 | while (len-- > 0)
|
433 |
| - *str++ = *s++; |
| 440 | + PUTC(*s++); |
434 | 441 | /* Trailing padding with ' ' */
|
435 | 442 | while (field_width-- > 0)
|
436 |
| - *str++ = ' '; |
| 443 | + PUTC(' '); |
437 | 444 | }
|
438 | 445 | fail:
|
439 |
| - *str = '\0'; |
440 |
| - |
441 | 446 | va_end(args);
|
442 | 447 |
|
443 |
| - return str - buf; |
| 448 | + if (size) |
| 449 | + buf[min(pos, size-1)] = '\0'; |
| 450 | + |
| 451 | + return pos; |
444 | 452 | }
|
445 | 453 |
|
446 |
| -int sprintf(char *buf, const char *fmt, ...) |
| 454 | +int snprintf(char *buf, size_t size, const char *fmt, ...) |
447 | 455 | {
|
448 | 456 | va_list args;
|
449 | 457 | int i;
|
450 | 458 |
|
451 | 459 | va_start(args, fmt);
|
452 |
| - i = vsprintf(buf, fmt, args); |
| 460 | + i = vsnprintf(buf, size, fmt, args); |
453 | 461 | va_end(args);
|
454 | 462 | return i;
|
455 | 463 | }
|
0 commit comments