diff options
author | Ian Campbell <ian.campbell@xensource.com> | 2006-11-27 13:50:02 +0000 |
---|---|---|
committer | Ian Campbell <ian.campbell@xensource.com> | 2006-11-27 13:50:02 +0000 |
commit | b23fab8e20f28f83b51a0cf64a921e817375fce3 (patch) | |
tree | e182097b298df7ad06ee9049514dad9c87133e7a /patches | |
parent | 821b3ff18b15be67d262771a7104dbaf67d6d6ba (diff) | |
download | xen-b23fab8e20f28f83b51a0cf64a921e817375fce3.tar.gz xen-b23fab8e20f28f83b51a0cf64a921e817375fce3.tar.bz2 xen-b23fab8e20f28f83b51a0cf64a921e817375fce3.zip |
[LINUX] Import kasprintf patch from upstream.
kasprintf has been merged upstream with a slightly different protoype
to the one in Xen. Import this patch and fixup the Xen tree to fit.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
Diffstat (limited to 'patches')
-rw-r--r-- | patches/linux-2.6.16.32/kasprintf.patch | 59 | ||||
-rw-r--r-- | patches/linux-2.6.16.32/series | 2 | ||||
-rw-r--r-- | patches/linux-2.6.16.32/vsnprintf.patch | 211 |
3 files changed, 272 insertions, 0 deletions
diff --git a/patches/linux-2.6.16.32/kasprintf.patch b/patches/linux-2.6.16.32/kasprintf.patch new file mode 100644 index 0000000000..03e8c07ccf --- /dev/null +++ b/patches/linux-2.6.16.32/kasprintf.patch @@ -0,0 +1,59 @@ +commit e905914f96e11862b130dd229f73045dad9a34e8 +Author: Jeremy Fitzhardinge <jeremy@xensource.com> +Date: Sun Jun 25 05:49:17 2006 -0700 + + [PATCH] Implement kasprintf + + Implement kasprintf, a kernel version of asprintf. This allocates the + memory required for the formatted string, including the trailing '\0'. + Returns NULL on allocation failure. + + Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> + Signed-off-by: Chris Wright <chrisw@sous-sol.org> + Signed-off-by: Andrew Morton <akpm@osdl.org> + Signed-off-by: Linus Torvalds <torvalds@osdl.org> + +diff --git a/include/linux/kernel.h b/include/linux/kernel.h +index 8c21aaa..3c5e4c2 100644 +--- a/include/linux/kernel.h ++++ b/include/linux/kernel.h +@@ -117,6 +117,8 @@ extern int scnprintf(char * buf, size_t + __attribute__ ((format (printf, 3, 4))); + extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) + __attribute__ ((format (printf, 3, 0))); ++extern char *kasprintf(gfp_t gfp, const char *fmt, ...) ++ __attribute__ ((format (printf, 2, 3))); + + extern int sscanf(const char *, const char *, ...) + __attribute__ ((format (scanf, 2, 3))); +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index f595947..797428a 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -849,3 +849,26 @@ int sscanf(const char * buf, const char + } + + 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); diff --git a/patches/linux-2.6.16.32/series b/patches/linux-2.6.16.32/series index ae8fbd2885..ef2c35842e 100644 --- a/patches/linux-2.6.16.32/series +++ b/patches/linux-2.6.16.32/series @@ -23,3 +23,5 @@ xenoprof-generic.patch x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch x86-elfnote-as-preprocessor-macro.patch +vsnprintf.patch +kasprintf.patch diff --git a/patches/linux-2.6.16.32/vsnprintf.patch b/patches/linux-2.6.16.32/vsnprintf.patch new file mode 100644 index 0000000000..69a93fa5c5 --- /dev/null +++ b/patches/linux-2.6.16.32/vsnprintf.patch @@ -0,0 +1,211 @@ +commit f796937a062c7aeb44cd0e75e1586c8543634a7d +Author: Jeremy Fitzhardinge <jeremy@xensource.com> +Date: Sun Jun 25 05:49:17 2006 -0700 + + [PATCH] Fix bounds check in vsnprintf, to allow for a 0 size and NULL buffer + + This change allows callers to use a 0-byte buffer and a NULL buffer pointer + with vsnprintf, so it can be used to determine how large the resulting + formatted string will be. + + Previously the code effectively treated a size of 0 as a size of 4G (on + 32-bit systems), with other checks preventing it from actually trying to + emit the string - but the terminal \0 would still be written, which would + crash if the buffer is NULL. + + This change changes the boundary check so that 'end' points to the putative + location of the terminal '\0', which is only written if size > 0. + + vsnprintf still allows the buffer size to be set very large, to allow + unbounded buffer sizes (to implement sprintf, etc). + + [akpm@osdl.org: fix long-vs-longlong confusion] + Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> + Signed-off-by: Chris Wright <chrisw@sous-sol.org> + Signed-off-by: Andrew Morton <akpm@osdl.org> + Signed-off-by: Linus Torvalds <torvalds@osdl.org> + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index b07db5c..f595947 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -187,49 +187,49 @@ static char * number(char * buf, char * + 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, co + /* '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, co + } + + 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, co + 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, co + + 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, co + continue; + + case '%': +- if (str <= end) ++ if (str < end) + *str = '%'; + ++str; + continue; +@@ -449,11 +451,11 @@ int vsnprintf(char *buf, size_t size, co + 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, co + 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; + } + |