Skip to content

Commit ef18119

Browse files
avargitster
authored andcommitted
refs API: add a version of refs_resolve_ref_unsafe() with "errno"
Add a new refs_werrres_ref_unsafe() function, which is like refs_resolve_ref_unsafe() except that it explicitly saves away the "errno" to a passed-in parameter, the refs_resolve_ref_unsafe() then becomes a wrapper for it. In subsequent commits we'll migrate code over to it, before finally making "refs_resolve_ref_unsafe()" with an "errno" parameter the canonical version, so this this function exists only so that we can incrementally migrate callers, it will be going away in a subsequent commit. As the added comment notes has a rather tortured name to be the same length as "refs_resolve_ref_unsafe", to avoid churn as we won't need to re-indent the argument lists, similarly the documentation and structure of it in refs.h is designed to minimize a diff in a subsequent commit, where that documentation will be added to the new refs_resolve_ref_unsafe(). At the end of this migration the "meaningful errno" TODO item left in 76d70dc (refs.c: make resolve_ref_unsafe set errno to something meaningful on error, 2014-06-20) will be resolved. As can be seen from the use of refs_read_raw_ref() we'll also need to convert some functions that the new refs_werrres_ref_unsafe() itself calls to take this "failure_errno". That will be done in subsequent commits. Signed-off-by: Han-Wen Nienhuys <[email protected]> Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent aa30fe1 commit ef18119

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

refs.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,17 +1679,19 @@ int refs_read_raw_ref(struct ref_store *ref_store,
16791679
type, &errno);
16801680
}
16811681

1682-
/* This function needs to return a meaningful errno on failure */
1683-
const char *refs_resolve_ref_unsafe(struct ref_store *refs,
1682+
const char *refs_werrres_ref_unsafe(struct ref_store *refs,
16841683
const char *refname,
16851684
int resolve_flags,
1686-
struct object_id *oid, int *flags)
1685+
struct object_id *oid,
1686+
int *flags, int *failure_errno)
16871687
{
16881688
static struct strbuf sb_refname = STRBUF_INIT;
16891689
struct object_id unused_oid;
16901690
int unused_flags;
16911691
int symref_count;
16921692

1693+
assert(failure_errno);
1694+
16931695
if (!oid)
16941696
oid = &unused_oid;
16951697
if (!flags)
@@ -1700,7 +1702,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
17001702
if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
17011703
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
17021704
!refname_is_safe(refname)) {
1703-
errno = EINVAL;
1705+
*failure_errno = EINVAL;
17041706
return NULL;
17051707
}
17061708

@@ -1718,9 +1720,12 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
17181720
for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
17191721
unsigned int read_flags = 0;
17201722

1723+
errno = 0;
17211724
if (refs_read_raw_ref(refs, refname,
17221725
oid, &sb_refname, &read_flags)) {
17231726
*flags |= read_flags;
1727+
if (errno)
1728+
*failure_errno = errno;
17241729

17251730
/* In reading mode, refs must eventually resolve */
17261731
if (resolve_flags & RESOLVE_REF_READING)
@@ -1731,9 +1736,9 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
17311736
* may show errors besides ENOENT if there are
17321737
* similarly-named refs.
17331738
*/
1734-
if (errno != ENOENT &&
1735-
errno != EISDIR &&
1736-
errno != ENOTDIR)
1739+
if (*failure_errno != ENOENT &&
1740+
*failure_errno != EISDIR &&
1741+
*failure_errno != ENOTDIR)
17371742
return NULL;
17381743

17391744
oidclr(oid);
@@ -1760,18 +1765,31 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
17601765
if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
17611766
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
17621767
!refname_is_safe(refname)) {
1763-
errno = EINVAL;
1768+
*failure_errno = EINVAL;
17641769
return NULL;
17651770
}
17661771

17671772
*flags |= REF_ISBROKEN | REF_BAD_NAME;
17681773
}
17691774
}
17701775

1771-
errno = ELOOP;
1776+
*failure_errno = ELOOP;
17721777
return NULL;
17731778
}
17741779

1780+
const char *refs_resolve_ref_unsafe(struct ref_store *refs, const char *refname,
1781+
int resolve_flags, struct object_id *oid,
1782+
int *flags)
1783+
{
1784+
int failure_errno = 0;
1785+
const char *refn;
1786+
refn = refs_werrres_ref_unsafe(refs, refname, resolve_flags,
1787+
oid, flags, &failure_errno);
1788+
if (!refn)
1789+
errno = failure_errno;
1790+
return refn;
1791+
}
1792+
17751793
/* backend functions */
17761794
int refs_init_db(struct strbuf *err)
17771795
{

refs.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ struct string_list;
1111
struct string_list_item;
1212
struct worktree;
1313

14+
/*
15+
* Callers should not inspect "errno" on failure, but rather pass in a
16+
* "failure_errno" parameter, on failure the "errno" will indicate the
17+
* type of failure encountered, but not necessarily one that came from
18+
* a syscall. We might have faked it up.
19+
*/
20+
const char *refs_werrres_ref_unsafe(struct ref_store *refs,
21+
const char *refname,
22+
int resolve_flags,
23+
struct object_id *oid,
24+
int *flags, int *failure_errno);
25+
1426
/*
1527
* Resolve a reference, recursively following symbolic refererences.
1628
*

0 commit comments

Comments
 (0)