alistair23-linux/tools/perf/util/pager.c
Michael Lentine 21cfc5e103 perf tools: Add cat as fallback pager
This patch adds a fallback to cat for the pager. This is useful
on environments, such as Android, where less does not exist.
It is better to default to cat than to abort.

Signed-off-by: Michael Lentine <mlentine@google.com>
Reviewed-by: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1400579330-5043-2-git-send-email-eranian@google.com
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
2014-05-21 11:48:33 +02:00

101 lines
2 KiB
C

#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");
if (!(pager || access("/usr/bin/pager", X_OK)))
pager = "/usr/bin/pager";
if (!(pager || access("/usr/bin/less", X_OK)))
pager = "/usr/bin/less";
if (!pager)
pager = "cat";
if (!*pager || !strcmp(pager, "cat"))
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;
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;
}