1 /* 2 * linux/lib/kasprintf.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 */ 6 7 #include <stdarg.h> 8 #include <linux/export.h> 9 #include <linux/slab.h> 10 #include <linux/types.h> 11 #include <linux/string.h> 12 13 /* Simplified asprintf. */ 14 char *kvasprintf(gfp_t gfp, const char *fmt, va_list ap) 15 { 16 unsigned int first, second; 17 char *p; 18 va_list aq; 19 20 va_copy(aq, ap); 21 first = vsnprintf(NULL, 0, fmt, aq); 22 va_end(aq); 23 24 p = kmalloc_track_caller(first+1, gfp); 25 if (!p) 26 return NULL; 27 28 second = vsnprintf(p, first+1, fmt, ap); 29 WARN(first != second, "different return values (%u and %u) from vsnprintf(\"%s\", ...)", 30 first, second, fmt); 31 32 return p; 33 } 34 EXPORT_SYMBOL(kvasprintf); 35 36 /* 37 * If fmt contains no % (or is exactly %s), use kstrdup_const. If fmt 38 * (or the sole vararg) points to rodata, we will then save a memory 39 * allocation and string copy. In any case, the return value should be 40 * freed using kfree_const(). 41 */ 42 const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list ap) 43 { 44 if (!strchr(fmt, '%')) 45 return kstrdup_const(fmt, gfp); 46 if (!strcmp(fmt, "%s")) 47 return kstrdup_const(va_arg(ap, const char*), gfp); 48 return kvasprintf(gfp, fmt, ap); 49 } 50 EXPORT_SYMBOL(kvasprintf_const); 51 52 char *kasprintf(gfp_t gfp, const char *fmt, ...) 53 { 54 va_list ap; 55 char *p; 56 57 va_start(ap, fmt); 58 p = kvasprintf(gfp, fmt, ap); 59 va_end(ap); 60 61 return p; 62 } 63 EXPORT_SYMBOL(kasprintf); 64