Add kmem_vasprintf function

We might as well have both asprintf() variants.  This allows us
to safely pass a va_list through several levels of the stack
using va_copy() instead of va_start().
This commit is contained in:
Brian Behlendorf 2010-06-24 09:41:59 -07:00
parent 438683c0a9
commit e6de04b73c
2 changed files with 22 additions and 5 deletions

View File

@ -248,6 +248,7 @@ enum {
#define KMC_DEFAULT_SEEKS 1 #define KMC_DEFAULT_SEEKS 1
extern int kmem_debugging(void); extern int kmem_debugging(void);
extern char *kmem_vasprintf(const char *fmt, va_list ap);
extern char *kmem_asprintf(const char *fmt, ...); extern char *kmem_asprintf(const char *fmt, ...);
#define strfree(str) kfree(str) #define strfree(str) kfree(str)
#define strdup(str) kstrdup(str, GFP_KERNEL) #define strdup(str) kstrdup(str, GFP_KERNEL)

View File

@ -239,16 +239,32 @@ EXPORT_SYMBOL(kvasprintf);
#endif /* HAVE_KVASPRINTF */ #endif /* HAVE_KVASPRINTF */
char * char *
kmem_asprintf(const char *fmt, ...) kmem_vasprintf(const char *fmt, va_list ap)
{ {
va_list args; va_list aq;
char *ptr; char *ptr;
va_start(args, fmt); va_copy(aq, ap);
do { do {
ptr = kvasprintf(GFP_KERNEL, fmt, args); ptr = kvasprintf(GFP_KERNEL, fmt, aq);
} while (ptr == NULL); } while (ptr == NULL);
va_end(args); va_end(aq);
return ptr;
}
EXPORT_SYMBOL(kmem_vasprintf);
char *
kmem_asprintf(const char *fmt, ...)
{
va_list ap;
char *ptr;
va_start(ap, fmt);
do {
ptr = kvasprintf(GFP_KERNEL, fmt, ap);
} while (ptr == NULL);
va_end(ap);
return ptr; return ptr;
} }