lstat_cache(): print a warning if doing ping-pong between cache types
[gitweb.git] / abspath.c
index 0d561246e0a958d9a7284409b1900a82876eebf3..649f34f83365db3513c5166b897c4f033831444d 100644 (file)
--- a/abspath.c
+++ b/abspath.c
@@ -1,5 +1,16 @@
 #include "cache.h"
 
+/*
+ * Do not use this for inspecting *tracked* content.  When path is a
+ * symlink to a directory, we do not want to say it is a directory when
+ * dealing with tracked content in the working tree.
+ */
+int is_directory(const char *path)
+{
+       struct stat st;
+       return (!stat(path, &st) && S_ISDIR(st.st_mode));
+}
+
 /* We allow "recursive" symbolic links. Only within reason, though. */
 #define MAXDEPTH 5
 
@@ -17,7 +28,7 @@ const char *make_absolute_path(const char *path)
                die ("Too long path: %.*s", 60, path);
 
        while (depth--) {
-               if (stat(buf, &st) || !S_ISDIR(st.st_mode)) {
+               if (!is_directory(buf)) {
                        char *last_slash = strrchr(buf, '/');
                        if (last_slash) {
                                *last_slash = '\0';
@@ -53,6 +64,8 @@ const char *make_absolute_path(const char *path)
                        len = readlink(buf, next_buf, PATH_MAX);
                        if (len < 0)
                                die ("Invalid symlink: %s", buf);
+                       if (PATH_MAX <= len)
+                               die("symbolic link too long: %s", buf);
                        next_buf[len] = '\0';
                        buf = next_buf;
                        buf_index = 1 - buf_index;