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