diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-05-05 23:16:01 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-05-05 23:16:01 -0400 |
commit | a3c1c3ed54d9d595feb1df38e775af3d6ff9facd (patch) | |
tree | 4d7347b1cc073be521cb8f0d6e5b36ab5e091021 | |
parent | df7d960b0d7e1f9bd8aa58654760e41b6282f78a (diff) | |
download | bfs-a3c1c3ed54d9d595feb1df38e775af3d6ff9facd.tar.xz |
color: Don't stat() if we don't need to
-rw-r--r-- | color.c | 70 | ||||
-rw-r--r-- | eval.c | 8 | ||||
-rwxr-xr-x | tests.sh | 10 | ||||
-rw-r--r-- | tests/test_color_L_no_stat.out | 20 | ||||
-rw-r--r-- | tests/test_color_no_stat.out | 20 |
5 files changed, 95 insertions, 33 deletions
@@ -551,28 +551,32 @@ static bool is_link_broken(const struct BFTW *ftwbuf) { /** Get the color for a file. */ static const char *file_color(const struct colors *colors, const char *filename, const struct BFTW *ftwbuf, enum bfs_stat_flag flags) { - const struct bfs_stat *sb = bftw_stat(ftwbuf, flags); - if (!sb) { - if (colors->missing) { - return colors->missing; - } else { - return colors->orphan; - } + enum bftw_typeflag typeflag = bftw_typeflag(ftwbuf, flags); + if (typeflag == BFTW_ERROR) { + goto error; } + const struct bfs_stat *statbuf = NULL; const char *color = NULL; - switch (sb->mode & S_IFMT) { - case S_IFREG: - if (colors->setuid && (sb->mode & 04000)) { + switch (typeflag) { + case BFTW_REG: + if (colors->setuid || colors->setgid || colors->executable || colors->multi_hard) { + statbuf = bftw_stat(ftwbuf, flags); + if (!statbuf) { + goto error; + } + } + + if (colors->setuid && (statbuf->mode & 04000)) { color = colors->setuid; - } else if (colors->setgid && (sb->mode & 02000)) { + } else if (colors->setgid && (statbuf->mode & 02000)) { color = colors->setgid; } else if (colors->capable && bfs_check_capabilities(ftwbuf)) { color = colors->capable; - } else if (colors->executable && (sb->mode & 00111)) { + } else if (colors->executable && (statbuf->mode & 00111)) { color = colors->executable; - } else if (colors->multi_hard && sb->nlink > 1) { + } else if (colors->multi_hard && statbuf->nlink > 1) { color = colors->multi_hard; } @@ -586,12 +590,19 @@ static const char *file_color(const struct colors *colors, const char *filename, break; - case S_IFDIR: - if (colors->sticky_other_writable && (sb->mode & 01002) == 01002) { + case BFTW_DIR: + if (colors->sticky_other_writable || colors->other_writable || colors->sticky) { + statbuf = bftw_stat(ftwbuf, flags); + if (!statbuf) { + goto error; + } + } + + if (colors->sticky_other_writable && (statbuf->mode & 01002) == 01002) { color = colors->sticky_other_writable; - } else if (colors->other_writable && (sb->mode & 00002)) { + } else if (colors->other_writable && (statbuf->mode & 00002)) { color = colors->other_writable; - } else if (colors->sticky && (sb->mode & 01000)) { + } else if (colors->sticky && (statbuf->mode & 01000)) { color = colors->sticky; } else { color = colors->directory; @@ -599,7 +610,7 @@ static const char *file_color(const struct colors *colors, const char *filename, break; - case S_IFLNK: + case BFTW_LNK: if (colors->orphan && is_link_broken(ftwbuf)) { color = colors->orphan; } else { @@ -607,24 +618,24 @@ static const char *file_color(const struct colors *colors, const char *filename, } break; - case S_IFBLK: + case BFTW_BLK: color = colors->blockdev; break; - case S_IFCHR: + case BFTW_CHR: color = colors->chardev; break; - case S_IFIFO: + case BFTW_FIFO: color = colors->pipe; break; - case S_IFSOCK: + case BFTW_SOCK: color = colors->socket; break; - -#ifdef S_IFDOOR - case S_IFDOOR: + case BFTW_DOOR: color = colors->door; break; -#endif + + default: + break; } if (!color) { @@ -632,6 +643,13 @@ static const char *file_color(const struct colors *colors, const char *filename, } return color; + +error: + if (colors->missing) { + return colors->missing; + } else { + return colors->orphan; + } } /** Print a fixed-length string. */ @@ -700,15 +700,9 @@ error: * -f?print action. */ bool eval_fprint(const struct expr *expr, struct eval_state *state) { - CFILE *cfile = expr->cfile; - if (cfile->colors) { - eval_stat(state); - } - - if (cfprintf(cfile, "%pP\n", state->ftwbuf) < 0) { + if (cfprintf(expr->cfile, "%pP\n", state->ftwbuf) < 0) { eval_report_error(state); } - return true; } @@ -610,6 +610,8 @@ bfs_tests=( test_color_ext_override test_color_ext_underride test_color_missing_colon + test_color_no_stat + test_color_L_no_stat test_execdir_plus @@ -2056,6 +2058,14 @@ function test_color_missing_colon() { LS_COLORS="*.txt=01" bfs_diff rainbow -color } +function test_color_no_stat() { + LS_COLORS="mh=0:ex=0:sg=0:su=0:st=0:ow=0:tw=0:*.txt=01:" bfs_diff rainbow -color +} + +function test_color_L_no_stat() { + LS_COLORS="mh=0:ex=0:sg=0:su=0:st=0:ow=0:tw=0:*.txt=01:" bfs_diff -L rainbow -color +} + function test_deep() { closefrom 4 diff --git a/tests/test_color_L_no_stat.out b/tests/test_color_L_no_stat.out new file mode 100644 index 0000000..c0bb1be --- /dev/null +++ b/tests/test_color_L_no_stat.out @@ -0,0 +1,20 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;33mchardev_link[0m +[01;34mrainbow/[0m[01;34mow[0m +[01;34mrainbow/[0m[01;34msticky[0m +[01;34mrainbow/[0m[01;34msticky_ow[0m +[01;34mrainbow/[0m[01;35msocket[0m +[01;34mrainbow/[0m[01;36mbroken[0m +[01;34mrainbow/[0m[01mfile.txt[0m +[01;34mrainbow/[0m[01mlink.txt[0m +[01;34mrainbow/[0m[33mpipe[0m +[01;34mrainbow/[0mexec.sh +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 +[01;34mrainbow/[0msgid +[01;34mrainbow/[0mstar.gz +[01;34mrainbow/[0mstar.tar +[01;34mrainbow/[0mstar.tar.gz +[01;34mrainbow/[0msugid +[01;34mrainbow/[0msuid diff --git a/tests/test_color_no_stat.out b/tests/test_color_no_stat.out new file mode 100644 index 0000000..1fc5324 --- /dev/null +++ b/tests/test_color_no_stat.out @@ -0,0 +1,20 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;34mow[0m +[01;34mrainbow/[0m[01;34msticky[0m +[01;34mrainbow/[0m[01;34msticky_ow[0m +[01;34mrainbow/[0m[01;35msocket[0m +[01;34mrainbow/[0m[01;36mbroken[0m +[01;34mrainbow/[0m[01;36mchardev_link[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[01mfile.txt[0m +[01;34mrainbow/[0m[33mpipe[0m +[01;34mrainbow/[0mexec.sh +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 +[01;34mrainbow/[0msgid +[01;34mrainbow/[0mstar.gz +[01;34mrainbow/[0mstar.tar +[01;34mrainbow/[0mstar.tar.gz +[01;34mrainbow/[0msugid +[01;34mrainbow/[0msuid |