aboutsummaryrefslogtreecommitdiff
path: root/read-cache.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-10-31 13:15:21 -0700
committerJunio C Hamano <gitster@pobox.com>2016-10-31 13:15:21 -0700
commit906d6906fb580f2002bfdaadab80da6884bab16f (patch)
treeaa2f6fae92c550a78573b34dcdc343ad363f0d05 /read-cache.c
parent7805bda2ac68c659b0042f45473723d9fdcece74 (diff)
parenta0a6cb96625cebe8590841c469bfbb461a132ae3 (diff)
downloadgit-906d6906fb580f2002bfdaadab80da6884bab16f.tar.xz
Merge branch 'ls/git-open-cloexec'
Git generally does not explicitly close file descriptors that were open in the parent process when spawning a child process, but most of the time the child does not want to access them. As Windows does not allow removing or renaming a file that has a file descriptor open, a slow-to-exit child can even break the parent process by holding onto them. Use O_CLOEXEC flag to open files in various codepaths. * ls/git-open-cloexec: read-cache: make sure file handles are not inherited by child processes sha1_file: open window into packfiles with O_CLOEXEC sha1_file: rename git_open_noatime() to git_open()
Diffstat (limited to 'read-cache.c')
-rw-r--r--read-cache.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/read-cache.c b/read-cache.c
index 38d67faf70..db5d910642 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -156,7 +156,14 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
static int ce_compare_data(const struct cache_entry *ce, struct stat *st)
{
int match = -1;
- int fd = open(ce->name, O_RDONLY);
+ static int cloexec = O_CLOEXEC;
+ int fd = open(ce->name, O_RDONLY | cloexec);
+
+ if ((cloexec & O_CLOEXEC) && fd < 0 && errno == EINVAL) {
+ /* Try again w/o O_CLOEXEC: the kernel might not support it */
+ cloexec &= ~O_CLOEXEC;
+ fd = open(ce->name, O_RDONLY | cloexec);
+ }
if (fd >= 0) {
unsigned char sha1[20];