[PATCH/RFC] Fix for default pager

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



All commands using pager:

Default pager was 'less' even when some systems such AIX and other basic
or old systems do NOT have 'less' installed. In such case, git just
does not display anything in pager-enabled functionalities such as 'git log'
or 'git show', exiting with status 0.

With this patch, git will not use DEFAULT_PAGER macro anymore, instead,
git will look for 'less' and 'more' in the most common paths.
If there is no pager, returns NULL as if it's 'cat'.

Obviously, the commit message needs to be rewritten :p

Signed-off-by: Dario Rodriguez <soft.d4rio@xxxxxxxxx>
---
 pager.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/pager.c b/pager.c
index dac358f..3cfbd73 100644
--- a/pager.c
+++ b/pager.c
@@ -2,10 +2,19 @@
 #include "run-command.h"
 #include "sigchain.h"
 
-#ifndef DEFAULT_PAGER
-#define DEFAULT_PAGER "less"
+#ifndef GIT_PAGER_ENVIRONMENT
+#define GIT_PAGER_ENVIRONMENT "GIT_PAGER"
 #endif
 
+#ifndef GIT_PGR_LOOKUP_DBG_ENVIRONMENT
+#define GIT_PGR_LOOKUP_DBG_ENVIRONMENT "GIT_PAGER_LOOKUP_DEBUG"
+#endif
+
+#ifndef PAGER_ENVIRONMENT
+#define PAGER_ENVIRONMENT "PAGER"
+#endif
+
+
 /*
  * This is split up from the rest of git so that we can do
  * something different on Windows.
@@ -48,23 +57,80 @@ static void wait_for_pager_signal(int signo)
 	raise(signo);
 }
 
-const char *git_pager(int stdout_is_tty)
+static int is_executable(const char *name)
+{
+	struct stat st;
+
+	if (stat(name, &st) ||
+	    !S_ISREG(st.st_mode))
+		return 0;
+
+#ifdef WIN32
+{	/* cannot trust the executable bit, peek into the file instead */
+	char buf[3] = { 0 };
+	int n;
+	int fd = open(name, O_RDONLY);
+	st.st_mode &= ~S_IXUSR;
+	if (fd >= 0) {
+		n = read(fd, buf, 2);
+		if (n == 2)
+			/* DOS executables start with "MZ" */
+			if (!strcmp(buf, "#!") || !strcmp(buf, "MZ"))
+				st.st_mode |= S_IXUSR;
+		close(fd);
+	}
+}
+#endif
+	return st.st_mode & S_IXUSR;
+}
+
+const char *git_pager(int stdout_is_tty) 
 {
+	static const char *pager_bins[] =
+		{ "less", "more", NULL };
+	static const char *common_binary_paths[] =
+		{ "/bin/","/usr/bin/","/usr/local/bin/",NULL };
+
 	const char *pager;
+	char **p1,**p2,*pager_heap;
+	char exe_name[255];
+	int pager_lkp_dbg=0;
 
 	if (!stdout_is_tty)
 		return NULL;
 
-	pager = getenv("GIT_PAGER");
+	if(getenv(GIT_PGR_LOOKUP_DBG_ENVIRONMENT))
+		pager_lkp_dbg=1;
+
+	memset( exe_name,0,255 );
+	pager = getenv(GIT_PAGER_ENVIRONMENT);
 	if (!pager) {
 		if (!pager_program)
 			git_config(git_default_config, NULL);
 		pager = pager_program;
 	}
 	if (!pager)
-		pager = getenv("PAGER");
-	if (!pager)
-		pager = DEFAULT_PAGER;
+		pager = getenv(PAGER_ENVIRONMENT);
+	if (!pager) {
+
+		for (p1=(char**)pager_bins; (*p1)&&(!pager)
+			;p1++)
+			for (p2=(char**)common_binary_paths; (*p2)&&(!pager)
+				;p2++) {
+				sprintf( exe_name,"%s%s",
+					 *p2,*p1 );
+				if (is_executable(exe_name)) {
+					pager_heap = (char*) malloc(sizeof(exe_name));
+					strcpy(pager_heap,exe_name);
+					pager = pager_heap;
+				}
+			}
+
+		if (pager_lkp_dbg)
+			fprintf(stderr, "Debug: Lookup for existent pagers, got [%s]\n",
+				(pager==NULL)?"(null)":pager);
+
+	}
 	else if (!*pager || !strcmp(pager, "cat"))
 		pager = NULL;
 
-- 
1.7.1.245.g7c42e.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]