@@ -1678,17 +1678,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)
@@ -1699,7 +1701,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;
}
@@ -1717,9 +1719,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)
@@ -1730,9 +1735,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);
@@ -1759,7 +1764,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;
}
@@ -1767,10 +1772,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)
{
@@ -11,6 +11,18 @@ struct string_list;
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.
*