]> git.proxmox.com Git - libgit2.git/blame - src/libgit2/errors.c
Merge https://salsa.debian.org/debian/libgit2 into proxmox/bullseye
[libgit2.git] / src / libgit2 / errors.c
CommitLineData
02f9e637 1/*
359fc2d2 2 * Copyright (C) the libgit2 contributors. All rights reserved.
02f9e637 3 *
bb742ede
VM
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
02f9e637 6 */
eae0bfdc 7
ae234862 8#include "common.h"
eae0bfdc 9
c25aa7cd 10#include "threadstate.h"
60bc2d20 11#include "posix.h"
e579e0f7 12#include "str.h"
c25aa7cd 13#include "libgit2.h"
02f9e637 14
60bc2d20
VM
15/********************************************
16 * New error handling
17 ********************************************/
18
1a481123
VM
19static git_error g_git_oom_error = {
20 "Out of memory",
ac3d33df 21 GIT_ERROR_NOMEMORY
1a481123
VM
22};
23
c25aa7cd
PP
24static git_error g_git_uninitialized_error = {
25 "libgit2 has not been initialized; you must call git_libgit2_init",
26 GIT_ERROR_INVALID
27};
28
f85fc367 29static void set_error_from_buffer(int error_class)
22772166 30{
c25aa7cd 31 git_error *error = &GIT_THREADSTATE->error_t;
e579e0f7 32 git_str *buf = &GIT_THREADSTATE->error_buf;
22772166 33
f85fc367 34 error->message = buf->ptr;
22772166
VM
35 error->klass = error_class;
36
c25aa7cd 37 GIT_THREADSTATE->last_error = error;
22772166
VM
38}
39
f85fc367
CMN
40static void set_error(int error_class, char *string)
41{
e579e0f7 42 git_str *buf = &GIT_THREADSTATE->error_buf;
f85fc367 43
e579e0f7 44 git_str_clear(buf);
f85fc367 45 if (string) {
e579e0f7 46 git_str_puts(buf, string);
f85fc367
CMN
47 git__free(string);
48 }
49
50 set_error_from_buffer(error_class);
51}
52
ac3d33df 53void git_error_set_oom(void)
1a481123 54{
c25aa7cd 55 GIT_THREADSTATE->last_error = &g_git_oom_error;
1a481123
VM
56}
57
22a2d3d5
UG
58void git_error_set(int error_class, const char *fmt, ...)
59{
60 va_list ap;
61
62 va_start(ap, fmt);
63 git_error_vset(error_class, fmt, ap);
64 va_end(ap);
65}
66
67void git_error_vset(int error_class, const char *fmt, va_list ap)
60bc2d20 68{
3ae0aad7 69#ifdef GIT_WIN32
ac3d33df 70 DWORD win32_error_code = (error_class == GIT_ERROR_OS) ? GetLastError() : 0;
3ae0aad7 71#endif
ac3d33df 72 int error_code = (error_class == GIT_ERROR_OS) ? errno : 0;
e579e0f7 73 git_str *buf = &GIT_THREADSTATE->error_buf;
60bc2d20 74
e579e0f7 75 git_str_clear(buf);
22a2d3d5 76 if (fmt) {
e579e0f7 77 git_str_vprintf(buf, fmt, ap);
ac3d33df 78 if (error_class == GIT_ERROR_OS)
e579e0f7 79 git_str_PUTS(buf, ": ");
e62f96de 80 }
60bc2d20 81
ac3d33df 82 if (error_class == GIT_ERROR_OS) {
e1de726c 83#ifdef GIT_WIN32
c70455c7
SS
84 char * win32_error = git_win32_get_error_message(win32_error_code);
85 if (win32_error) {
e579e0f7 86 git_str_puts(buf, win32_error);
c70455c7 87 git__free(win32_error);
8f624a47
PK
88
89 SetLastError(0);
e1de726c 90 }
8f624a47 91 else
e1de726c 92#endif
e62f96de 93 if (error_code)
e579e0f7 94 git_str_puts(buf, strerror(error_code));
8f624a47
PK
95
96 if (error_code)
97 errno = 0;
ae9e29fd
RB
98 }
99
e579e0f7 100 if (!git_str_oom(buf))
f85fc367 101 set_error_from_buffer(error_class);
dda708e7
VM
102}
103
22a2d3d5 104int git_error_set_str(int error_class, const char *string)
dda708e7 105{
e579e0f7 106 git_str *buf = &GIT_THREADSTATE->error_buf;
1a628100 107
c25aa7cd 108 GIT_ASSERT_ARG(string);
dda708e7 109
e579e0f7
MB
110 git_str_clear(buf);
111 git_str_puts(buf, string);
6c72035f 112
e579e0f7 113 if (git_str_oom(buf))
22a2d3d5 114 return -1;
6c72035f 115
22a2d3d5
UG
116 set_error_from_buffer(error_class);
117 return 0;
dda708e7
VM
118}
119
ac3d33df 120void git_error_clear(void)
60bc2d20 121{
c25aa7cd 122 if (GIT_THREADSTATE->last_error != NULL) {
96869a4e 123 set_error(0, NULL);
c25aa7cd 124 GIT_THREADSTATE->last_error = NULL;
96869a4e 125 }
97a17e4e
RB
126
127 errno = 0;
128#ifdef GIT_WIN32
129 SetLastError(0);
130#endif
60bc2d20 131}
e3c47510 132
ac3d33df 133const git_error *git_error_last(void)
ef4857c2 134{
c25aa7cd
PP
135 /* If the library is not initialized, return a static error. */
136 if (!git_libgit2_init_count())
137 return &g_git_uninitialized_error;
138
139 return GIT_THREADSTATE->last_error;
ef4857c2
ET
140}
141
ac3d33df 142int git_error_state_capture(git_error_state *state, int error_code)
d6c60169 143{
c25aa7cd 144 git_error *error = GIT_THREADSTATE->last_error;
e579e0f7 145 git_str *error_buf = &GIT_THREADSTATE->error_buf;
d6c60169 146
ef4857c2 147 memset(state, 0, sizeof(git_error_state));
d6c60169 148
ef4857c2
ET
149 if (!error_code)
150 return 0;
151
152 state->error_code = error_code;
153 state->oom = (error == &g_git_oom_error);
d6c60169 154
ef4857c2
ET
155 if (error) {
156 state->error_msg.klass = error->klass;
d6c60169 157
ef4857c2
ET
158 if (state->oom)
159 state->error_msg.message = g_git_oom_error.message;
160 else
e579e0f7 161 state->error_msg.message = git_str_detach(error_buf);
0fcfb60d 162 }
d6c60169 163
ac3d33df 164 git_error_clear();
ef4857c2 165 return error_code;
d6c60169
RB
166}
167
ac3d33df 168int git_error_state_restore(git_error_state *state)
e3c47510 169{
ef4857c2 170 int ret = 0;
96869a4e 171
ac3d33df 172 git_error_clear();
96869a4e 173
ef4857c2
ET
174 if (state && state->error_msg.message) {
175 if (state->oom)
ac3d33df 176 git_error_set_oom();
ef4857c2 177 else
0fcfb60d 178 set_error(state->error_msg.klass, state->error_msg.message);
ef4857c2
ET
179
180 ret = state->error_code;
181 memset(state, 0, sizeof(git_error_state));
0fcfb60d 182 }
96869a4e 183
ef4857c2
ET
184 return ret;
185}
186
ac3d33df 187void git_error_state_free(git_error_state *state)
ef4857c2
ET
188{
189 if (!state)
190 return;
191
192 if (!state->oom)
193 git__free(state->error_msg.message);
194
195 memset(state, 0, sizeof(git_error_state));
96869a4e
RB
196}
197
ac3d33df 198int git_error_system_last(void)
96869a4e
RB
199{
200#ifdef GIT_WIN32
201 return GetLastError();
202#else
203 return errno;
204#endif
205}
206
ac3d33df 207void git_error_system_set(int code)
96869a4e
RB
208{
209#ifdef GIT_WIN32
210 SetLastError(code);
211#else
212 errno = code;
213#endif
214}
ac3d33df
JK
215
216/* Deprecated error values and functions */
217
22a2d3d5 218#ifndef GIT_DEPRECATE_HARD
ac3d33df
JK
219const git_error *giterr_last(void)
220{
221 return git_error_last();
222}
223
224void giterr_clear(void)
225{
226 git_error_clear();
227}
228
229void giterr_set_str(int error_class, const char *string)
230{
231 git_error_set_str(error_class, string);
232}
233
234void giterr_set_oom(void)
235{
236 git_error_set_oom();
237}
22a2d3d5 238#endif