Commit 854b701c by Edward Thomson

Merge remote-tracking branches 'upstream/pr/3323' and 'upstream/pr/3329'

parents 988ea594 f85fc367
...@@ -18,19 +18,30 @@ static git_error g_git_oom_error = { ...@@ -18,19 +18,30 @@ static git_error g_git_oom_error = {
GITERR_NOMEMORY GITERR_NOMEMORY
}; };
static void set_error(int error_class, char *string) static void set_error_from_buffer(int error_class)
{ {
git_error *error = &GIT_GLOBAL->error_t; git_error *error = &GIT_GLOBAL->error_t;
git_buf *buf = &GIT_GLOBAL->error_buf;
if (error->message != string) error->message = buf->ptr;
git__free(error->message);
error->message = string;
error->klass = error_class; error->klass = error_class;
GIT_GLOBAL->last_error = error; GIT_GLOBAL->last_error = error;
} }
static void set_error(int error_class, char *string)
{
git_buf *buf = &GIT_GLOBAL->error_buf;
git_buf_clear(buf);
if (string) {
git_buf_puts(buf, string);
git__free(string);
}
set_error_from_buffer(error_class);
}
void giterr_set_oom(void) void giterr_set_oom(void)
{ {
GIT_GLOBAL->last_error = &g_git_oom_error; GIT_GLOBAL->last_error = &g_git_oom_error;
...@@ -38,27 +49,28 @@ void giterr_set_oom(void) ...@@ -38,27 +49,28 @@ void giterr_set_oom(void)
void giterr_set(int error_class, const char *string, ...) void giterr_set(int error_class, const char *string, ...)
{ {
git_buf buf = GIT_BUF_INIT;
va_list arglist; va_list arglist;
#ifdef GIT_WIN32 #ifdef GIT_WIN32
DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0; DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0;
#endif #endif
int error_code = (error_class == GITERR_OS) ? errno : 0; int error_code = (error_class == GITERR_OS) ? errno : 0;
git_buf *buf = &GIT_GLOBAL->error_buf;
git_buf_clear(buf);
if (string) { if (string) {
va_start(arglist, string); va_start(arglist, string);
git_buf_vprintf(&buf, string, arglist); git_buf_vprintf(buf, string, arglist);
va_end(arglist); va_end(arglist);
if (error_class == GITERR_OS) if (error_class == GITERR_OS)
git_buf_PUTS(&buf, ": "); git_buf_PUTS(buf, ": ");
} }
if (error_class == GITERR_OS) { if (error_class == GITERR_OS) {
#ifdef GIT_WIN32 #ifdef GIT_WIN32
char * win32_error = git_win32_get_error_message(win32_error_code); char * win32_error = git_win32_get_error_message(win32_error_code);
if (win32_error) { if (win32_error) {
git_buf_puts(&buf, win32_error); git_buf_puts(buf, win32_error);
git__free(win32_error); git__free(win32_error);
SetLastError(0); SetLastError(0);
...@@ -66,26 +78,29 @@ void giterr_set(int error_class, const char *string, ...) ...@@ -66,26 +78,29 @@ void giterr_set(int error_class, const char *string, ...)
else else
#endif #endif
if (error_code) if (error_code)
git_buf_puts(&buf, strerror(error_code)); git_buf_puts(buf, strerror(error_code));
if (error_code) if (error_code)
errno = 0; errno = 0;
} }
if (!git_buf_oom(&buf)) if (!git_buf_oom(buf))
set_error(error_class, git_buf_detach(&buf)); set_error_from_buffer(error_class);
} }
void giterr_set_str(int error_class, const char *string) void giterr_set_str(int error_class, const char *string)
{ {
char *message; git_buf *buf = &GIT_GLOBAL->error_buf;
assert(string); assert(string);
message = git__strdup(string); if (!string)
return;
if (message) git_buf_clear(buf);
set_error(error_class, message); git_buf_puts(buf, string);
if (!git_buf_oom(buf))
set_error_from_buffer(error_class);
} }
int giterr_set_regex(const regex_t *regex, int error_code) int giterr_set_regex(const regex_t *regex, int error_code)
...@@ -119,13 +134,14 @@ void giterr_clear(void) ...@@ -119,13 +134,14 @@ void giterr_clear(void)
static int giterr_detach(git_error *cpy) static int giterr_detach(git_error *cpy)
{ {
git_error *error = GIT_GLOBAL->last_error; git_error *error = GIT_GLOBAL->last_error;
git_buf *buf = &GIT_GLOBAL->error_buf;
assert(cpy); assert(cpy);
if (!error) if (!error)
return -1; return -1;
cpy->message = error->message; cpy->message = git_buf_detach(buf);
cpy->klass = error->klass; cpy->klass = error->klass;
if (error != &g_git_oom_error) { if (error != &g_git_oom_error) {
......
...@@ -279,18 +279,19 @@ int git_libgit2_shutdown(void) ...@@ -279,18 +279,19 @@ int git_libgit2_shutdown(void)
git_global_st *git__global_state(void) git_global_st *git__global_state(void)
{ {
void *ptr; git_global_st *ptr;
assert(git_atomic_get(&git__n_inits) > 0); assert(git_atomic_get(&git__n_inits) > 0);
if ((ptr = TlsGetValue(_tls_index)) != NULL) if ((ptr = TlsGetValue(_tls_index)) != NULL)
return ptr; return ptr;
ptr = git__malloc(sizeof(git_global_st)); ptr = git__calloc(1, sizeof(git_global_st));
if (!ptr) if (!ptr)
return NULL; return NULL;
memset(ptr, 0x0, sizeof(git_global_st)); git_buf_init(&ptr->error_buf, 0);
TlsSetValue(_tls_index, ptr); TlsSetValue(_tls_index, ptr);
return ptr; return ptr;
} }
...@@ -378,18 +379,18 @@ int git_libgit2_shutdown(void) ...@@ -378,18 +379,18 @@ int git_libgit2_shutdown(void)
git_global_st *git__global_state(void) git_global_st *git__global_state(void)
{ {
void *ptr; git_global_st *ptr;
assert(git_atomic_get(&git__n_inits) > 0); assert(git_atomic_get(&git__n_inits) > 0);
if ((ptr = pthread_getspecific(_tls_key)) != NULL) if ((ptr = pthread_getspecific(_tls_key)) != NULL)
return ptr; return ptr;
ptr = git__malloc(sizeof(git_global_st)); ptr = git__calloc(1, sizeof(git_global_st));
if (!ptr) if (!ptr)
return NULL; return NULL;
memset(ptr, 0x0, sizeof(git_global_st)); git_buf_init(&ptr->error_buf, 0);
pthread_setspecific(_tls_key, ptr); pthread_setspecific(_tls_key, ptr);
return ptr; return ptr;
} }
...@@ -407,6 +408,7 @@ int git_libgit2_init(void) ...@@ -407,6 +408,7 @@ int git_libgit2_init(void)
ssl_inited = 1; ssl_inited = 1;
} }
git_buf_init(&__state.error_buf, 0);
return git_atomic_inc(&git__n_inits); return git_atomic_inc(&git__n_inits);
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
typedef struct { typedef struct {
git_error *last_error; git_error *last_error;
git_error error_t; git_error error_t;
git_buf error_buf;
char oid_fmt[GIT_OID_HEXSZ+1]; char oid_fmt[GIT_OID_HEXSZ+1];
} git_global_st; } git_global_st;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment