summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--Src/hist.c47
-rw-r--r--configure.ac17
3 files changed, 42 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 8d639b52e..365abc7b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2014-11-30 Oliver Kiddle <opk@zsh.org>
+ * 33820: configure.ac, Src/hist.c: detect support for realpath()
+ with a NULL argument and fixes to the use of it
+
* 33800: Src/Zle/zle_main.c: remove old workaround for ancient
systems to consume typeahead before setting up the terminal
diff --git a/Src/hist.c b/Src/hist.c
index 083175640..7fe843a4a 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -1702,11 +1702,12 @@ int
chrealpath(char **junkptr)
{
char *str;
-#ifdef HAVE_CANONICALIZE_FILE_NAME
+#ifdef HAVE_REALPATH
+# ifdef REALPATH_ACCEPTS_NULL
char *lastpos, *nonreal, *real;
-#else
-# ifdef HAVE_REALPATH
- char *lastpos, *nonreal, real[PATH_MAX];
+# else
+ char *lastpos, *nonreal, pathbuf[PATH_MAX];
+ char *real = pathbuf;
# endif
#endif
@@ -1717,7 +1718,7 @@ chrealpath(char **junkptr)
if (!chabspath(junkptr))
return 0;
-#if !defined(HAVE_REALPATH) && !defined(HAVE_CANONICALIZE_FILE_NAME)
+#ifndef HAVE_REALPATH
return 1;
#else
/*
@@ -1733,29 +1734,21 @@ chrealpath(char **junkptr)
nonreal = lastpos + 1;
while (!
-#ifdef HAVE_CANONICALIZE_FILE_NAME
- /*
- * This is a GNU extension to realpath(); it's the
- * same as calling realpath() with a NULL second argument
- * which uses malloc() to get memory. The alternative
- * interface is easier to test for, however.
- */
- (real = canonicalize_file_name(*junkptr))
+#ifdef REALPATH_ACCEPTS_NULL
+ /* realpath() with a NULL second argument uses malloc() to get
+ * memory so we don't need to worry about overflowing PATH_MAX */
+ (real = realpath(*junkptr, NULL))
#else
realpath(*junkptr, real)
#endif
) {
- if (errno == EINVAL || errno == ELOOP ||
- errno == ENAMETOOLONG || errno == ENOMEM)
- return 0;
-
-#ifdef HAVE_CANONICALIZE_FILE_NAME
- if (!real)
+ if (errno == EINVAL || errno == ENOMEM)
return 0;
-#endif
if (nonreal == *junkptr) {
- *real = '\0';
+#ifndef REALPATH_ACCEPTS_NULL
+ real = NULL;
+#endif
break;
}
@@ -1771,11 +1764,15 @@ chrealpath(char **junkptr)
str++;
}
- *junkptr = metafy(str = bicat(real, nonreal), -1, META_HEAPDUP);
- zsfree(str);
-#ifdef HAVE_CANONICALIZE_FILE_NAME
- free(real);
+ if (real) {
+ *junkptr = metafy(str = bicat(real, nonreal), -1, META_HEAPDUP);
+ zsfree(str);
+#ifdef REALPATH_ACCEPTS_NULL
+ free(real);
#endif
+ } else {
+ *junkptr = metafy(nonreal, lastpos - nonreal + 1, META_HEAPDUP);
+ }
#endif
return 1;
diff --git a/configure.ac b/configure.ac
index 56c4cfb13..8ea9737c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1302,6 +1302,23 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
cygwin_conv_path)
AC_FUNC_STRCOLL
+AH_TEMPLATE([REALPATH_ACCEPTS_NULL],
+[Define if realpath() accepts NULL as its second argument.])
+AC_CACHE_CHECK([if realpath accepts NULL],
+zsh_cv_func_realpath_accepts_null,
+[AC_RUN_IFELSE([AC_LANG_PROGRAM([
+#include <stdlib.h>
+#include <limits.h>
+],[
+exit(!realpath("/", (char*)0));
+])],
+[zsh_cv_func_realpath_accepts_null=yes],
+[zsh_cv_func_realpath_accepts_null=no],
+[zsh_cv_func_realpath_accepts_null=$ac_cv_func_canonicalize_file_name])])
+if test x$zsh_cv_func_realpath_accepts_null = xyes; then
+ AC_DEFINE(REALPATH_ACCEPTS_NULL)
+fi
+
if test x$enable_cap = xyes; then
AC_CHECK_FUNCS(cap_get_proc)
fi