source: roaraudio/libroar/error.c @ 4871:fd43e266a063

Last change on this file since 4871:fd43e266a063 was 4871:fd43e266a063, checked in by phi, 13 years ago

added some more error handling functions

File size: 11.7 KB
Line 
1//error.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38// 'no error' value for errno.
39// zero is true for GNU/Linux.
40// don't know about other systems.
41#define CLEAN_ERRNO 0
42
43int roar_errno = ROAR_ERROR_NONE;
44
45int    roar_err_int(struct roar_error_frame * frame) {
46 if ( frame == NULL )
47  return -1;
48
49 memset(frame, 0, sizeof(struct roar_error_frame));
50
51 frame->cmd         = -1;
52 frame->ra_errno    = -1;
53 frame->ra_suberrno = -1;
54 frame->p_errno     = -1;
55
56 return 0;
57}
58
59void * roar_err_buildmsg(struct roar_message * mes, struct roar_error_frame * frame) {
60 int16_t * d;
61
62 if ( mes == NULL || frame == NULL )
63  return NULL;
64
65 memset(mes,  0, sizeof(struct roar_message));
66
67 d = (int16_t*)mes->data;
68
69 mes->datalen = 8 + frame->datalen;
70 frame->data  = &(mes->data[8]);
71
72 mes->data[0]    = 0; // version.
73 mes->data[1]    = frame->cmd;
74 mes->data[2]    = frame->ra_errno;
75 mes->data[3]    = frame->ra_suberrno;
76 d[2]            = ROAR_HOST2NET16(frame->p_errno);
77 d[3]            = ROAR_HOST2NET16(frame->flags);
78
79 return frame->data;
80}
81
82int    roar_err_parsemsg(struct roar_message * mes, struct roar_error_frame * frame) {
83 int16_t * d;
84
85 if ( mes == NULL || frame == NULL )
86  return -1;
87
88 d = (int16_t*)mes->data;
89
90 if ( mes->datalen < 8 )
91  return -1;
92
93 if ( mes->data[0] != 0 )
94  return -1;
95
96 frame->cmd         = mes->data[1];
97 frame->ra_errno    = mes->data[2];
98 frame->ra_suberrno = mes->data[3];
99 frame->p_errno     = ROAR_NET2HOST16(d[2]);
100 frame->flags       = ROAR_NET2HOST16(d[3]);
101
102 frame->datalen     = mes->datalen - 8;
103 frame->data        = &(mes->data[8]);
104
105 return 0;
106}
107
108int *  roar_errno2(void) {
109 return &roar_errno;
110}
111
112void   roar_err_clear(void) {
113 *roar_errno2() = ROAR_ERROR_NONE;
114}
115
116void   roar_err_clear_errno(void) {
117 errno = CLEAN_ERRNO;
118}
119
120void   roar_err_clear_all(void) {
121 roar_err_clear();
122 roar_err_clear_errno();
123}
124
125void   roar_err_update(void) {
126 int * err = roar_errno2();
127 if ( *err != ROAR_ERROR_NONE ) {
128  roar_err_to_errno();
129 } else if ( !roar_err_is_errno_clean() ) {
130  roar_err_from_errno();
131 }
132}
133
134int    roar_err_is_errno_clean(void) {
135 return errno == CLEAN_ERRNO ? 1 : 0;
136}
137
138void   roar_err_set(const int error) {
139 *roar_errno2() = error;
140}
141
142void   roar_err_from_errno(void) {
143 int _roar_errno = ROAR_ERROR_NONE;
144
145 switch (errno) {
146#ifdef EPERM
147  case EPERM:        _roar_errno = ROAR_ERROR_PERM; break;
148#endif
149#ifdef ENOENT
150  case ENOENT:       _roar_errno = ROAR_ERROR_NOENT; break;
151#endif
152#ifdef EBADMSG
153  case EBADMSG:      _roar_errno = ROAR_ERROR_BADMSG; break;
154#endif
155#ifdef EBUSY
156  case EBUSY:        _roar_errno = ROAR_ERROR_BUSY; break;
157#endif
158#ifdef ECONNREFUSED
159  case ECONNREFUSED: _roar_errno = ROAR_ERROR_CONNREFUSED; break;
160#endif
161#ifdef ENOSYS
162  case ENOSYS:       _roar_errno = ROAR_ERROR_NOSYS; break;
163#endif
164#ifdef ENOTSUP
165  case ENOTSUP:      _roar_errno = ROAR_ERROR_NOTSUP; break;
166#endif
167#ifdef EPIPE
168  case EPIPE:        _roar_errno = ROAR_ERROR_PIPE; break;
169#endif
170#ifdef EPROTO
171  case EPROTO:       _roar_errno = ROAR_ERROR_PROTO; break;
172#endif
173#ifdef ERANGE
174  case ERANGE:       _roar_errno = ROAR_ERROR_RANGE; break;
175#endif
176#ifdef EMSGSIZE
177  case EMSGSIZE:     _roar_errno = ROAR_ERROR_MSGSIZE; break;
178#endif
179#ifdef ENOMEM
180  case ENOMEM:       _roar_errno = ROAR_ERROR_NOMEM; break;
181#endif
182#ifdef EINVAL
183  case EINVAL:       _roar_errno = ROAR_ERROR_INVAL; break;
184#endif
185#ifdef EALREADY
186  case EALREADY:     _roar_errno = ROAR_ERROR_ALREADY; break;
187#endif
188#ifdef EBADRQC
189  case EBADRQC:      _roar_errno = ROAR_ERROR_BADRQC; break;
190#endif
191#ifdef EDOM
192  case EDOM:         _roar_errno = ROAR_ERROR_DOM; break;
193#endif
194#ifdef EEXIST
195  case EEXIST:       _roar_errno = ROAR_ERROR_EXIST; break;
196#endif
197#ifdef EFAULT
198  case EFAULT:       _roar_errno = ROAR_ERROR_FAULT; break;
199#endif
200#ifdef EIO
201  case EIO:          _roar_errno = ROAR_ERROR_IO; break;
202#endif
203#ifdef EKEYEXPIRED
204  case EKEYEXPIRED:  _roar_errno = ROAR_ERROR_KEYEXPIRED; break;
205#endif
206#ifdef EKEYREJECTED
207  case EKEYREJECTED: _roar_errno = ROAR_ERROR_KEYREJECTED; break;
208#endif
209#ifdef ELOOP
210  case ELOOP:        _roar_errno = ROAR_ERROR_LOOP; break;
211#endif
212#ifdef EMFILE
213  case EMFILE:       _roar_errno = ROAR_ERROR_MFILE; break;
214#endif
215#ifdef ENAMETOOLONG
216  case ENAMETOOLONG: _roar_errno = ROAR_ERROR_NAMETOOLONG; break;
217#endif
218#ifdef ENODATA
219  case ENODATA:      _roar_errno = ROAR_ERROR_NODATA; break;
220#endif
221#ifdef ENODEV
222  case ENODEV:       _roar_errno = ROAR_ERROR_NODEV; break;
223#endif
224#ifdef ENOSPC
225  case ENOSPC:       _roar_errno = ROAR_ERROR_NOSPC; break;
226#endif
227#ifdef ENOTCONN
228  case ENOTCONN:     _roar_errno = ROAR_ERROR_NOTCONN; break;
229#endif
230#ifdef EPROTONOSUPPORT
231  case EPROTONOSUPPORT: _roar_errno = ROAR_ERROR_PROTONOSUP; break;
232#endif
233#ifdef EROFS
234  case EROFS:        _roar_errno = ROAR_ERROR_RO; break;
235#endif
236#ifdef ETIMEDOUT
237  case ETIMEDOUT:    _roar_errno = ROAR_ERROR_TIMEDOUT; break;
238#endif
239#ifdef EAGAIN
240  case EAGAIN:       _roar_errno = ROAR_ERROR_AGAIN; break;
241#endif
242#ifdef ENETDOWN
243  case ENETDOWN:     _roar_errno = ROAR_ERROR_LINKDOWN; break;
244#endif
245  default:
246    _roar_errno = ROAR_ERROR_UNKNOWN;
247   break;
248 }
249
250 roar_err_set(_roar_errno);
251}
252
253void   roar_err_to_errno(void) {
254 int * err = roar_errno2();
255 switch (*err) {
256  case ROAR_ERROR_NONE:
257    roar_err_clear_errno();
258   break;
259#ifdef EPERM
260  case ROAR_ERROR_PERM:
261    errno = EPERM;
262   break;
263#endif
264#ifdef ENOENT
265  case ROAR_ERROR_NOENT:
266    errno = ENOENT;
267   break;
268#endif
269#ifdef EBADMSG
270  case ROAR_ERROR_BADMSG:
271    errno = EBADMSG;
272   break;
273#endif
274#ifdef EBUSY
275  case ROAR_ERROR_BUSY:
276    errno = EBUSY;
277   break;
278#endif
279#ifdef ECONNREFUSED
280  case ROAR_ERROR_CONNREFUSED:
281    errno = ECONNREFUSED;
282   break;
283#endif
284#ifdef ENOSYS
285  case ROAR_ERROR_NOSYS:
286    errno = ENOSYS;
287   break;
288#endif
289#ifdef ENOTSUP
290  case ROAR_ERROR_NOTSUP:
291    errno = ENOTSUP;
292   break;
293#endif
294#ifdef EPIPE
295  case ROAR_ERROR_PIPE:
296    errno = EPIPE;
297   break;
298#endif
299#ifdef EPROTO
300  case ROAR_ERROR_PROTO:
301    errno = EPROTO;
302   break;
303#endif
304#ifdef ERANGE
305  case ROAR_ERROR_RANGE:
306    errno = ERANGE;
307   break;
308#endif
309#ifdef EMSGSIZE
310  case ROAR_ERROR_MSGSIZE:
311    errno = EMSGSIZE;
312   break;
313#endif
314#ifdef ENOMEM
315  case ROAR_ERROR_NOMEM:
316    errno = ENOMEM;
317   break;
318#endif
319#ifdef EINVAL
320  case ROAR_ERROR_INVAL:
321    errno = EINVAL;
322   break;
323#endif
324#ifdef EALREADY
325  case ROAR_ERROR_ALREADY:
326    errno = EALREADY;
327   break;
328#endif
329#ifdef EBADRQC
330  case ROAR_ERROR_BADRQC:
331    errno = EBADRQC;
332   break;
333#endif
334#ifdef EDOM
335  case ROAR_ERROR_DOM:
336    errno = EDOM;
337   break;
338#endif
339#ifdef EEXIST
340  case ROAR_ERROR_EXIST:
341    errno = EEXIST;
342   break;
343#endif
344#ifdef EFAULT
345  case ROAR_ERROR_FAULT:
346    errno = EFAULT;
347   break;
348#endif
349#ifdef EIO
350  case ROAR_ERROR_IO:
351  case ROAR_ERROR_RIO:
352    errno = EIO;
353   break;
354#endif
355#ifdef EKEYEXPIRED
356  case ROAR_ERROR_KEYEXPIRED:
357    errno = EKEYEXPIRED;
358   break;
359#endif
360#ifdef EKEYREJECTED
361  case ROAR_ERROR_KEYREJECTED:
362    errno = EKEYREJECTED;
363   break;
364#endif
365#ifdef ELOOP
366  case ROAR_ERROR_LOOP:
367    errno = ELOOP;
368   break;
369#endif
370#ifdef EMFILE
371  case ROAR_ERROR_MFILE:
372    errno = EMFILE;
373   break;
374#endif
375#ifdef ENAMETOOLONG
376  case ROAR_ERROR_NAMETOOLONG:
377    errno = ENAMETOOLONG;
378   break;
379#endif
380#ifdef ENODATA
381  case ROAR_ERROR_NODATA:
382    errno = ENODATA;
383   break;
384#endif
385#ifdef ENODEV
386  case ROAR_ERROR_NODEV:
387  case ROAR_ERROR_NODRV:
388    errno = ENODEV;
389   break;
390#endif
391#ifdef ENOSPC
392  case ROAR_ERROR_NOSPC:
393    errno = ENOSPC;
394   break;
395#endif
396#ifdef EINVAL
397  case ROAR_ERROR_TYPEMM:
398    errno = EINVAL;
399   break;
400#endif
401#ifdef ENOSYS
402  case ROAR_ERROR_NORSYS:
403    errno = ENOSYS;
404   break;
405#endif
406#ifdef ENOTCONN
407  case ROAR_ERROR_NOTCONN:
408    errno = ENOTCONN;
409   break;
410#endif
411#ifdef EPROTONOSUPPORT
412  case ROAR_ERROR_PROTONOSUP:
413    errno = EPROTONOSUPPORT;
414   break;
415#endif
416#ifdef EROFS
417  case ROAR_ERROR_RO:
418    errno = EROFS;
419   break;
420#endif
421#ifdef ETIMEDOUT
422  case ROAR_ERROR_TIMEDOUT:
423    errno = ETIMEDOUT;
424   break;
425#endif
426#ifdef EAGAIN
427  case ROAR_ERROR_AGAIN:
428    errno = EAGAIN;
429   break;
430#endif
431#ifdef ENETDOWN
432  case ROAR_ERROR_LINKDOWN:
433    errno = ENETDOWN;
434   break;
435#endif
436  default:
437#ifdef EINVAL
438    errno = EINVAL;
439#else
440    errno = -1; // just guess
441#endif
442   break;
443 }
444}
445
446
447const char * roar_error2str(const int error) {
448 const struct {
449  const int    err;
450  const char * msg;
451 } msgs[] = {
452  {ROAR_ERROR_NONE,        "No error"},
453  {ROAR_ERROR_PERM,        "Operation not permitted"},
454  {ROAR_ERROR_NOENT,       "No such object, file or directory"},
455  {ROAR_ERROR_BADMSG,      "Bad message"},
456  {ROAR_ERROR_BUSY,        "Device or resource busy"},
457  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
458  {ROAR_ERROR_NOSYS,       "Function not implemented"},
459  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
460  {ROAR_ERROR_PIPE,        "Broken pipe"},
461  {ROAR_ERROR_PROTO,       "Protocol error"},
462  {ROAR_ERROR_RANGE,       "Result too large or parameter out of range"},
463  {ROAR_ERROR_MSGSIZE,     "Message too long"},
464  {ROAR_ERROR_NOMEM,       "Not enough space"},
465  {ROAR_ERROR_INVAL,       "Invalid argument"},
466  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
467  {ROAR_ERROR_BADRQC,      "Invalid request code"},
468  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
469  {ROAR_ERROR_EXIST,       "File or object exists"},
470  {ROAR_ERROR_FAULT,       "Bad address"},
471  {ROAR_ERROR_IO,          "I/O-Error"},
472  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
473  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
474  {ROAR_ERROR_LOOP,        "Too many recursions"},
475  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
476  {ROAR_ERROR_NAMETOOLONG, "File or object name too long"},
477  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
478  {ROAR_ERROR_NODEV,       "No such device"},
479  {ROAR_ERROR_NODRV,       "No such driver"},
480  {ROAR_ERROR_NOSPC,       "No space left on device"},
481  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
482  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
483  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
484  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
485  {ROAR_ERROR_RIO,         "Remote I/O Error"},
486  {ROAR_ERROR_RO,          "File or object is read only"},
487  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
488  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
489  {ROAR_ERROR_NOISE,       "Line too noisy"},
490  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
491  {-1, NULL}
492 };
493 int i;
494
495 for (i = 0; msgs[i].msg != NULL; i++)
496  if ( msgs[i].err == error )
497   return msgs[i].msg;
498
499 return NULL;
500}
501
502//ll
Note: See TracBrowser for help on using the repository browser.