aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Perches <joe@perches.com>2010-06-26 21:02:33 -0400
committerDavid S. Miller <davem@davemloft.net>2010-07-04 13:40:17 -0400
commit7db6f5fb65a82af03229eef104dc9899c5eecf33 (patch)
treefb7a83297d8bf2680df9616ebf58bec89229ff3b
parente490c1defec4236a6a131fe2d13bf7ba787c02f8 (diff)
vsprintf: Recursive vsnprintf: Add "%pV", struct va_format
Add the ability to print a format and va_list from a structure pointer Allows __dev_printk to be implemented as a single printk while minimizing string space duplication. %pV should not be used without some mechanism to verify the format and argument use ala __attribute__(format (printf(...))). Signed-off-by: Joe Perches <joe@perches.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/kernel.h5
-rw-r--r--lib/vsprintf.c9
2 files changed, 14 insertions, 0 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 8317ec4b9f3b..01dfc05ef4ac 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -171,6 +171,11 @@ static inline void might_fault(void)
171} 171}
172#endif 172#endif
173 173
174struct va_format {
175 const char *fmt;
176 va_list *va;
177};
178
174extern struct atomic_notifier_head panic_notifier_list; 179extern struct atomic_notifier_head panic_notifier_list;
175extern long (*panic_blink)(long time); 180extern long (*panic_blink)(long time);
176NORET_TYPE void panic(const char * fmt, ...) 181NORET_TYPE void panic(const char * fmt, ...)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index b8a2f549ab0e..4ee19d0d3910 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -980,6 +980,11 @@ char *uuid_string(char *buf, char *end, const u8 *addr,
980 * [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15] 980 * [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
981 * little endian output byte order is: 981 * little endian output byte order is:
982 * [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15] 982 * [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
983 * - 'V' For a struct va_format which contains a format string * and va_list *,
984 * call vsnprintf(->format, *->va_list).
985 * Implements a "recursive vsnprintf".
986 * Do not use this feature without some mechanism to verify the
987 * correctness of the format string and va_list arguments.
983 * 988 *
984 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 989 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
985 * function pointers are really function descriptors, which contain a 990 * function pointers are really function descriptors, which contain a
@@ -1025,6 +1030,10 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
1025 break; 1030 break;
1026 case 'U': 1031 case 'U':
1027 return uuid_string(buf, end, ptr, spec, fmt); 1032 return uuid_string(buf, end, ptr, spec, fmt);
1033 case 'V':
1034 return buf + vsnprintf(buf, end - buf,
1035 ((struct va_format *)ptr)->fmt,
1036 *(((struct va_format *)ptr)->va));
1028 } 1037 }
1029 spec.flags |= SMALL; 1038 spec.flags |= SMALL;
1030 if (spec.field_width == -1) { 1039 if (spec.field_width == -1) {