summaryrefslogtreecommitdiff
path: root/src/errors.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-12-03 16:45:39 -0800
committerRussell Belfer <rb@github.com>2013-12-11 10:57:49 -0800
commit96869a4edb2872934e0e167a726ab240f4270fea (patch)
tree2d770414acef2d1d45a609e004c0aa6fa56d06d7 /src/errors.c
parent9f77b3f6f5ce6944ec49dfc666ef6b8df0af0c6b (diff)
downloadlibgit2-96869a4edb2872934e0e167a726ab240f4270fea.tar.gz
Improve GIT_EUSER handling
This adds giterr_user_cancel to return GIT_EUSER and clear any error message that is sitting around. As a result of using that in places, we need to be more thorough with capturing errors that happen inside a callback when used internally. To help with that, this also adds giterr_capture and giterr_restore so that when we internally use a foreach-type function that clears errors and converts them to GIT_EUSER, it is easier to restore not just the return value, but the actual error message text.
Diffstat (limited to 'src/errors.c')
-rw-r--r--src/errors.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/src/errors.c b/src/errors.c
index d04da4ca9..a0b085923 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -23,7 +23,8 @@ static void set_error(int error_class, char *string)
{
git_error *error = &GIT_GLOBAL->error_t;
- git__free(error->message);
+ if (error->message != string)
+ git__free(error->message);
error->message = string;
error->klass = error_class;
@@ -103,8 +104,10 @@ int giterr_set_regex(const regex_t *regex, int error_code)
void giterr_clear(void)
{
- set_error(0, NULL);
- GIT_GLOBAL->last_error = NULL;
+ if (GIT_GLOBAL->last_error != NULL) {
+ set_error(0, NULL);
+ GIT_GLOBAL->last_error = NULL;
+ }
errno = 0;
#ifdef GIT_WIN32
@@ -134,3 +137,39 @@ const git_error *giterr_last(void)
{
return GIT_GLOBAL->last_error;
}
+
+int giterr_capture(git_error_state *state, int error_code)
+{
+ state->error_code = error_code;
+ if (error_code)
+ giterr_detach(&state->error_msg);
+ return error_code;
+}
+
+int giterr_restore(git_error_state *state)
+{
+ if (state && state->error_code && state->error_msg.message)
+ set_error(state->error_msg.klass, state->error_msg.message);
+ else
+ giterr_clear();
+
+ return state ? state->error_code : 0;
+}
+
+int giterr_system_last(void)
+{
+#ifdef GIT_WIN32
+ return GetLastError();
+#else
+ return errno;
+#endif
+}
+
+void giterr_system_set(int code)
+{
+#ifdef GIT_WIN32
+ SetLastError(code);
+#else
+ errno = code;
+#endif
+}