source: roaraudio/libroar/error.c @ 5034:447ce1817e45

Last change on this file since 5034:447ce1817e45 was 5034:447ce1817e45, checked in by phi, 13 years ago

added info about posix

File size: 14.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// IEEE Std 1003.1-2008 (POSIX 7) requires:
42// 'distinct positive values'.
43#define CLEAN_ERRNO 0
44
45int roar_errno = ROAR_ERROR_NONE;
46
47int    roar_err_int(struct roar_error_frame * frame) {
48 if ( frame == NULL )
49  return -1;
50
51 memset(frame, 0, sizeof(struct roar_error_frame));
52
53 frame->cmd         = -1;
54 frame->ra_errno    = -1;
55 frame->ra_suberrno = -1;
56 frame->p_errno     = -1;
57
58 return 0;
59}
60
61void * roar_err_buildmsg(struct roar_message * mes, struct roar_error_frame * frame) {
62 int16_t * d;
63
64 if ( mes == NULL || frame == NULL )
65  return NULL;
66
67 memset(mes,  0, sizeof(struct roar_message));
68
69 d = (int16_t*)mes->data;
70
71 mes->datalen = 8 + frame->datalen;
72 frame->data  = &(mes->data[8]);
73
74 mes->data[0]    = 0; // version.
75 mes->data[1]    = frame->cmd;
76 mes->data[2]    = frame->ra_errno;
77 mes->data[3]    = frame->ra_suberrno;
78 d[2]            = ROAR_HOST2NET16(frame->p_errno);
79 d[3]            = ROAR_HOST2NET16(frame->flags);
80
81 return frame->data;
82}
83
84int    roar_err_parsemsg(struct roar_message * mes, struct roar_error_frame * frame) {
85 int16_t * d;
86
87 if ( mes == NULL || frame == NULL )
88  return -1;
89
90 d = (int16_t*)mes->data;
91
92 if ( mes->datalen < 8 )
93  return -1;
94
95 if ( mes->data[0] != 0 )
96  return -1;
97
98 frame->cmd         = mes->data[1];
99 frame->ra_errno    = mes->data[2];
100 frame->ra_suberrno = mes->data[3];
101 frame->p_errno     = ROAR_NET2HOST16(d[2]);
102 frame->flags       = ROAR_NET2HOST16(d[3]);
103
104 frame->datalen     = mes->datalen - 8;
105 frame->data        = &(mes->data[8]);
106
107 return 0;
108}
109
110int *  roar_errno2(void) {
111 return &roar_errno;
112}
113
114void   roar_err_clear(void) {
115 *roar_errno2() = ROAR_ERROR_NONE;
116}
117
118void   roar_err_clear_errno(void) {
119 errno = CLEAN_ERRNO;
120}
121
122void   roar_err_clear_all(void) {
123 roar_err_clear();
124 roar_err_clear_errno();
125}
126
127void   roar_err_update(void) {
128 int * err = roar_errno2();
129
130 // NOTE: _NEVER_ call ROAR_{DBG,INFO,WARN,ERRO}() in here! (will result in endless loop)
131 //printf("*err=%i, errno=%i\n", *err, (int)errno);
132
133 if ( *err != ROAR_ERROR_NONE ) {
134  roar_err_to_errno();
135 } else if ( !roar_err_is_errno_clean() ) {
136  roar_err_from_errno();
137 }
138}
139
140int    roar_err_is_errno_clean(void) {
141 return errno == CLEAN_ERRNO ? 1 : 0;
142}
143
144void   roar_err_set(const int error) {
145 *roar_errno2() = error;
146}
147
148void   roar_err_from_errno(void) {
149 int _roar_errno = ROAR_ERROR_NONE;
150
151 switch (errno) {
152#ifdef EACCES
153  case EACCES:       _roar_errno = ROAR_ERROR_PERM; break;
154#endif
155#ifdef EPERM
156  case EPERM:        _roar_errno = ROAR_ERROR_PERM; break;
157#endif
158#ifdef ENOENT
159  case ENOENT:       _roar_errno = ROAR_ERROR_NOENT; break;
160#endif
161#ifdef EBADMSG
162  case EBADMSG:      _roar_errno = ROAR_ERROR_BADMSG; break;
163#endif
164#ifdef EBUSY
165  case EBUSY:        _roar_errno = ROAR_ERROR_BUSY; break;
166#endif
167#ifdef ECONNREFUSED
168  case ECONNREFUSED: _roar_errno = ROAR_ERROR_CONNREFUSED; break;
169#endif
170#ifdef ENOSYS
171  case ENOSYS:       _roar_errno = ROAR_ERROR_NOSYS; break;
172#endif
173#ifdef ENOTSUP
174  case ENOTSUP:      _roar_errno = ROAR_ERROR_NOTSUP; break;
175#endif
176#ifdef EPIPE
177  case EPIPE:        _roar_errno = ROAR_ERROR_PIPE; break;
178#endif
179#ifdef EPROTO
180  case EPROTO:       _roar_errno = ROAR_ERROR_PROTO; break;
181#endif
182#ifdef ERANGE
183  case ERANGE:       _roar_errno = ROAR_ERROR_RANGE; break;
184#endif
185#ifdef EMSGSIZE
186  case EMSGSIZE:     _roar_errno = ROAR_ERROR_MSGSIZE; break;
187#endif
188#ifdef ENOMEM
189  case ENOMEM:       _roar_errno = ROAR_ERROR_NOMEM; break;
190#endif
191#ifdef EINVAL
192  case EINVAL:       _roar_errno = ROAR_ERROR_INVAL; break;
193#endif
194#ifdef EALREADY
195  case EALREADY:     _roar_errno = ROAR_ERROR_ALREADY; break;
196#endif
197#ifdef EBADRQC
198  case EBADRQC:      _roar_errno = ROAR_ERROR_BADRQC; break;
199#endif
200#ifdef EDOM
201  case EDOM:         _roar_errno = ROAR_ERROR_DOM; break;
202#endif
203#ifdef EEXIST
204  case EEXIST:       _roar_errno = ROAR_ERROR_EXIST; break;
205#endif
206#ifdef EFAULT
207  case EFAULT:       _roar_errno = ROAR_ERROR_FAULT; break;
208#endif
209#ifdef EIO
210  case EIO:          _roar_errno = ROAR_ERROR_IO; break;
211#endif
212#ifdef EREMOTEIO
213  case EREMOTEIO:    _roar_errno = ROAR_ERROR_RIO; break;
214#endif
215#ifdef EKEYEXPIRED
216  case EKEYEXPIRED:  _roar_errno = ROAR_ERROR_KEYEXPIRED; break;
217#endif
218#ifdef EKEYREJECTED
219  case EKEYREJECTED: _roar_errno = ROAR_ERROR_KEYREJECTED; break;
220#endif
221#ifdef ELOOP
222  case ELOOP:        _roar_errno = ROAR_ERROR_LOOP; break;
223#endif
224#ifdef EMFILE
225  case EMFILE:       _roar_errno = ROAR_ERROR_MFILE; break;
226#endif
227#ifdef ENAMETOOLONG
228  case ENAMETOOLONG: _roar_errno = ROAR_ERROR_NAMETOOLONG; break;
229#endif
230#ifdef ENODATA
231  case ENODATA:      _roar_errno = ROAR_ERROR_NODATA; break;
232#endif
233#ifdef ENODEV
234  case ENODEV:       _roar_errno = ROAR_ERROR_NODEV; break;
235#endif
236#ifdef ENOSPC
237  case ENOSPC:       _roar_errno = ROAR_ERROR_NOSPC; break;
238#endif
239#ifdef ENOTCONN
240  case ENOTCONN:     _roar_errno = ROAR_ERROR_NOTCONN; break;
241#endif
242#ifdef EPROTONOSUPPORT
243  case EPROTONOSUPPORT: _roar_errno = ROAR_ERROR_PROTONOSUP; break;
244#endif
245#ifdef EROFS
246  case EROFS:        _roar_errno = ROAR_ERROR_RO; break;
247#endif
248#ifdef ETIMEDOUT
249  case ETIMEDOUT:    _roar_errno = ROAR_ERROR_TIMEDOUT; break;
250#endif
251#ifdef EAGAIN
252  case EAGAIN:       _roar_errno = ROAR_ERROR_AGAIN; break;
253#endif
254#ifdef ENETDOWN
255  case ENETDOWN:     _roar_errno = ROAR_ERROR_LINKDOWN; break;
256#endif
257#ifdef EINTR
258  case EINTR:        _roar_errno = ROAR_ERROR_INTERRUPTED; break;
259#endif
260#ifdef EDQUOT
261  case EDQUOT:       _roar_errno = ROAR_ERROR_QUOTA; break;
262#endif
263#ifdef ELIBBAD
264  case ELIBBAD:      _roar_errno = ROAR_ERROR_BADLIB; break;
265#endif
266#ifdef ENOMEDIUM
267  case ENOMEDIUM:    _roar_errno = ROAR_ERROR_NOMEDIUM; break;
268#endif
269#ifdef ENOTUNIQ
270  case ENOTUNIQ:     _roar_errno = ROAR_ERROR_NOTUNIQ; break;
271#endif
272#ifdef EILSEQ
273  case EILSEQ:       _roar_errno = ROAR_ERROR_ILLSEQ; break;
274#endif
275#ifdef EADDRINUSE
276  case EADDRINUSE:   _roar_errno = ROAR_ERROR_ADDRINUSE; break;
277#endif
278#ifdef ESPIPE
279  case ESPIPE:       _roar_errno = ROAR_ERROR_BADSEEK; break;
280#endif
281  default:
282    _roar_errno = ROAR_ERROR_UNKNOWN;
283   break;
284 }
285
286 roar_err_set(_roar_errno);
287}
288
289void   roar_err_to_errno(void) {
290 int * err = roar_errno2();
291 switch (*err) {
292  case ROAR_ERROR_NONE:
293    roar_err_clear_errno();
294   break;
295#ifdef EPERM
296  case ROAR_ERROR_PERM:
297    errno = EPERM;
298   break;
299#endif
300#ifdef ENOENT
301  case ROAR_ERROR_NOENT:
302    errno = ENOENT;
303   break;
304#endif
305#ifdef EBADMSG
306  case ROAR_ERROR_BADMSG:
307    errno = EBADMSG;
308   break;
309#endif
310#ifdef EBUSY
311  case ROAR_ERROR_BUSY:
312    errno = EBUSY;
313   break;
314#endif
315#ifdef ECONNREFUSED
316  case ROAR_ERROR_CONNREFUSED:
317    errno = ECONNREFUSED;
318   break;
319#endif
320#ifdef ENOSYS
321  case ROAR_ERROR_NOSYS:
322    errno = ENOSYS;
323   break;
324#endif
325#ifdef ENOTSUP
326  case ROAR_ERROR_NOTSUP:
327    errno = ENOTSUP;
328   break;
329#endif
330#ifdef EPIPE
331  case ROAR_ERROR_PIPE:
332    errno = EPIPE;
333   break;
334#endif
335#ifdef EPROTO
336  case ROAR_ERROR_PROTO:
337    errno = EPROTO;
338   break;
339#endif
340#ifdef ERANGE
341  case ROAR_ERROR_RANGE:
342    errno = ERANGE;
343   break;
344#endif
345#ifdef EMSGSIZE
346  case ROAR_ERROR_MSGSIZE:
347    errno = EMSGSIZE;
348   break;
349#endif
350#ifdef ENOMEM
351  case ROAR_ERROR_NOMEM:
352    errno = ENOMEM;
353   break;
354#endif
355#ifdef EINVAL
356  case ROAR_ERROR_INVAL:
357    errno = EINVAL;
358   break;
359#endif
360#ifdef EALREADY
361  case ROAR_ERROR_ALREADY:
362    errno = EALREADY;
363   break;
364#endif
365#ifdef EBADRQC
366  case ROAR_ERROR_BADRQC:
367    errno = EBADRQC;
368   break;
369#endif
370#ifdef EDOM
371  case ROAR_ERROR_DOM:
372    errno = EDOM;
373   break;
374#endif
375#ifdef EEXIST
376  case ROAR_ERROR_EXIST:
377    errno = EEXIST;
378   break;
379#endif
380#ifdef EFAULT
381  case ROAR_ERROR_FAULT:
382    errno = EFAULT;
383   break;
384#endif
385#if defined(EREMOTEIO) || defined(EIO)
386  case ROAR_ERROR_RIO:
387#ifdef EREMOTEIO
388    errno = EREMOTEIO;
389#else
390    errno = EIO;
391#endif
392   break;
393#endif
394#ifdef EIO
395  case ROAR_ERROR_IO:
396  case ROAR_ERROR_HOLE:
397  case ROAR_ERROR_BADCKSUM:
398  case ROAR_ERROR_LOSTSYNC:
399  case ROAR_ERROR_NOHORSE:
400    errno = EIO;
401   break;
402#endif
403#ifdef EKEYEXPIRED
404  case ROAR_ERROR_KEYEXPIRED:
405    errno = EKEYEXPIRED;
406   break;
407#endif
408#ifdef EKEYREJECTED
409  case ROAR_ERROR_KEYREJECTED:
410    errno = EKEYREJECTED;
411   break;
412#endif
413#ifdef ELOOP
414  case ROAR_ERROR_LOOP:
415    errno = ELOOP;
416   break;
417#endif
418#ifdef EMFILE
419  case ROAR_ERROR_MFILE:
420    errno = EMFILE;
421   break;
422#endif
423#ifdef ENAMETOOLONG
424  case ROAR_ERROR_NAMETOOLONG:
425    errno = ENAMETOOLONG;
426   break;
427#endif
428#ifdef ENODATA
429  case ROAR_ERROR_NODATA:
430    errno = ENODATA;
431   break;
432#endif
433#ifdef ENODEV
434  case ROAR_ERROR_NODEV:
435  case ROAR_ERROR_NODRV:
436    errno = ENODEV;
437   break;
438#endif
439#ifdef ENOSPC
440  case ROAR_ERROR_NOSPC:
441    errno = ENOSPC;
442   break;
443#endif
444#ifdef EINVAL
445  case ROAR_ERROR_TYPEMM:
446    errno = EINVAL;
447   break;
448#endif
449#ifdef ENOSYS
450  case ROAR_ERROR_NORSYS:
451    errno = ENOSYS;
452   break;
453#endif
454#ifdef ENOTCONN
455  case ROAR_ERROR_NOTCONN:
456    errno = ENOTCONN;
457   break;
458#endif
459#ifdef EPROTONOSUPPORT
460  case ROAR_ERROR_PROTONOSUP:
461    errno = EPROTONOSUPPORT;
462   break;
463#endif
464#ifdef EROFS
465  case ROAR_ERROR_RO:
466    errno = EROFS;
467   break;
468#endif
469#ifdef ETIMEDOUT
470  case ROAR_ERROR_TIMEDOUT:
471    errno = ETIMEDOUT;
472   break;
473#endif
474#ifdef EAGAIN
475  case ROAR_ERROR_AGAIN:
476    errno = EAGAIN;
477   break;
478#endif
479#ifdef ENETDOWN
480  case ROAR_ERROR_LINKDOWN:
481    errno = ENETDOWN;
482   break;
483#endif
484#ifdef EINTR
485  case ROAR_ERROR_INTERRUPTED:
486    errno = EINTR;
487   break;
488#endif
489#ifdef EDQUOT
490  case ROAR_ERROR_QUOTA:
491    errno = EDQUOT;
492   break;
493#endif
494#ifdef ELIBBAD
495  case ROAR_ERROR_BADLIB:
496    errno = ELIBBAD;
497   break;
498#endif
499#ifdef ENOMEDIUM
500  case ROAR_ERROR_NOMEDIUM:
501    errno = ENOMEDIUM;
502   break;
503#endif
504#ifdef ENOTUNIQ
505  case ROAR_ERROR_NOTUNIQ:
506    errno = ENOTUNIQ;
507   break;
508#endif
509#ifdef EILSEQ
510  case ROAR_ERROR_ILLSEQ:
511    errno = EILSEQ;
512   break;
513#endif
514#ifdef EADDRINUSE
515  case ROAR_ERROR_ADDRINUSE:
516    errno = EADDRINUSE;
517   break;
518#endif
519#ifdef ESPIPE
520  case ROAR_ERROR_BADSEEK:
521  case ROAR_ERROR_NOSEEK:
522    errno = ESPIPE;
523   break;
524#endif
525  default:
526#ifdef EINVAL
527    errno = EINVAL;
528#else
529    errno = -1; // just guess
530#endif
531   break;
532 }
533}
534
535// phi@ph7:roaraudio $ grep '^#define ROAR_ERROR_' error.h  | tr -d /\* | while read d c d t; do printf "  {%-23s \"%s\"},\n" $c, "$t"; done
536
537const char * roar_error2str(const int error) {
538 const struct {
539  const int    err;
540  const char * msg;
541 } msgs[] = {
542  {ROAR_ERROR_NONE,        "No error"},
543  {ROAR_ERROR_PERM,        "Operation not permitted"},
544  {ROAR_ERROR_NOENT,       "No such object, file or directory"},
545  {ROAR_ERROR_BADMSG,      "Bad message"},
546  {ROAR_ERROR_BUSY,        "Device or resource busy"},
547  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
548  {ROAR_ERROR_NOSYS,       "Function not implemented"},
549  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
550  {ROAR_ERROR_PIPE,        "Broken pipe"},
551  {ROAR_ERROR_PROTO,       "Protocol error"},
552  {ROAR_ERROR_RANGE,       "Result too large or parameter out of range"},
553  {ROAR_ERROR_MSGSIZE,     "Message too long"},
554  {ROAR_ERROR_NOMEM,       "Not enough space"},
555  {ROAR_ERROR_INVAL,       "Invalid argument"},
556  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
557  {ROAR_ERROR_BADRQC,      "Invalid request code"},
558  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
559  {ROAR_ERROR_EXIST,       "File or object exists"},
560  {ROAR_ERROR_FAULT,       "Bad address"},
561  {ROAR_ERROR_IO,          "I/O-Error"},
562  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
563  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
564  {ROAR_ERROR_LOOP,        "Too many recursions"},
565  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
566  {ROAR_ERROR_NAMETOOLONG, "File or object name too long"},
567  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
568  {ROAR_ERROR_NODEV,       "No such device"},
569  {ROAR_ERROR_NODRV,       "No such driver"},
570  {ROAR_ERROR_NOSPC,       "No space left on device"},
571  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
572  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
573  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
574  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
575  {ROAR_ERROR_RIO,         "Remote I/O Error"},
576  {ROAR_ERROR_RO,          "File or object is read only"},
577  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
578  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
579  {ROAR_ERROR_NOISE,       "Line too noisy"},
580  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
581  {ROAR_ERROR_INTERRUPTED, "Operation was interruped"},
582  {ROAR_ERROR_CAUSALITY,   "Causality error"},
583  {ROAR_ERROR_QUOTA,       "Quota exceeded"},
584  {ROAR_ERROR_BADLIB,      "Accessing a corrupted shared library"},
585  {ROAR_ERROR_NOMEDIUM,    "No medium found"},
586  {ROAR_ERROR_NOTUNIQ,     "Name not unique"},
587  {ROAR_ERROR_ILLSEQ,      "Illegal byte sequence"},
588  {ROAR_ERROR_ADDRINUSE,   "Address in use"},
589  {ROAR_ERROR_HOLE,        "Hole in data"},
590  {ROAR_ERROR_BADVERSION,  "Bad version"},
591  {ROAR_ERROR_NSVERSION,   "Not supported version"},
592  {ROAR_ERROR_BADMAGIC,    "Bad magic number"},
593  {ROAR_ERROR_LOSTSYNC,    "Lost synchronization"},
594  {ROAR_ERROR_BADSEEK,     "Can not seek to destination position"},
595  {ROAR_ERROR_NOSEEK,      "Seeking not supported on resource"},
596  {ROAR_ERROR_BADCKSUM,    "Data integrity error"},
597  {ROAR_ERROR_NOHORSE,     "Mount failed"},
598  {ROAR_ERROR_CHERNOBYL,   "Fatal device error"},
599  {ROAR_ERROR_NOHUG,       "Device needs love"},
600  {-1, NULL}
601 };
602 int i;
603
604 for (i = 0; msgs[i].msg != NULL; i++)
605  if ( msgs[i].err == error )
606   return msgs[i].msg;
607
608 return NULL;
609}
610
611//ll
Note: See TracBrowser for help on using the repository browser.