2009-05-27 11:50:13 +04:00
# include "cache.h"
# include "run-command.h"
# include "sigchain.h"
/*
* This is split up from the rest of git so that we can do
* something different on Windows .
*/
static int spawned_pager ;
static void pager_preexec ( void )
{
/*
* Work around bug in " less " by not starting it until we
* have real input
*/
fd_set in ;
FD_ZERO ( & in ) ;
FD_SET ( 0 , & in ) ;
select ( 1 , & in , NULL , & in , NULL ) ;
setenv ( " LESS " , " FRSX " , 0 ) ;
}
static const char * pager_argv [ ] = { " sh " , " -c " , NULL , NULL } ;
static struct child_process pager_process ;
static void wait_for_pager ( void )
{
fflush ( stdout ) ;
fflush ( stderr ) ;
/* signal EOF to pager */
close ( 1 ) ;
close ( 2 ) ;
finish_command ( & pager_process ) ;
}
static void wait_for_pager_signal ( int signo )
{
wait_for_pager ( ) ;
sigchain_pop ( signo ) ;
raise ( signo ) ;
}
void setup_pager ( void )
{
const char * pager = getenv ( " PERF_PAGER " ) ;
if ( ! isatty ( 1 ) )
return ;
if ( ! pager ) {
if ( ! pager_program )
perf_config ( perf_default_config , NULL ) ;
pager = pager_program ;
}
if ( ! pager )
pager = getenv ( " PAGER " ) ;
2014-05-20 13:48:49 +04:00
if ( ! ( pager | | access ( " /usr/bin/pager " , X_OK ) ) )
pager = " /usr/bin/pager " ;
if ( ! ( pager | | access ( " /usr/bin/less " , X_OK ) ) )
pager = " /usr/bin/less " ;
2009-05-27 11:50:13 +04:00
if ( ! pager )
2014-05-20 13:48:49 +04:00
pager = " cat " ;
if ( ! * pager | | ! strcmp ( pager , " cat " ) )
2009-05-27 11:50:13 +04:00
return ;
spawned_pager = 1 ; /* means we are emitting to terminal */
/* spawn the pager */
pager_argv [ 2 ] = pager ;
pager_process . argv = pager_argv ;
pager_process . in = - 1 ;
pager_process . preexec_cb = pager_preexec ;
2009-06-27 08:06:39 +04:00
2009-05-27 11:50:13 +04:00
if ( start_command ( & pager_process ) )
return ;
/* original process continues, but writes to the pipe */
dup2 ( pager_process . in , 1 ) ;
if ( isatty ( 2 ) )
dup2 ( pager_process . in , 2 ) ;
close ( pager_process . in ) ;
/* this makes sure that the parent terminates after the pager */
sigchain_push_common ( wait_for_pager_signal ) ;
atexit ( wait_for_pager ) ;
}
int pager_in_use ( void )
{
const char * env ;
if ( spawned_pager )
return 1 ;
env = getenv ( " PERF_PAGER_IN_USE " ) ;
return env ? perf_config_bool ( " PERF_PAGER_IN_USE " , env ) : 0 ;
}