2009-04-20 15:00:56 +02:00
# include "cache.h"
# include "exec_cmd.h"
# include "quote.h"
2015-12-15 09:39:35 -06:00
# include "subcmd-config.h"
2009-07-01 12:37:06 +02:00
# include <string.h>
2009-04-20 15:00:56 +02:00
# define MAX_ARGS 32
static const char * argv_exec_path ;
static const char * argv0_path ;
2015-12-15 09:39:35 -06:00
void exec_cmd_init ( const char * exec_name , const char * prefix ,
const char * exec_path , const char * exec_path_env )
{
subcmd_config . exec_name = exec_name ;
subcmd_config . prefix = prefix ;
subcmd_config . exec_path = exec_path ;
subcmd_config . exec_path_env = exec_path_env ;
}
2015-11-19 15:04:53 +09:00
char * system_path ( const char * path )
2009-04-20 15:00:56 +02:00
{
struct strbuf d = STRBUF_INIT ;
if ( is_absolute_path ( path ) )
2015-11-19 15:04:53 +09:00
return strdup ( path ) ;
2009-04-20 15:00:56 +02:00
2015-12-15 09:39:35 -06:00
strbuf_addf ( & d , " %s/%s " , subcmd_config . prefix , path ) ;
2009-04-20 15:00:56 +02:00
path = strbuf_detach ( & d , NULL ) ;
2015-11-19 15:04:53 +09:00
return ( char * ) path ;
2009-04-20 15:00:56 +02:00
}
const char * perf_extract_argv0_path ( const char * argv0 )
{
const char * slash ;
if ( ! argv0 | | ! * argv0 )
return NULL ;
slash = argv0 + strlen ( argv0 ) ;
while ( argv0 < = slash & & ! is_dir_sep ( * slash ) )
slash - - ;
if ( slash > = argv0 ) {
2010-05-18 18:54:30 -03:00
argv0_path = strndup ( argv0 , slash - argv0 ) ;
return argv0_path ? slash + 1 : NULL ;
2009-04-20 15:00:56 +02:00
}
return argv0 ;
}
void perf_set_argv_exec_path ( const char * exec_path )
{
argv_exec_path = exec_path ;
/*
* Propagate this setting to external programs .
*/
2015-12-15 09:39:35 -06:00
setenv ( subcmd_config . exec_path_env , exec_path , 1 ) ;
2009-04-20 15:00:56 +02:00
}
/* Returns the highest-priority, location to look for perf programs. */
2015-11-19 15:04:53 +09:00
char * perf_exec_path ( void )
2009-04-20 15:00:56 +02:00
{
2015-11-19 15:04:53 +09:00
char * env ;
2009-04-20 15:00:56 +02:00
if ( argv_exec_path )
2015-11-19 15:04:53 +09:00
return strdup ( argv_exec_path ) ;
2009-04-20 15:00:56 +02:00
2015-12-15 09:39:35 -06:00
env = getenv ( subcmd_config . exec_path_env ) ;
2015-11-19 15:04:53 +09:00
if ( env & & * env )
return strdup ( env ) ;
2009-04-20 15:00:56 +02:00
2015-12-15 09:39:35 -06:00
return system_path ( subcmd_config . exec_path ) ;
2009-04-20 15:00:56 +02:00
}
static void add_path ( struct strbuf * out , const char * path )
{
if ( path & & * path ) {
if ( is_absolute_path ( path ) )
strbuf_addstr ( out , path ) ;
else
strbuf_addstr ( out , make_nonrelative_path ( path ) ) ;
strbuf_addch ( out , PATH_SEP ) ;
}
}
void setup_path ( void )
{
const char * old_path = getenv ( " PATH " ) ;
struct strbuf new_path = STRBUF_INIT ;
2015-11-19 15:04:53 +09:00
char * tmp = perf_exec_path ( ) ;
2009-04-20 15:00:56 +02:00
2015-11-19 15:04:53 +09:00
add_path ( & new_path , tmp ) ;
2009-04-20 15:00:56 +02:00
add_path ( & new_path , argv0_path ) ;
2015-11-19 15:04:53 +09:00
free ( tmp ) ;
2009-04-20 15:00:56 +02:00
if ( old_path )
strbuf_addstr ( & new_path , old_path ) ;
else
strbuf_addstr ( & new_path , " /usr/local/bin:/usr/bin:/bin " ) ;
setenv ( " PATH " , new_path . buf , 1 ) ;
strbuf_release ( & new_path ) ;
}
2010-05-18 18:29:23 -03:00
static const char * * prepare_perf_cmd ( const char * * argv )
2009-04-20 15:00:56 +02:00
{
int argc ;
const char * * nargv ;
for ( argc = 0 ; argv [ argc ] ; argc + + )
; /* just counting */
nargv = malloc ( sizeof ( * nargv ) * ( argc + 2 ) ) ;
2015-12-15 09:39:35 -06:00
nargv [ 0 ] = subcmd_config . exec_name ;
2009-04-20 15:00:56 +02:00
for ( argc = 0 ; argv [ argc ] ; argc + + )
nargv [ argc + 1 ] = argv [ argc ] ;
nargv [ argc + 1 ] = NULL ;
return nargv ;
}
int execv_perf_cmd ( const char * * argv ) {
const char * * nargv = prepare_perf_cmd ( argv ) ;
/* execvp() can only ever return if it fails */
2015-12-15 09:39:35 -06:00
execvp ( subcmd_config . exec_name , ( char * * ) nargv ) ;
2009-04-20 15:00:56 +02:00
free ( nargv ) ;
return - 1 ;
}
int execl_perf_cmd ( const char * cmd , . . . )
{
int argc ;
const char * argv [ MAX_ARGS + 1 ] ;
const char * arg ;
va_list param ;
va_start ( param , cmd ) ;
argv [ 0 ] = cmd ;
argc = 1 ;
while ( argc < MAX_ARGS ) {
arg = argv [ argc + + ] = va_arg ( param , char * ) ;
if ( ! arg )
break ;
}
va_end ( param ) ;
if ( MAX_ARGS < = argc )
return error ( " too many args to run %s " , cmd ) ;
argv [ argc ] = NULL ;
return execv_perf_cmd ( argv ) ;
}