|
Packit |
ae9e2a |
/*
|
|
Packit |
ae9e2a |
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
Packit |
ae9e2a |
*
|
|
Packit |
ae9e2a |
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
Packit |
ae9e2a |
* a Linking Exception. For full terms see the included COPYING file.
|
|
Packit |
ae9e2a |
*/
|
|
Packit |
ae9e2a |
#include "common.h"
|
|
Packit |
ae9e2a |
#include "global.h"
|
|
Packit |
ae9e2a |
#include "posix.h"
|
|
Packit |
ae9e2a |
#include "buffer.h"
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
/********************************************
|
|
Packit |
ae9e2a |
* New error handling
|
|
Packit |
ae9e2a |
********************************************/
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
static git_error g_git_oom_error = {
|
|
Packit |
ae9e2a |
"Out of memory",
|
|
Packit |
ae9e2a |
GITERR_NOMEMORY
|
|
Packit |
ae9e2a |
};
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
static void set_error_from_buffer(int error_class)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
git_error *error = &GIT_GLOBAL->error_t;
|
|
Packit |
ae9e2a |
git_buf *buf = &GIT_GLOBAL->error_buf;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
error->message = buf->ptr;
|
|
Packit |
ae9e2a |
error->klass = error_class;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
GIT_GLOBAL->last_error = error;
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
static void set_error(int error_class, char *string)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
git_buf *buf = &GIT_GLOBAL->error_buf;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
git_buf_clear(buf);
|
|
Packit |
ae9e2a |
if (string) {
|
|
Packit |
ae9e2a |
git_buf_puts(buf, string);
|
|
Packit |
ae9e2a |
git__free(string);
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
set_error_from_buffer(error_class);
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
void giterr_set_oom(void)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
GIT_GLOBAL->last_error = &g_git_oom_error;
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
void giterr_set(int error_class, const char *string, ...)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
va_list arglist;
|
|
Packit |
ae9e2a |
#ifdef GIT_WIN32
|
|
Packit |
ae9e2a |
DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0;
|
|
Packit |
ae9e2a |
#endif
|
|
Packit |
ae9e2a |
int error_code = (error_class == GITERR_OS) ? errno : 0;
|
|
Packit |
ae9e2a |
git_buf *buf = &GIT_GLOBAL->error_buf;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
git_buf_clear(buf);
|
|
Packit |
ae9e2a |
if (string) {
|
|
Packit |
ae9e2a |
va_start(arglist, string);
|
|
Packit |
ae9e2a |
git_buf_vprintf(buf, string, arglist);
|
|
Packit |
ae9e2a |
va_end(arglist);
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (error_class == GITERR_OS)
|
|
Packit |
ae9e2a |
git_buf_PUTS(buf, ": ");
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (error_class == GITERR_OS) {
|
|
Packit |
ae9e2a |
#ifdef GIT_WIN32
|
|
Packit |
ae9e2a |
char * win32_error = git_win32_get_error_message(win32_error_code);
|
|
Packit |
ae9e2a |
if (win32_error) {
|
|
Packit |
ae9e2a |
git_buf_puts(buf, win32_error);
|
|
Packit |
ae9e2a |
git__free(win32_error);
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
SetLastError(0);
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
else
|
|
Packit |
ae9e2a |
#endif
|
|
Packit |
ae9e2a |
if (error_code)
|
|
Packit |
ae9e2a |
git_buf_puts(buf, strerror(error_code));
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (error_code)
|
|
Packit |
ae9e2a |
errno = 0;
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (!git_buf_oom(buf))
|
|
Packit |
ae9e2a |
set_error_from_buffer(error_class);
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
void giterr_set_str(int error_class, const char *string)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
git_buf *buf = &GIT_GLOBAL->error_buf;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
assert(string);
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (!string)
|
|
Packit |
ae9e2a |
return;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
git_buf_clear(buf);
|
|
Packit |
ae9e2a |
git_buf_puts(buf, string);
|
|
Packit |
ae9e2a |
if (!git_buf_oom(buf))
|
|
Packit |
ae9e2a |
set_error_from_buffer(error_class);
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
int giterr_set_regex(const regex_t *regex, int error_code)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
char error_buf[1024];
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
assert(error_code);
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
regerror(error_code, regex, error_buf, sizeof(error_buf));
|
|
Packit |
ae9e2a |
giterr_set_str(GITERR_REGEX, error_buf);
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (error_code == REG_NOMATCH)
|
|
Packit |
ae9e2a |
return GIT_ENOTFOUND;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
return GIT_EINVALIDSPEC;
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
void giterr_clear(void)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
if (GIT_GLOBAL->last_error != NULL) {
|
|
Packit |
ae9e2a |
set_error(0, NULL);
|
|
Packit |
ae9e2a |
GIT_GLOBAL->last_error = NULL;
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
errno = 0;
|
|
Packit |
ae9e2a |
#ifdef GIT_WIN32
|
|
Packit |
ae9e2a |
SetLastError(0);
|
|
Packit |
ae9e2a |
#endif
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
const git_error *giterr_last(void)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
return GIT_GLOBAL->last_error;
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
int giterr_state_capture(git_error_state *state, int error_code)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
git_error *error = GIT_GLOBAL->last_error;
|
|
Packit |
ae9e2a |
git_buf *error_buf = &GIT_GLOBAL->error_buf;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
memset(state, 0, sizeof(git_error_state));
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (!error_code)
|
|
Packit |
ae9e2a |
return 0;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
state->error_code = error_code;
|
|
Packit |
ae9e2a |
state->oom = (error == &g_git_oom_error);
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (error) {
|
|
Packit |
ae9e2a |
state->error_msg.klass = error->klass;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (state->oom)
|
|
Packit |
ae9e2a |
state->error_msg.message = g_git_oom_error.message;
|
|
Packit |
ae9e2a |
else
|
|
Packit |
ae9e2a |
state->error_msg.message = git_buf_detach(error_buf);
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
giterr_clear();
|
|
Packit |
ae9e2a |
return error_code;
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
int giterr_state_restore(git_error_state *state)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
int ret = 0;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
giterr_clear();
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (state && state->error_msg.message) {
|
|
Packit |
ae9e2a |
if (state->oom)
|
|
Packit |
ae9e2a |
giterr_set_oom();
|
|
Packit |
ae9e2a |
else
|
|
Packit |
ae9e2a |
set_error(state->error_msg.klass, state->error_msg.message);
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
ret = state->error_code;
|
|
Packit |
ae9e2a |
memset(state, 0, sizeof(git_error_state));
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
return ret;
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
void giterr_state_free(git_error_state *state)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
if (!state)
|
|
Packit |
ae9e2a |
return;
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
if (!state->oom)
|
|
Packit |
ae9e2a |
git__free(state->error_msg.message);
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
memset(state, 0, sizeof(git_error_state));
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
int giterr_system_last(void)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
#ifdef GIT_WIN32
|
|
Packit |
ae9e2a |
return GetLastError();
|
|
Packit |
ae9e2a |
#else
|
|
Packit |
ae9e2a |
return errno;
|
|
Packit |
ae9e2a |
#endif
|
|
Packit |
ae9e2a |
}
|
|
Packit |
ae9e2a |
|
|
Packit |
ae9e2a |
void giterr_system_set(int code)
|
|
Packit |
ae9e2a |
{
|
|
Packit |
ae9e2a |
#ifdef GIT_WIN32
|
|
Packit |
ae9e2a |
SetLastError(code);
|
|
Packit |
ae9e2a |
#else
|
|
Packit |
ae9e2a |
errno = code;
|
|
Packit |
ae9e2a |
#endif
|
|
Packit |
ae9e2a |
}
|