From f18234fad62b8f890ccd01bb15443afc2484af1b Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Fri, 8 Aug 2014 13:17:50 -0700 Subject: [PATCH] Don't report status on named pipes Git skips entries in directories that are not S_ISDIR, S_ISREG, or S_ISLNK, so let's make libgit2 do the same thing. --- src/path.c | 23 ++++++++++++----------- tests/repo/iterator.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/path.c b/src/path.c index 4837b01f9..77f8d8858 100644 --- a/src/path.c +++ b/src/path.c @@ -1110,28 +1110,29 @@ int git_path_dirload_with_stat( if ((error = git_buf_joinpath(&full, full.ptr, ps->path)) < 0 || (error = git_path_lstat(full.ptr, &ps->st)) < 0) { + if (error == GIT_ENOTFOUND) { - giterr_clear(); - error = 0; + /* file was removed between readdir and lstat */ git_vector_remove(contents, i--); - continue; - } - /* Treat the file as unreadable if we get any other error */ - if (error != 0) { - giterr_clear(); - error = 0; + } else { + /* Treat the file as unreadable if we get any other error */ memset(&ps->st, 0, sizeof(ps->st)); ps->st.st_mode = GIT_FILEMODE_UNREADABLE; - continue; } - - break; + + giterr_clear(); + error = 0; + continue; } if (S_ISDIR(ps->st.st_mode)) { ps->path[ps->path_len++] = '/'; ps->path[ps->path_len] = '\0'; } + else if (!S_ISREG(ps->st.st_mode) && !S_ISLNK(ps->st.st_mode)) { + /* skip everything but dirs, plain files, and symlinks */ + git_vector_remove(contents, i--); + } } /* sort now that directory suffix is added */ diff --git a/tests/repo/iterator.c b/tests/repo/iterator.c index fb70a9ea0..764c2c6cd 100644 --- a/tests/repo/iterator.c +++ b/tests/repo/iterator.c @@ -960,3 +960,35 @@ void test_repo_iterator__fs_preserves_error(void) git_iterator_free(i); } + +void test_repo_iterator__skips_fifos_and_such(void) +{ +#ifndef GIT_WIN32 + git_iterator *i; + const git_index_entry *e; + + g_repo = cl_git_sandbox_init("empty_standard_repo"); + + cl_must_pass(p_mkdir("empty_standard_repo/dir", 0777)); + cl_git_mkfile("empty_standard_repo/file", "not me"); + + cl_assert(!mkfifo("empty_standard_repo/fifo", 0777)); + cl_assert(!access("empty_standard_repo/fifo", F_OK)); + + cl_git_pass(git_iterator_for_filesystem( + &i, "empty_standard_repo", GIT_ITERATOR_INCLUDE_TREES | + GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL)); + + cl_git_pass(git_iterator_advance(&e, i)); /* .git */ + cl_assert(S_ISDIR(e->mode)); + cl_git_pass(git_iterator_advance(&e, i)); /* dir */ + cl_assert(S_ISDIR(e->mode)); + /* skips fifo */ + cl_git_pass(git_iterator_advance(&e, i)); /* file */ + cl_assert(S_ISREG(e->mode)); + + cl_assert_equal_i(GIT_ITEROVER, git_iterator_advance(&e, i)); + + git_iterator_free(i); +#endif +}