]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - lib/kasprintf.c
x86: provide an init_mem_mapping hypervisor hook
[karo-tx-linux.git] / lib / kasprintf.c
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);