diff options
Diffstat (limited to 'read-cache.c')
-rw-r--r-- | read-cache.c | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/read-cache.c b/read-cache.c index 31eddec5f7..f92a912dcb 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]; @@ -627,7 +634,7 @@ void set_object_name_for_intent_to_add_entry(struct cache_entry *ce) hashcpy(ce->oid.hash, sha1); } -int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags, int force_mode) +int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags) { int size, namelen, was_same; mode_t st_mode = st->st_mode; @@ -656,11 +663,10 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, else ce->ce_flags |= CE_INTENT_TO_ADD; - if (S_ISREG(st_mode) && force_mode) - ce->ce_mode = create_ce_mode(force_mode); - else if (trust_executable_bit && has_symlinks) + + if (trust_executable_bit && has_symlinks) { ce->ce_mode = create_ce_mode(st_mode); - else { + } else { /* If there is an existing entry, pick the mode bits and type * from it, otherwise assume unexecutable regular file. */ @@ -719,13 +725,12 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, return 0; } -int add_file_to_index(struct index_state *istate, const char *path, - int flags, int force_mode) +int add_file_to_index(struct index_state *istate, const char *path, int flags) { struct stat st; if (lstat(path, &st)) die_errno("unable to stat '%s'", path); - return add_to_index(istate, path, &st, flags, force_mode); + return add_to_index(istate, path, &st, flags); } struct cache_entry *make_cache_entry(unsigned int mode, @@ -756,6 +761,35 @@ struct cache_entry *make_cache_entry(unsigned int mode, return ret; } +/* + * Chmod an index entry with either +x or -x. + * + * Returns -1 if the chmod for the particular cache entry failed (if it's + * not a regular file), -2 if an invalid flip argument is passed in, 0 + * otherwise. + */ +int chmod_index_entry(struct index_state *istate, struct cache_entry *ce, + char flip) +{ + if (!S_ISREG(ce->ce_mode)) + return -1; + switch (flip) { + case '+': + ce->ce_mode |= 0111; + break; + case '-': + ce->ce_mode &= ~0111; + break; + default: + return -2; + } + cache_tree_invalidate_path(istate, ce->name); + ce->ce_flags |= CE_UPDATE_IN_BASE; + istate->cache_changed |= CE_ENTRY_CHANGED; + + return 0; +} + int ce_same_name(const struct cache_entry *a, const struct cache_entry *b) { int len = ce_namelen(a); @@ -1391,12 +1425,9 @@ static int read_index_extension(struct index_state *istate, return 0; } -int hold_locked_index(struct lock_file *lk, int die_on_error) +int hold_locked_index(struct lock_file *lk, int lock_flags) { - return hold_lock_file_for_update(lk, get_index_file(), - die_on_error - ? LOCK_DIE_ON_ERROR - : 0); + return hold_lock_file_for_update(lk, get_index_file(), lock_flags); } int read_index(struct index_state *istate) |