diff options
-rw-r--r-- | refs.c | 36 | ||||
-rw-r--r-- | refs.h | 12 |
2 files changed, 39 insertions, 9 deletions
@@ -1679,17 +1679,19 @@ int refs_read_raw_ref(struct ref_store *ref_store, type, &errno); } -/* This function needs to return a meaningful errno on failure */ -const char *refs_resolve_ref_unsafe(struct ref_store *refs, +const char *refs_werrres_ref_unsafe(struct ref_store *refs, const char *refname, int resolve_flags, - struct object_id *oid, int *flags) + struct object_id *oid, + int *flags, int *failure_errno) { static struct strbuf sb_refname = STRBUF_INIT; struct object_id unused_oid; int unused_flags; int symref_count; + assert(failure_errno); + if (!oid) oid = &unused_oid; if (!flags) @@ -1700,7 +1702,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs, if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || !refname_is_safe(refname)) { - errno = EINVAL; + *failure_errno = EINVAL; return NULL; } @@ -1718,9 +1720,12 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs, for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) { unsigned int read_flags = 0; + errno = 0; if (refs_read_raw_ref(refs, refname, oid, &sb_refname, &read_flags)) { *flags |= read_flags; + if (errno) + *failure_errno = errno; /* In reading mode, refs must eventually resolve */ if (resolve_flags & RESOLVE_REF_READING) @@ -1731,9 +1736,9 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs, * may show errors besides ENOENT if there are * similarly-named refs. */ - if (errno != ENOENT && - errno != EISDIR && - errno != ENOTDIR) + if (*failure_errno != ENOENT && + *failure_errno != EISDIR && + *failure_errno != ENOTDIR) return NULL; oidclr(oid); @@ -1760,7 +1765,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs, if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || !refname_is_safe(refname)) { - errno = EINVAL; + *failure_errno = EINVAL; return NULL; } @@ -1768,10 +1773,23 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs, } } - errno = ELOOP; + *failure_errno = ELOOP; return NULL; } +const char *refs_resolve_ref_unsafe(struct ref_store *refs, const char *refname, + int resolve_flags, struct object_id *oid, + int *flags) +{ + int failure_errno = 0; + const char *refn; + refn = refs_werrres_ref_unsafe(refs, refname, resolve_flags, + oid, flags, &failure_errno); + if (!refn) + errno = failure_errno; + return refn; +} + /* backend functions */ int refs_init_db(struct strbuf *err) { @@ -12,6 +12,18 @@ struct string_list_item; struct worktree; /* + * Callers should not inspect "errno" on failure, but rather pass in a + * "failure_errno" parameter, on failure the "errno" will indicate the + * type of failure encountered, but not necessarily one that came from + * a syscall. We might have faked it up. + */ +const char *refs_werrres_ref_unsafe(struct ref_store *refs, + const char *refname, + int resolve_flags, + struct object_id *oid, + int *flags, int *failure_errno); + +/* * Resolve a reference, recursively following symbolic refererences. * * Return the name of the non-symbolic reference that ultimately pointed |