pager.con commit merge-recursive: don't segfault while handling rename clashes (c94736a)
   1#include "cache.h"
   2#include "run-command.h"
   3
   4/*
   5 * This is split up from the rest of git so that we can do
   6 * something different on Windows.
   7 */
   8
   9static int spawned_pager;
  10
  11#ifndef __MINGW32__
  12static void pager_preexec(void)
  13{
  14        /*
  15         * Work around bug in "less" by not starting it until we
  16         * have real input
  17         */
  18        fd_set in;
  19
  20        FD_ZERO(&in);
  21        FD_SET(0, &in);
  22        select(1, &in, NULL, &in, NULL);
  23
  24        setenv("LESS", "FRSX", 0);
  25}
  26#endif
  27
  28static const char *pager_argv[] = { "sh", "-c", NULL, NULL };
  29static struct child_process pager_process;
  30
  31static void wait_for_pager(void)
  32{
  33        fflush(stdout);
  34        fflush(stderr);
  35        /* signal EOF to pager */
  36        close(1);
  37        close(2);
  38        finish_command(&pager_process);
  39}
  40
  41void setup_pager(void)
  42{
  43        const char *pager = getenv("GIT_PAGER");
  44
  45        if (!isatty(1))
  46                return;
  47        if (!pager) {
  48                if (!pager_program)
  49                        git_config(git_default_config, NULL);
  50                pager = pager_program;
  51        }
  52        if (!pager)
  53                pager = getenv("PAGER");
  54        if (!pager)
  55                pager = "less";
  56        else if (!*pager || !strcmp(pager, "cat"))
  57                return;
  58
  59        spawned_pager = 1; /* means we are emitting to terminal */
  60
  61        /* spawn the pager */
  62        pager_argv[2] = pager;
  63        pager_process.argv = pager_argv;
  64        pager_process.in = -1;
  65#ifndef __MINGW32__
  66        pager_process.preexec_cb = pager_preexec;
  67#endif
  68        if (start_command(&pager_process))
  69                return;
  70
  71        /* original process continues, but writes to the pipe */
  72        dup2(pager_process.in, 1);
  73        if (isatty(2))
  74                dup2(pager_process.in, 2);
  75        close(pager_process.in);
  76
  77        /* this makes sure that the parent terminates after the pager */
  78        atexit(wait_for_pager);
  79}
  80
  81int pager_in_use(void)
  82{
  83        const char *env;
  84
  85        if (spawned_pager)
  86                return 1;
  87
  88        env = getenv("GIT_PAGER_IN_USE");
  89        return env ? git_config_bool("GIT_PAGER_IN_USE", env) : 0;
  90}