Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  linux/lib/kasprintf.c
0004  *
0005  *  Copyright (C) 1991, 1992  Linus Torvalds
0006  */
0007 
0008 #include <linux/stdarg.h>
0009 #include <linux/export.h>
0010 #include <linux/slab.h>
0011 #include <linux/types.h>
0012 #include <linux/string.h>
0013 
0014 /* Simplified asprintf. */
0015 char *kvasprintf(gfp_t gfp, const char *fmt, va_list ap)
0016 {
0017     unsigned int first, second;
0018     char *p;
0019     va_list aq;
0020 
0021     va_copy(aq, ap);
0022     first = vsnprintf(NULL, 0, fmt, aq);
0023     va_end(aq);
0024 
0025     p = kmalloc_track_caller(first+1, gfp);
0026     if (!p)
0027         return NULL;
0028 
0029     second = vsnprintf(p, first+1, fmt, ap);
0030     WARN(first != second, "different return values (%u and %u) from vsnprintf(\"%s\", ...)",
0031          first, second, fmt);
0032 
0033     return p;
0034 }
0035 EXPORT_SYMBOL(kvasprintf);
0036 
0037 /*
0038  * If fmt contains no % (or is exactly %s), use kstrdup_const. If fmt
0039  * (or the sole vararg) points to rodata, we will then save a memory
0040  * allocation and string copy. In any case, the return value should be
0041  * freed using kfree_const().
0042  */
0043 const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list ap)
0044 {
0045     if (!strchr(fmt, '%'))
0046         return kstrdup_const(fmt, gfp);
0047     if (!strcmp(fmt, "%s"))
0048         return kstrdup_const(va_arg(ap, const char*), gfp);
0049     return kvasprintf(gfp, fmt, ap);
0050 }
0051 EXPORT_SYMBOL(kvasprintf_const);
0052 
0053 char *kasprintf(gfp_t gfp, const char *fmt, ...)
0054 {
0055     va_list ap;
0056     char *p;
0057 
0058     va_start(ap, fmt);
0059     p = kvasprintf(gfp, fmt, ap);
0060     va_end(ap);
0061 
0062     return p;
0063 }
0064 EXPORT_SYMBOL(kasprintf);