diff options
author | Ronnie Sahlberg <sahlberg@google.com> | 2014-06-10 14:05:22 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-06-12 13:39:30 -0700 |
commit | abf429ca4495ff5c5a4af36e62c856e768b69dd7 (patch) | |
tree | 5670147bc6869e59dc4bafd4a07ad3e135ed41f3 | |
parent | 96136c812eba943e4fb1c20f16a16cf396c936a8 (diff) | |
download | git-abf429ca4495ff5c5a4af36e62c856e768b69dd7.tar.gz |
refs.c: make resolve_ref_unsafe set errno to something meaningful on error
Making errno when returning from resolve_ref_unsafe() meaningful,
which should fix
* a bug in lock_ref_sha1_basic, where it assumes EISDIR
means it failed due to a directory being in the way
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
-rw-r--r-- | cache.h | 2 | ||||
-rw-r--r-- | refs.c | 19 |
2 files changed, 16 insertions, 5 deletions
@@ -979,7 +979,7 @@ extern int read_ref(const char *refname, unsigned char *sha1); * NULL. If more than MAXDEPTH recursive symbolic lookups are needed, * give up and return NULL. * - * errno is sometimes set on errors, but not always. + * errno is set to something meaningful on error. */ extern const char *resolve_ref_unsafe(const char *ref, unsigned char *sha1, int reading, int *flag); extern char *resolve_refdup(const char *ref, unsigned char *sha1, int reading, int *flag); @@ -1334,6 +1334,7 @@ static const char *handle_missing_loose_ref(const char *refname, } } +/* This function needs to return a meaningful errno on failure */ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int reading, int *flag) { int depth = MAXDEPTH; @@ -1344,8 +1345,10 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int rea if (flag) *flag = 0; - if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) + if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { + errno = EINVAL; return NULL; + } for (;;) { char path[PATH_MAX]; @@ -1353,8 +1356,10 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int rea char *buf; int fd; - if (--depth < 0) + if (--depth < 0) { + errno = ELOOP; return NULL; + } git_snpath(path, sizeof(path), "%s", refname); @@ -1416,9 +1421,13 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int rea return NULL; } len = read_in_full(fd, buffer, sizeof(buffer)-1); + if (len < 0) { + int save_errno = errno; + close(fd); + errno = save_errno; + return NULL; + } close(fd); - if (len < 0) - return NULL; while (len && isspace(buffer[len-1])) len--; buffer[len] = '\0'; @@ -1435,6 +1444,7 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int rea (buffer[40] != '\0' && !isspace(buffer[40]))) { if (flag) *flag |= REF_ISBROKEN; + errno = EINVAL; return NULL; } return refname; @@ -1447,6 +1457,7 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int rea if (check_refname_format(buf, REFNAME_ALLOW_ONELEVEL)) { if (flag) *flag |= REF_ISBROKEN; + errno = EINVAL; return NULL; } refname = strcpy(refname_buffer, buf); |