diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-06-26 01:31:38 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-06-26 01:31:38 -0400 |
commit | 4854c7b27f0975a2b629f35ea3996d2968eb7c4f (patch) | |
tree | 4102bdb70289764a2058aff0f907b13d7cf0e0d1 /lib/vsprintf.c | |
parent | 3cbd5b32cb625f5c0f1b1476d154fac873dd49ce (diff) | |
parent | fcc18e83e1f6fd9fa6b333735bf0fcd530655511 (diff) | |
download | kernel-crypto-4854c7b27f0975a2b629f35ea3996d2968eb7c4f.tar.gz kernel-crypto-4854c7b27f0975a2b629f35ea3996d2968eb7c4f.tar.xz kernel-crypto-4854c7b27f0975a2b629f35ea3996d2968eb7c4f.zip |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 88 |
1 files changed, 56 insertions, 32 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index b07db5ca3f6..797428afd11 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -187,49 +187,49 @@ static char * number(char * buf, char * end, unsigned long long num, int base, i size -= precision; if (!(type&(ZEROPAD+LEFT))) { while(size-->0) { - if (buf <= end) + if (buf < end) *buf = ' '; ++buf; } } if (sign) { - if (buf <= end) + if (buf < end) *buf = sign; ++buf; } if (type & SPECIAL) { if (base==8) { - if (buf <= end) + if (buf < end) *buf = '0'; ++buf; } else if (base==16) { - if (buf <= end) + if (buf < end) *buf = '0'; ++buf; - if (buf <= end) + if (buf < end) *buf = digits[33]; ++buf; } } if (!(type & LEFT)) { while (size-- > 0) { - if (buf <= end) + if (buf < end) *buf = c; ++buf; } } while (i < precision--) { - if (buf <= end) + if (buf < end) *buf = '0'; ++buf; } while (i-- > 0) { - if (buf <= end) + if (buf < end) *buf = tmp[i]; ++buf; } while (size-- > 0) { - if (buf <= end) + if (buf < end) *buf = ' '; ++buf; } @@ -272,7 +272,8 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) /* 'z' changed to 'Z' --davidm 1/25/99 */ /* 't' added for ptrdiff_t */ - /* Reject out-of-range values early */ + /* Reject out-of-range values early. Large positive sizes are + used for unknown buffer sizes. */ if (unlikely((int) size < 0)) { /* There can be only one.. */ static int warn = 1; @@ -282,16 +283,17 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) } str = buf; - end = buf + size - 1; + end = buf + size; - if (end < buf - 1) { - end = ((void *) -1); - size = end - buf + 1; + /* Make sure end is always >= buf */ + if (end < buf) { + end = ((void *)-1); + size = end - buf; } for (; *fmt ; ++fmt) { if (*fmt != '%') { - if (str <= end) + if (str < end) *str = *fmt; ++str; continue; @@ -357,17 +359,17 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) case 'c': if (!(flags & LEFT)) { while (--field_width > 0) { - if (str <= end) + if (str < end) *str = ' '; ++str; } } c = (unsigned char) va_arg(args, int); - if (str <= end) + if (str < end) *str = c; ++str; while (--field_width > 0) { - if (str <= end) + if (str < end) *str = ' '; ++str; } @@ -382,18 +384,18 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) if (!(flags & LEFT)) { while (len < field_width--) { - if (str <= end) + if (str < end) *str = ' '; ++str; } } for (i = 0; i < len; ++i) { - if (str <= end) + if (str < end) *str = *s; ++str; ++s; } while (len < field_width--) { - if (str <= end) + if (str < end) *str = ' '; ++str; } @@ -426,7 +428,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) continue; case '%': - if (str <= end) + if (str < end) *str = '%'; ++str; continue; @@ -449,11 +451,11 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) break; default: - if (str <= end) + if (str < end) *str = '%'; ++str; if (*fmt) { - if (str <= end) + if (str < end) *str = *fmt; ++str; } else { @@ -483,14 +485,13 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) str = number(str, end, num, base, field_width, precision, flags); } - if (str <= end) - *str = '\0'; - else if (size > 0) - /* don't write out a null byte if the buf size is zero */ - *end = '\0'; - /* the trailing null byte doesn't count towards the total - * ++str; - */ + if (size > 0) { + if (str < end) + *str = '\0'; + else + *end = '\0'; + } + /* the trailing null byte doesn't count towards the total */ return str-buf; } @@ -848,3 +849,26 @@ int sscanf(const char * buf, const char * fmt, ...) } EXPORT_SYMBOL(sscanf); + + +/* Simplified asprintf. */ +char *kasprintf(gfp_t gfp, const char *fmt, ...) +{ + va_list ap; + unsigned int len; + char *p; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + p = kmalloc(len+1, gfp); + if (!p) + return NULL; + va_start(ap, fmt); + vsnprintf(p, len+1, fmt, ap); + va_end(ap); + return p; +} + +EXPORT_SYMBOL(kasprintf); |