@ -17,11 +17,11 @@
# include "c.h"
# include "xalloc.h"
# include "nls.h"
# include "ttyutils.h"
# include "pager.h"
# define NULL_DEVICE " / dev / null"
void setup_pager ( void ) ;
static const char * pager_argv [ ] = { " sh " , " -c " , NULL , NULL } ;
struct child_process {
@ -30,6 +30,10 @@ struct child_process {
int in ;
int out ;
int err ;
int org_err ;
int org_out ;
unsigned no_stdin : 1 ;
void ( * preexec_cb ) ( void ) ;
} ;
@ -144,6 +148,9 @@ static void pager_preexec(void)
static void wait_for_pager ( void )
{
if ( pager_process . pid = = 0 )
return ;
fflush ( stdout ) ;
fflush ( stderr ) ;
/* signal EOF to pager */
@ -158,7 +165,7 @@ static void wait_for_pager_signal(int signo)
raise ( signo ) ;
}
void setup_pager ( void )
static void __ setup_pager( void )
{
const char * pager = getenv ( " PAGER " ) ;
@ -191,10 +198,50 @@ void setup_pager(void)
signal ( SIGTERM , wait_for_pager_signal ) ;
signal ( SIGQUIT , wait_for_pager_signal ) ;
signal ( SIGPIPE , wait_for_pager_signal ) ;
}
/* Setup pager and redirects output to the $PAGER. The pager is closed at exit.
*/
void pager_redirect ( void )
{
if ( pager_process . pid )
return ; /* already running */
__setup_pager ( ) ;
atexit ( wait_for_pager ) ;
}
/* Setup pager and redirect output, the pager may be closed by pager_close().
*/
void pager_open ( void )
{
if ( pager_process . pid )
return ; /* already running */
pager_process . org_out = dup ( STDOUT_FILENO ) ;
pager_process . org_err = dup ( STDERR_FILENO ) ;
__setup_pager ( ) ;
}
/* Close pager and restore original std{out,err}.
*/
void pager_close ( void )
{
if ( pager_process . pid = = 0 )
return ;
wait_for_pager ( ) ;
dup2 ( pager_process . org_out , STDOUT_FILENO ) ;
dup2 ( pager_process . org_err , STDERR_FILENO ) ;
close ( pager_process . org_out ) ;
close ( pager_process . org_err ) ;
memset ( & pager_process , 0 , sizeof ( pager_process ) ) ;
}
# ifdef TEST_PROGRAM
# define MAX 255
@ -204,7 +251,7 @@ int main(int argc __attribute__ ((__unused__)),
{
int i ;
setup_ pager( ) ;
pager_setup ( ) ;
for ( i = 0 ; i < MAX ; i + + )
printf ( " %d \n " , i ) ;
return EXIT_SUCCESS ;