]> git.proxmox.com Git - libgit2.git/blame - src/errors.c
Include stacktrace summary in memory leak output.
[libgit2.git] / src / 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 */
ae234862 7#include "common.h"
a15c550d 8#include "global.h"
60bc2d20 9#include "posix.h"
22772166 10#include "buffer.h"
02f9e637 11
60bc2d20
VM
12/********************************************
13 * New error handling
14 ********************************************/
15
1a481123
VM
16static git_error g_git_oom_error = {
17 "Out of memory",
18 GITERR_NOMEMORY
19};
20
22772166
VM
21static void set_error(int error_class, char *string)
22{
23 git_error *error = &GIT_GLOBAL->error_t;
24
96869a4e
RB
25 if (error->message != string)
26 git__free(error->message);
22772166
VM
27
28 error->message = string;
29 error->klass = error_class;
30
31 GIT_GLOBAL->last_error = error;
32}
33
1a481123
VM
34void giterr_set_oom(void)
35{
36 GIT_GLOBAL->last_error = &g_git_oom_error;
37}
38
39void giterr_set(int error_class, const char *string, ...)
60bc2d20 40{
22772166 41 git_buf buf = GIT_BUF_INIT;
60bc2d20 42 va_list arglist;
3ae0aad7
RB
43#ifdef GIT_WIN32
44 DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0;
45#endif
46 int error_code = (error_class == GITERR_OS) ? errno : 0;
60bc2d20 47
e62f96de
ET
48 if (string) {
49 va_start(arglist, string);
50 git_buf_vprintf(&buf, string, arglist);
51 va_end(arglist);
52
53 if (error_class == GITERR_OS)
54 git_buf_PUTS(&buf, ": ");
55 }
60bc2d20 56
dda708e7 57 if (error_class == GITERR_OS) {
e1de726c 58#ifdef GIT_WIN32
c70455c7
SS
59 char * win32_error = git_win32_get_error_message(win32_error_code);
60 if (win32_error) {
c70455c7
SS
61 git_buf_puts(&buf, win32_error);
62 git__free(win32_error);
8f624a47
PK
63
64 SetLastError(0);
e1de726c 65 }
8f624a47 66 else
e1de726c 67#endif
e62f96de 68 if (error_code)
8f624a47 69 git_buf_puts(&buf, strerror(error_code));
8f624a47
PK
70
71 if (error_code)
72 errno = 0;
ae9e29fd
RB
73 }
74
22772166
VM
75 if (!git_buf_oom(&buf))
76 set_error(error_class, git_buf_detach(&buf));
dda708e7
VM
77}
78
79void giterr_set_str(int error_class, const char *string)
80{
1a628100
RB
81 char *message;
82
83 assert(string);
84
85 message = git__strdup(string);
dda708e7 86
22772166
VM
87 if (message)
88 set_error(error_class, message);
60bc2d20
VM
89}
90
cc146626 91int giterr_set_regex(const regex_t *regex, int error_code)
dda708e7
VM
92{
93 char error_buf[1024];
6c72035f
PK
94
95 assert(error_code);
96
dda708e7
VM
97 regerror(error_code, regex, error_buf, sizeof(error_buf));
98 giterr_set_str(GITERR_REGEX, error_buf);
cc146626 99
100 if (error_code == REG_NOMATCH)
101 return GIT_ENOTFOUND;
6c72035f
PK
102
103 return GIT_EINVALIDSPEC;
dda708e7
VM
104}
105
1a481123 106void giterr_clear(void)
60bc2d20 107{
96869a4e
RB
108 if (GIT_GLOBAL->last_error != NULL) {
109 set_error(0, NULL);
110 GIT_GLOBAL->last_error = NULL;
111 }
97a17e4e
RB
112
113 errno = 0;
114#ifdef GIT_WIN32
115 SetLastError(0);
116#endif
60bc2d20 117}
e3c47510 118
1eab9f0e 119int giterr_detach(git_error *cpy)
d6c60169 120{
d6c60169
RB
121 git_error *error = GIT_GLOBAL->last_error;
122
1eab9f0e 123 assert(cpy);
d6c60169
RB
124
125 if (!error)
1eab9f0e 126 return -1;
d6c60169 127
1eab9f0e
VM
128 cpy->message = error->message;
129 cpy->klass = error->klass;
d6c60169
RB
130
131 error->message = NULL;
132 giterr_clear();
133
1eab9f0e 134 return 0;
d6c60169
RB
135}
136
3fbcac89 137const git_error *giterr_last(void)
e3c47510
RB
138{
139 return GIT_GLOBAL->last_error;
140}
96869a4e
RB
141
142int giterr_capture(git_error_state *state, int error_code)
143{
144 state->error_code = error_code;
145 if (error_code)
146 giterr_detach(&state->error_msg);
147 return error_code;
148}
149
150int giterr_restore(git_error_state *state)
151{
152 if (state && state->error_code && state->error_msg.message)
153 set_error(state->error_msg.klass, state->error_msg.message);
154 else
155 giterr_clear();
156
157 return state ? state->error_code : 0;
158}
159
160int giterr_system_last(void)
161{
162#ifdef GIT_WIN32
163 return GetLastError();
164#else
165 return errno;
166#endif
167}
168
169void giterr_system_set(int code)
170{
171#ifdef GIT_WIN32
172 SetLastError(code);
173#else
174 errno = code;
175#endif
176}