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 76d70dc0c63 (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 <hanwen@google.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
aa30fe1481
commit
ef18119dec
36
refs.c
36
refs.c
@ -1679,17 +1679,19 @@ int refs_read_raw_ref(struct ref_store *ref_store,
|
|||||||
type, &errno);
|
type, &errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function needs to return a meaningful errno on failure */
|
const char *refs_werrres_ref_unsafe(struct ref_store *refs,
|
||||||
const char *refs_resolve_ref_unsafe(struct ref_store *refs,
|
|
||||||
const char *refname,
|
const char *refname,
|
||||||
int resolve_flags,
|
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;
|
static struct strbuf sb_refname = STRBUF_INIT;
|
||||||
struct object_id unused_oid;
|
struct object_id unused_oid;
|
||||||
int unused_flags;
|
int unused_flags;
|
||||||
int symref_count;
|
int symref_count;
|
||||||
|
|
||||||
|
assert(failure_errno);
|
||||||
|
|
||||||
if (!oid)
|
if (!oid)
|
||||||
oid = &unused_oid;
|
oid = &unused_oid;
|
||||||
if (!flags)
|
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 (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
|
||||||
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
|
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
|
||||||
!refname_is_safe(refname)) {
|
!refname_is_safe(refname)) {
|
||||||
errno = EINVAL;
|
*failure_errno = EINVAL;
|
||||||
return NULL;
|
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++) {
|
for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
|
||||||
unsigned int read_flags = 0;
|
unsigned int read_flags = 0;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
if (refs_read_raw_ref(refs, refname,
|
if (refs_read_raw_ref(refs, refname,
|
||||||
oid, &sb_refname, &read_flags)) {
|
oid, &sb_refname, &read_flags)) {
|
||||||
*flags |= read_flags;
|
*flags |= read_flags;
|
||||||
|
if (errno)
|
||||||
|
*failure_errno = errno;
|
||||||
|
|
||||||
/* In reading mode, refs must eventually resolve */
|
/* In reading mode, refs must eventually resolve */
|
||||||
if (resolve_flags & RESOLVE_REF_READING)
|
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
|
* may show errors besides ENOENT if there are
|
||||||
* similarly-named refs.
|
* similarly-named refs.
|
||||||
*/
|
*/
|
||||||
if (errno != ENOENT &&
|
if (*failure_errno != ENOENT &&
|
||||||
errno != EISDIR &&
|
*failure_errno != EISDIR &&
|
||||||
errno != ENOTDIR)
|
*failure_errno != ENOTDIR)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
oidclr(oid);
|
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 (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
|
||||||
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
|
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
|
||||||
!refname_is_safe(refname)) {
|
!refname_is_safe(refname)) {
|
||||||
errno = EINVAL;
|
*failure_errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1768,10 +1773,23 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = ELOOP;
|
*failure_errno = ELOOP;
|
||||||
return NULL;
|
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 */
|
/* backend functions */
|
||||||
int refs_init_db(struct strbuf *err)
|
int refs_init_db(struct strbuf *err)
|
||||||
{
|
{
|
||||||
|
12
refs.h
12
refs.h
@ -11,6 +11,18 @@ struct string_list;
|
|||||||
struct string_list_item;
|
struct string_list_item;
|
||||||
struct worktree;
|
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.
|
* Resolve a reference, recursively following symbolic refererences.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user