]> Sergey Matveev's repositories - nnn.git/commitdiff
Refactor dentfill()
authorArun Prakash Jana <engineerarun@gmail.com>
Sat, 27 Apr 2019 10:42:11 +0000 (16:12 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Sat, 27 Apr 2019 13:00:44 +0000 (18:30 +0530)
src/nnn.c

index c14f68cb246d183c45df4113c52ad7bc615f123a..e5babc8945fc139952a84dfbd7edb5bd0bb55b32 100644 (file)
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -2637,7 +2637,7 @@ static void dentfree(void)
 
 static int dentfill(char *path, struct entry **dents)
 {
-       int n = 0, count;
+       int n = 0, count, flags = 0;
        ulong num_saved;
        struct dirent *dp;
        char *namep, *pnb;
@@ -2667,7 +2667,22 @@ static int dentfill(char *path, struct entry **dents)
                        open_max = max_openfds();
        }
 
-       while ((dp = readdir(dirp))) {
+       dp = readdir(dirp);
+       // if (!dp) /* We have opened the dir, at least . would be returned */
+       //      goto exit;
+
+       if (cfg.blkorder || dp->d_type == DT_UNKNOWN) {
+               /*
+                * Optimization added for filesystems which support dirent.d_type
+                * see readdir(3)
+                * Known drawbacks:
+                * - the symlink size is set to 0
+                * - the modification time of the symlink is set to that of the target file
+                */
+               flags = AT_SYMLINK_NOFOLLOW;
+       }
+
+       do {
                namep = dp->d_name;
 
                /* Skip self and parent */
@@ -2711,7 +2726,7 @@ static int dentfill(char *path, struct entry **dents)
                        continue;
                }
 
-               if (fstatat(fd, namep, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
+               if (fstatat(fd, namep, &sb, flags) == -1) {
                        DPRINTF_S(namep);
                        continue;
                }
@@ -2760,9 +2775,14 @@ static int dentfill(char *path, struct entry **dents)
                off += dentp->nlen;
 
                /* Copy other fields */
-               dentp->mode = sb.st_mode;
                dentp->t = sb.st_mtime;
-               dentp->size = sb.st_size;
+               if (dp->d_type == DT_LNK && !flags) { /* Do not add sizes for links */
+                       dentp->mode = (sb.st_mode & ~S_IFMT) | S_IFLNK;
+                       dentp->size = 0;
+               } else {
+                       dentp->mode = sb.st_mode;
+                       dentp->size = sb.st_size;
+               }
                dentp->flags = 0;
 
                if (cfg.blkorder) {
@@ -2796,18 +2816,22 @@ static int dentfill(char *path, struct entry **dents)
                        }
                }
 
-               /* Flag if this is a dir or symlink to a dir */
-               if (S_ISLNK(sb.st_mode)) {
-                       sb.st_mode = 0;
-                       fstatat(fd, namep, &sb, 0);
-               }
+               if (flags) {
+                       /* Flag if this is a dir or symlink to a dir */
+                       if (S_ISLNK(sb.st_mode)) {
+                               sb.st_mode = 0;
+                               fstatat(fd, namep, &sb, 0);
+                       }
 
-               if (S_ISDIR(sb.st_mode))
+                       if (S_ISDIR(sb.st_mode))
+                               dentp->flags |= DIR_OR_LINK_TO_DIR;
+               } else if (dp->d_type == DT_DIR || (dp->d_type == DT_LNK && S_ISDIR(sb.st_mode)))
                        dentp->flags |= DIR_OR_LINK_TO_DIR;
 
                ++n;
-       }
+       } while ((dp = readdir(dirp)));
 
+//exit:
        /* Should never be null */
        if (closedir(dirp) == -1) {
                dentfree();