65 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * linux/lib/kasprintf.c4 *5 * Copyright (C) 1991, 1992 Linus Torvalds6 */7 8#include <linux/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. */15char *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 va_copy(aq, ap);22 first = vsnprintf(NULL, 0, fmt, aq);23 va_end(aq);24 25 p = kmalloc_track_caller(first+1, gfp);26 if (!p)27 return NULL;28 29 second = vsnprintf(p, first+1, fmt, ap);30 WARN(first != second, "different return values (%u and %u) from vsnprintf(\"%s\", ...)",31 first, second, fmt);32 33 return p;34}35EXPORT_SYMBOL(kvasprintf);36 37/*38 * If fmt contains no % (or is exactly %s), use kstrdup_const. If fmt39 * (or the sole vararg) points to rodata, we will then save a memory40 * allocation and string copy. In any case, the return value should be41 * freed using kfree_const().42 */43const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list ap)44{45 if (!strchr(fmt, '%'))46 return kstrdup_const(fmt, gfp);47 if (!strcmp(fmt, "%s"))48 return kstrdup_const(va_arg(ap, const char*), gfp);49 return kvasprintf(gfp, fmt, ap);50}51EXPORT_SYMBOL(kvasprintf_const);52 53char *kasprintf(gfp_t gfp, const char *fmt, ...)54{55 va_list ap;56 char *p;57 58 va_start(ap, fmt);59 p = kvasprintf(gfp, fmt, ap);60 va_end(ap);61 62 return p;63}64EXPORT_SYMBOL(kasprintf);65