source: roaraudio/libroar/error.c @ 5040:303d9420b21e

Last change on this file since 5040:303d9420b21e was 5040:303d9420b21e, checked in by phi, 13 years ago

test and support ECHERNOBYL, ECRAY, ENOHORSE

File size: 15.2 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#ifdef ECHERNOBYL
282  case ECHERNOBYL:   _roar_errno = ROAR_ERROR_CHERNOBYL; break;
283#endif
284#ifdef ECRAY
285  case ECRAY:        _roar_errno = ROAR_ERROR_CAUSALITY; break;
286#endif
287#ifdef ENOHORSE
288  case ENOHORSE:     _roar_errno = ROAR_ERROR_NOHORSE; break;
289#endif
290  default:
291    _roar_errno = ROAR_ERROR_UNKNOWN;
292   break;
293 }
294
295 roar_err_set(_roar_errno);
296}
297
298void   roar_err_to_errno(void) {
299 int * err = roar_errno2();
300 switch (*err) {
301  case ROAR_ERROR_NONE:
302    roar_err_clear_errno();
303   break;
304#ifdef EPERM
305  case ROAR_ERROR_PERM:
306    errno = EPERM;
307   break;
308#endif
309#ifdef ENOENT
310  case ROAR_ERROR_NOENT:
311    errno = ENOENT;
312   break;
313#endif
314#ifdef EBADMSG
315  case ROAR_ERROR_BADMSG:
316    errno = EBADMSG;
317   break;
318#endif
319#ifdef EBUSY
320  case ROAR_ERROR_BUSY:
321    errno = EBUSY;
322   break;
323#endif
324#ifdef ECONNREFUSED
325  case ROAR_ERROR_CONNREFUSED:
326    errno = ECONNREFUSED;
327   break;
328#endif
329#ifdef ENOSYS
330  case ROAR_ERROR_NOSYS:
331    errno = ENOSYS;
332   break;
333#endif
334#ifdef ENOTSUP
335  case ROAR_ERROR_NOTSUP:
336    errno = ENOTSUP;
337   break;
338#endif
339#ifdef EPIPE
340  case ROAR_ERROR_PIPE:
341    errno = EPIPE;
342   break;
343#endif
344#ifdef EPROTO
345  case ROAR_ERROR_PROTO:
346    errno = EPROTO;
347   break;
348#endif
349#ifdef ERANGE
350  case ROAR_ERROR_RANGE:
351    errno = ERANGE;
352   break;
353#endif
354#ifdef EMSGSIZE
355  case ROAR_ERROR_MSGSIZE:
356    errno = EMSGSIZE;
357   break;
358#endif
359#ifdef ENOMEM
360  case ROAR_ERROR_NOMEM:
361    errno = ENOMEM;
362   break;
363#endif
364#ifdef EINVAL
365  case ROAR_ERROR_INVAL:
366    errno = EINVAL;
367   break;
368#endif
369#ifdef EALREADY
370  case ROAR_ERROR_ALREADY:
371    errno = EALREADY;
372   break;
373#endif
374#ifdef EBADRQC
375  case ROAR_ERROR_BADRQC:
376    errno = EBADRQC;
377   break;
378#endif
379#ifdef EDOM
380  case ROAR_ERROR_DOM:
381    errno = EDOM;
382   break;
383#endif
384#ifdef EEXIST
385  case ROAR_ERROR_EXIST:
386    errno = EEXIST;
387   break;
388#endif
389#ifdef EFAULT
390  case ROAR_ERROR_FAULT:
391    errno = EFAULT;
392   break;
393#endif
394#if defined(EREMOTEIO) || defined(EIO)
395  case ROAR_ERROR_RIO:
396#ifdef EREMOTEIO
397    errno = EREMOTEIO;
398#else
399    errno = EIO;
400#endif
401   break;
402#endif
403#ifdef EIO
404  case ROAR_ERROR_IO:
405  case ROAR_ERROR_HOLE:
406  case ROAR_ERROR_BADCKSUM:
407  case ROAR_ERROR_LOSTSYNC:
408  case ROAR_ERROR_NOHORSE:
409    errno = EIO;
410   break;
411#endif
412#ifdef EKEYEXPIRED
413  case ROAR_ERROR_KEYEXPIRED:
414    errno = EKEYEXPIRED;
415   break;
416#endif
417#ifdef EKEYREJECTED
418  case ROAR_ERROR_KEYREJECTED:
419    errno = EKEYREJECTED;
420   break;
421#endif
422#ifdef ELOOP
423  case ROAR_ERROR_LOOP:
424    errno = ELOOP;
425   break;
426#endif
427#ifdef EMFILE
428  case ROAR_ERROR_MFILE:
429    errno = EMFILE;
430   break;
431#endif
432#ifdef ENAMETOOLONG
433  case ROAR_ERROR_NAMETOOLONG:
434    errno = ENAMETOOLONG;
435   break;
436#endif
437#ifdef ENODATA
438  case ROAR_ERROR_NODATA:
439    errno = ENODATA;
440   break;
441#endif
442#ifdef ENODEV
443  case ROAR_ERROR_NODEV:
444  case ROAR_ERROR_NODRV:
445    errno = ENODEV;
446   break;
447#endif
448#ifdef ENOSPC
449  case ROAR_ERROR_NOSPC:
450    errno = ENOSPC;
451   break;
452#endif
453#ifdef EINVAL
454  case ROAR_ERROR_TYPEMM:
455    errno = EINVAL;
456   break;
457#endif
458#ifdef ENOSYS
459  case ROAR_ERROR_NORSYS:
460    errno = ENOSYS;
461   break;
462#endif
463#ifdef ENOTCONN
464  case ROAR_ERROR_NOTCONN:
465    errno = ENOTCONN;
466   break;
467#endif
468#ifdef EPROTONOSUPPORT
469  case ROAR_ERROR_PROTONOSUP:
470    errno = EPROTONOSUPPORT;
471   break;
472#endif
473#ifdef EROFS
474  case ROAR_ERROR_RO:
475    errno = EROFS;
476   break;
477#endif
478#ifdef ETIMEDOUT
479  case ROAR_ERROR_TIMEDOUT:
480    errno = ETIMEDOUT;
481   break;
482#endif
483#ifdef EAGAIN
484  case ROAR_ERROR_AGAIN:
485    errno = EAGAIN;
486   break;
487#endif
488#ifdef ENETDOWN
489  case ROAR_ERROR_LINKDOWN:
490    errno = ENETDOWN;
491   break;
492#endif
493#ifdef EINTR
494  case ROAR_ERROR_INTERRUPTED:
495    errno = EINTR;
496   break;
497#endif
498#ifdef EDQUOT
499  case ROAR_ERROR_QUOTA:
500    errno = EDQUOT;
501   break;
502#endif
503#ifdef ELIBBAD
504  case ROAR_ERROR_BADLIB:
505    errno = ELIBBAD;
506   break;
507#endif
508#ifdef ENOMEDIUM
509  case ROAR_ERROR_NOMEDIUM:
510    errno = ENOMEDIUM;
511   break;
512#endif
513#ifdef ENOTUNIQ
514  case ROAR_ERROR_NOTUNIQ:
515    errno = ENOTUNIQ;
516   break;
517#endif
518#ifdef EILSEQ
519  case ROAR_ERROR_ILLSEQ:
520    errno = EILSEQ;
521   break;
522#endif
523#ifdef EADDRINUSE
524  case ROAR_ERROR_ADDRINUSE:
525    errno = EADDRINUSE;
526   break;
527#endif
528#ifdef ESPIPE
529  case ROAR_ERROR_BADSEEK:
530  case ROAR_ERROR_NOSEEK:
531    errno = ESPIPE;
532   break;
533#endif
534#ifdef ECHERNOBYL
535  case ROAR_ERROR_CHERNOBYL:
536    errno = ECHERNOBYL;
537   break;
538#endif
539#ifdef ECRAY
540  case ROAR_ERROR_CAUSALITY:
541    errno = ECRAY;
542   break;
543#endif
544#ifdef ENOHORSE
545  case ROAR_ERROR_NOHORSE:
546    errno = ENOHORSE;
547   break;
548#endif
549
550  default:
551#ifdef EINVAL
552    errno = EINVAL;
553#else
554    errno = -1; // just guess
555#endif
556   break;
557 }
558}
559
560// 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
561
562const char * roar_error2str(const int error) {
563 const struct {
564  const int    err;
565  const char * msg;
566 } msgs[] = {
567  {ROAR_ERROR_NONE,        "No error"},
568  {ROAR_ERROR_PERM,        "Operation not permitted"},
569  {ROAR_ERROR_NOENT,       "No such object, file or directory"},
570  {ROAR_ERROR_BADMSG,      "Bad message"},
571  {ROAR_ERROR_BUSY,        "Device or resource busy"},
572  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
573  {ROAR_ERROR_NOSYS,       "Function not implemented"},
574  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
575  {ROAR_ERROR_PIPE,        "Broken pipe"},
576  {ROAR_ERROR_PROTO,       "Protocol error"},
577  {ROAR_ERROR_RANGE,       "Result too large or parameter out of range"},
578  {ROAR_ERROR_MSGSIZE,     "Message too long"},
579  {ROAR_ERROR_NOMEM,       "Not enough space"},
580  {ROAR_ERROR_INVAL,       "Invalid argument"},
581  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
582  {ROAR_ERROR_BADRQC,      "Invalid request code"},
583  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
584  {ROAR_ERROR_EXIST,       "File or object exists"},
585  {ROAR_ERROR_FAULT,       "Bad address"},
586  {ROAR_ERROR_IO,          "I/O-Error"},
587  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
588  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
589  {ROAR_ERROR_LOOP,        "Too many recursions"},
590  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
591  {ROAR_ERROR_NAMETOOLONG, "File or object name too long"},
592  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
593  {ROAR_ERROR_NODEV,       "No such device"},
594  {ROAR_ERROR_NODRV,       "No such driver"},
595  {ROAR_ERROR_NOSPC,       "No space left on device"},
596  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
597  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
598  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
599  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
600  {ROAR_ERROR_RIO,         "Remote I/O Error"},
601  {ROAR_ERROR_RO,          "File or object is read only"},
602  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
603  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
604  {ROAR_ERROR_NOISE,       "Line too noisy"},
605  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
606  {ROAR_ERROR_INTERRUPTED, "Operation was interruped"},
607  {ROAR_ERROR_CAUSALITY,   "Causality error"},
608  {ROAR_ERROR_QUOTA,       "Quota exceeded"},
609  {ROAR_ERROR_BADLIB,      "Accessing a corrupted shared library"},
610  {ROAR_ERROR_NOMEDIUM,    "No medium found"},
611  {ROAR_ERROR_NOTUNIQ,     "Name not unique"},
612  {ROAR_ERROR_ILLSEQ,      "Illegal byte sequence"},
613  {ROAR_ERROR_ADDRINUSE,   "Address in use"},
614  {ROAR_ERROR_HOLE,        "Hole in data"},
615  {ROAR_ERROR_BADVERSION,  "Bad version"},
616  {ROAR_ERROR_NSVERSION,   "Not supported version"},
617  {ROAR_ERROR_BADMAGIC,    "Bad magic number"},
618  {ROAR_ERROR_LOSTSYNC,    "Lost synchronization"},
619  {ROAR_ERROR_BADSEEK,     "Can not seek to destination position"},
620  {ROAR_ERROR_NOSEEK,      "Seeking not supported on resource"},
621  {ROAR_ERROR_BADCKSUM,    "Data integrity error"},
622  {ROAR_ERROR_NOHORSE,     "Mount failed"},
623  {ROAR_ERROR_CHERNOBYL,   "Fatal device error"},
624  {ROAR_ERROR_NOHUG,       "Device needs love"},
625  {-1, NULL}
626 };
627 int i;
628
629 for (i = 0; msgs[i].msg != NULL; i++)
630  if ( msgs[i].err == error )
631   return msgs[i].msg;
632
633 return NULL;
634}
635
636//ll
Note: See TracBrowser for help on using the repository browser.