]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-error.c
bus: synthesize timeout message errors instead of returning error codes
[thirdparty/systemd.git] / src / libsystemd-bus / bus-error.c
CommitLineData
de1c301e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <errno.h>
23#include <stdlib.h>
24#include <stdarg.h>
25#include <stdbool.h>
26#include <string.h>
27#include <stdio.h>
28
29#include "util.h"
30
31#include "sd-bus.h"
32#include "bus-error.h"
33
fbfa72b0
LP
34bool bus_error_is_dirty(sd_bus_error *e) {
35 if (!e)
36 return 0;
37
38 return e->name || e->message || e->need_free;
39}
40
de1c301e
LP
41void sd_bus_error_free(sd_bus_error *e) {
42 if (!e)
43 return;
44
45 if (e->need_free) {
46 free((void*) e->name);
47 free((void*) e->message);
48 }
49
50 e->name = e->message = NULL;
51 e->need_free = false;
52}
53
54int sd_bus_error_set(sd_bus_error *e, const char *name, const char *format, ...) {
55 char *n, *m = NULL;
56 va_list ap;
57 int r;
58
59 if (!e)
60 return 0;
fbfa72b0 61 if (bus_error_is_dirty(e))
de1c301e
LP
62 return -EINVAL;
63 if (!name)
64 return -EINVAL;
65
66 n = strdup(name);
67 if (!n)
68 return -ENOMEM;
69
70 if (format) {
71 va_start(ap, format);
72 r = vasprintf(&m, format, ap);
73 va_end(ap);
74
75 if (r < 0) {
76 free(n);
77 return -ENOMEM;
78 }
79 }
80
81 e->name = n;
82 e->message = m;
83 e->need_free = true;
84
85 return 0;
86}
87
88int sd_bus_error_copy(sd_bus_error *dest, const sd_bus_error *e) {
89ffcd2a
LP
89 char *x, *y = NULL;
90
de1c301e
LP
91 if (!dest)
92 return 0;
fbfa72b0 93 if (bus_error_is_dirty(dest))
de1c301e
LP
94 return -EINVAL;
95 if (!sd_bus_error_is_set(e))
96 return 0;
97
89ffcd2a
LP
98 x = strdup(e->name);
99 if (!x)
100 return -ENOMEM;
de1c301e 101
89ffcd2a
LP
102 if (e->message) {
103 y = strdup(e->message);
104 if (!y) {
105 free(x);
de1c301e 106 return -ENOMEM;
de1c301e 107 }
89ffcd2a 108 }
de1c301e 109
89ffcd2a
LP
110 dest->name = x;
111 dest->message = y;
112 dest->need_free = true;
de1c301e
LP
113 return 0;
114}
115
116void sd_bus_error_set_const(sd_bus_error *e, const char *name, const char *message) {
117 if (!e)
118 return;
fbfa72b0 119 if (bus_error_is_dirty(e))
de1c301e
LP
120 return;
121
122 e->name = name;
123 e->message = message;
fbfa72b0 124 e->need_free = false;
de1c301e
LP
125}
126
127int sd_bus_error_is_set(const sd_bus_error *e) {
128 if (!e)
129 return 0;
130
fbfa72b0 131 return !!e->name;
de1c301e
LP
132}
133
134int sd_bus_error_has_name(const sd_bus_error *e, const char *name) {
135 if (!e)
136 return 0;
137
138 return streq_ptr(e->name, name);
139}
140
141int bus_error_to_errno(const sd_bus_error* e) {
142
143 /* Better replce this with a gperf table */
144
eb01ba5d
LP
145 if (!e)
146 return -EIO;
147
de1c301e
LP
148 if (!e->name)
149 return -EIO;
150
151 if (streq(e->name, "org.freedesktop.DBus.Error.NoMemory"))
152 return -ENOMEM;
153
154 if (streq(e->name, "org.freedesktop.DBus.Error.AuthFailed") ||
155 streq(e->name, "org.freedesktop.DBus.Error.AccessDenied"))
156 return -EPERM;
157
eb01ba5d
LP
158 if (streq(e->name, "org.freedesktop.DBus.Error.InvalidArgs"))
159 return -EINVAL;
160
161 if (streq(e->name, "org.freedesktop.DBus.Error.UnixProcessIdUnknown"))
162 return -ESRCH;
163
164 if (streq(e->name, "org.freedesktop.DBus.Error.FileNotFound"))
165 return -ENOENT;
166
167 if (streq(e->name, "org.freedesktop.DBus.Error.FileExists"))
168 return -EEXIST;
169
170 if (streq(e->name, "org.freedesktop.DBus.Error.Timeout"))
171 return -ETIMEDOUT;
172
173 if (streq(e->name, "org.freedesktop.DBus.Error.IOError"))
174 return -EIO;
175
176 if (streq(e->name, "org.freedesktop.DBus.Error.Disconnected"))
177 return -ECONNRESET;
178
179 if (streq(e->name, "org.freedesktop.DBus.Error.NotSupported"))
180 return -ENOTSUP;
181
de1c301e
LP
182 return -EIO;
183}
184
185int bus_error_from_errno(sd_bus_error *e, int error) {
186 if (!e)
187 return error;
188
eb01ba5d
LP
189 switch (error) {
190
191 case -ENOMEM:
192 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.NoMemory", "Out of memory");
193 break;
194
195 case -EPERM:
196 case -EACCES:
197 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.AccessDenied", "Access denied");
198 break;
199
200 case -EINVAL:
201 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid argument");
202 break;
203
204 case -ESRCH:
205 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.UnixProcessIdUnknown", "No such process");
206 break;
207
208 case -ENOENT:
209 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.FileNotFound", "File not found");
210 break;
211
212 case -EEXIST:
213 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.FileExists", "File exists");
214 break;
215
216 case -ETIMEDOUT:
217 case -ETIME:
218 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.Timeout", "Timed out");
219 break;
220
221 case -EIO:
222 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.IOError", "Input/output error");
223 break;
224
225 case -ENETRESET:
226 case -ECONNABORTED:
227 case -ECONNRESET:
228 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.Disconnected", "Disconnected");
229 break;
230
231 case -ENOTSUP:
232 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.NotSupported", "Not supported");
233 break;
234 }
de1c301e 235
eb01ba5d 236 sd_bus_error_set_const(e, "org.freedesktop.DBus.Error.Failed", "Operation failed");
de1c301e
LP
237 return error;
238}
e3017af9
LP
239
240const char *bus_error_message(const sd_bus_error *e, int error) {
241 if (e && e->message)
242 return e->message;
243
244 return strerror(error);
245}