diff --git a/apply.c b/apply.c index c49cef0637..854faa6779 100644 --- a/apply.c +++ b/apply.c @@ -3741,7 +3741,7 @@ static int check_to_create(struct apply_state *state, return 0; return EXISTS_IN_WORKTREE; - } else if ((errno != ENOENT) && (errno != ENOTDIR)) { + } else if (!is_missing_file_error(errno)) { return error_errno("%s", new_name); } return 0; diff --git a/builtin/rm.c b/builtin/rm.c index 7c323d0123..b39f10fcb6 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -129,7 +129,7 @@ static int check_local_mod(struct object_id *head, int index_only) ce = active_cache[pos]; if (lstat(ce->name, &st) < 0) { - if (errno != ENOENT && errno != ENOTDIR) + if (!is_missing_file_error(errno)) warning_errno(_("failed to stat '%s'"), ce->name); /* It already vanished from the working tree */ continue; diff --git a/builtin/update-index.c b/builtin/update-index.c index ebfc09faa0..f99b1e5790 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -257,7 +257,7 @@ static int remove_one_path(const char *path) */ static int process_lstat_error(const char *path, int err) { - if (err == ENOENT || err == ENOTDIR) + if (is_missing_file_error(err)) return remove_one_path(path); return error("lstat(\"%s\"): %s", path, strerror(err)); } diff --git a/diff-lib.c b/diff-lib.c index 2982bf055a..76c8f185cd 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -29,7 +29,7 @@ static int check_removed(const struct cache_entry *ce, struct stat *st) { if (lstat(ce->name, st) < 0) { - if (errno != ENOENT && errno != ENOTDIR) + if (!is_missing_file_error(errno)) return -1; return 1; } diff --git a/dir.c b/dir.c index 9efcf1eab6..70f2de38f2 100644 --- a/dir.c +++ b/dir.c @@ -2337,7 +2337,7 @@ int remove_path(const char *name) { char *slash; - if (unlink(name) && errno != ENOENT && errno != ENOTDIR) + if (unlink(name) && !is_missing_file_error(errno)) return -1; slash = strrchr(name, '/'); diff --git a/git-compat-util.h b/git-compat-util.h index 4b7dcf21ad..e83fd2eb07 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -1134,6 +1134,21 @@ struct tm *git_gmtime_r(const time_t *, struct tm *); #define getc_unlocked(fh) getc(fh) #endif +/* + * Our code often opens a path to an optional file, to work on its + * contents when we can successfully open it. We can ignore a failure + * to open if such an optional file does not exist, but we do want to + * report a failure in opening for other reasons (e.g. we got an I/O + * error, or the file is there, but we lack the permission to open). + * + * Call this function after seeing an error from open() or fopen() to + * see if the errno indicates a missing file that we can safely ignore. + */ +static inline int is_missing_file_error(int errno_) +{ + return (errno_ == ENOENT || errno_ == ENOTDIR); +} + extern int cmd_main(int, const char **); #endif diff --git a/setup.c b/setup.c index e3f7699a90..ba6e855178 100644 --- a/setup.c +++ b/setup.c @@ -150,7 +150,7 @@ int check_filename(const char *prefix, const char *arg) free(to_free); return 1; /* file exists */ } - if (errno == ENOENT || errno == ENOTDIR) { + if (is_missing_file_error(errno)) { free(to_free); return 0; /* file does not exist */ } diff --git a/sha1_name.c b/sha1_name.c index e9ffe685d5..5126853bb5 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1408,7 +1408,7 @@ static void diagnose_invalid_sha1_path(const char *prefix, if (file_exists(filename)) die("Path '%s' exists on disk, but not in '%.*s'.", filename, object_name_len, object_name); - if (errno == ENOENT || errno == ENOTDIR) { + if (is_missing_file_error(errno)) { char *fullname = xstrfmt("%s%s", prefix, filename); if (!get_tree_entry(tree_sha1, fullname, @@ -1473,7 +1473,7 @@ static void diagnose_invalid_index_path(int stage, if (file_exists(filename)) die("Path '%s' exists on disk, but not in the index.", filename); - if (errno == ENOENT || errno == ENOTDIR) + if (is_missing_file_error(errno)) die("Path '%s' does not exist (neither on disk nor in the index).", filename); diff --git a/wrapper.c b/wrapper.c index d837417709..708e98a965 100644 --- a/wrapper.c +++ b/wrapper.c @@ -583,8 +583,8 @@ void warn_on_inaccessible(const char *path) static int access_error_is_ok(int err, unsigned flag) { - return err == ENOENT || err == ENOTDIR || - ((flag & ACCESS_EACCES_OK) && err == EACCES); + return (is_missing_file_error(err) || + ((flag & ACCESS_EACCES_OK) && err == EACCES)); } int access_or_warn(const char *path, int mode, unsigned flag)