2007-07-18 05:37:02 +04:00
/*
* Helper function for splitting a string into an argv - like array .
*/
# include <linux/kernel.h>
# include <linux/ctype.h>
2009-12-15 05:01:06 +03:00
# include <linux/string.h>
2007-10-20 02:25:12 +04:00
# include <linux/slab.h>
2011-11-17 06:29:17 +04:00
# include <linux/export.h>
2007-07-18 05:37:02 +04:00
static const char * skip_arg ( const char * cp )
{
while ( * cp & & ! isspace ( * cp ) )
cp + + ;
return cp ;
}
static int count_argc ( const char * str )
{
int count = 0 ;
while ( * str ) {
2009-12-15 05:01:06 +03:00
str = skip_spaces ( str ) ;
2007-07-18 05:37:02 +04:00
if ( * str ) {
count + + ;
str = skip_arg ( str ) ;
}
}
return count ;
}
/**
* argv_free - free an argv
* @ argv - the argument vector to be freed
*
* Frees an argv and the strings it points to .
*/
void argv_free ( char * * argv )
{
char * * p ;
for ( p = argv ; * p ; p + + )
kfree ( * p ) ;
kfree ( argv ) ;
}
EXPORT_SYMBOL ( argv_free ) ;
/**
* argv_split - split a string at whitespace , returning an argv
* @ gfp : the GFP mask used to allocate memory
* @ str : the string to be split
* @ argcp : returned argument count
*
* Returns an array of pointers to strings which are split out from
* @ str . This is performed by strictly splitting on white - space ; no
* quote processing is performed . Multiple whitespace characters are
* considered to be a single argument separator . The returned array
* is always NULL - terminated . Returns NULL on memory allocation
* failure .
*/
char * * argv_split ( gfp_t gfp , const char * str , int * argcp )
{
int argc = count_argc ( str ) ;
char * * argv = kzalloc ( sizeof ( * argv ) * ( argc + 1 ) , gfp ) ;
char * * argvp ;
if ( argv = = NULL )
goto out ;
2007-10-17 10:26:33 +04:00
if ( argcp )
* argcp = argc ;
2007-07-18 05:37:02 +04:00
argvp = argv ;
while ( * str ) {
2009-12-15 05:01:06 +03:00
str = skip_spaces ( str ) ;
2007-07-18 05:37:02 +04:00
if ( * str ) {
const char * p = str ;
char * t ;
str = skip_arg ( str ) ;
t = kstrndup ( p , str - p , gfp ) ;
if ( t = = NULL )
goto fail ;
* argvp + + = t ;
}
}
* argvp = NULL ;
out :
return argv ;
fail :
argv_free ( argv ) ;
return NULL ;
}
EXPORT_SYMBOL ( argv_split ) ;