source: roaraudio/libroar/error.c @ 5554:974f701cf7b5

Last change on this file since 5554:974f701cf7b5 was 5554:974f701cf7b5, checked in by phi, 7 years ago

support to convert EAI_* error codes (Closes: #255)

File size: 44.5 KB
Line 
1//error.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2012
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
45static int roar_errno = ROAR_ERROR_NONE;
46
47struct roar_error_frame * roar_err_errorframe(void) {
48 static struct roar_error_frame frame = {
49  .version     =  0,
50  .cmd         = -1,
51  .ra_errno    = ROAR_ERROR_UNKNOWN,
52  .ra_suberrno = -1,
53  .p_errno     = -1,
54  .flags       =  0,
55  .datalen     =  0,
56  .data        = NULL
57 };
58
59 return &frame;
60}
61
62int    roar_err_init(struct roar_error_frame * frame) {
63 if ( frame == NULL ) {
64  roar_err_set(ROAR_ERROR_FAULT);
65  return -1;
66 }
67
68 memset(frame, 0, sizeof(struct roar_error_frame));
69
70 frame->cmd         = -1;
71 frame->ra_errno    = ROAR_ERROR_UNKNOWN;
72 frame->ra_suberrno = -1;
73 frame->p_errno     = -1;
74 frame->datalen     =  0;
75 frame->data        = NULL;
76
77 return 0;
78}
79
80
81void * roar_err_buildmsg(struct roar_message * mes, void ** data, struct roar_error_frame * frame) {
82 char * databuf = NULL;
83 int16_t * d;
84 size_t datalen;
85
86 if ( mes == NULL || frame == NULL ) {
87  roar_err_set(ROAR_ERROR_FAULT);
88  return NULL;
89 }
90
91 if ( data != NULL )
92  *data = NULL;
93
94 datalen = 8 + frame->datalen;
95 if ( datalen > LIBROAR_BUFFER_MSGDATA ) {
96  if ( data == NULL ) {
97   roar_err_set(ROAR_ERROR_FAULT);
98   return NULL;
99  }
100
101  roar_err_clear_errno();
102  *data = roar_mm_malloc(datalen);
103  roar_err_from_errno();
104  if ( *data == NULL )
105   return NULL;
106
107  databuf = *data;
108 } else {
109  databuf = mes->data;
110 }
111
112 memset(mes,  0, sizeof(struct roar_message));
113 memset(databuf, 0, mes->datalen);
114
115 mes->datalen = datalen;
116
117 d = (int16_t*)databuf;
118
119 frame->data  = &(databuf[8]);
120
121 databuf[0]    = 0; // version.
122 databuf[1]    = frame->cmd;
123 databuf[2]    = frame->ra_errno;
124 databuf[3]    = frame->ra_suberrno;
125 d[2]            = ROAR_HOST2NET16(frame->p_errno);
126 d[3]            = ROAR_HOST2NET16(frame->flags);
127
128 return frame->data;
129}
130
131int    roar_err_parsemsg(struct roar_message * mes, void *  data, struct roar_error_frame * frame) {
132 char * databuf = (char *)data;
133 int16_t * d;
134
135 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
136          mes, (int)mes->datalen, mes->data, data, frame);
137
138 if ( mes == NULL || frame == NULL ) {
139  roar_err_set(ROAR_ERROR_FAULT);
140  ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=FAULT",
141           mes, (int)mes->datalen, mes->data, data, frame);
142  return -1;
143 }
144
145 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
146          mes, (int)mes->datalen, mes->data, data, frame);
147
148 if ( databuf == NULL )
149  databuf = mes->data;
150
151 d = (int16_t*)databuf;
152
153 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
154          mes, (int)mes->datalen, mes->data, data, frame);
155
156 if ( mes->datalen < 8 ) {
157  roar_err_set(ROAR_ERROR_MSGSIZE);
158  ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=MSGSIZE",
159           mes, (int)mes->datalen, mes->data, data, frame);
160  return -1;
161 }
162
163 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
164          mes, (int)mes->datalen, mes->data, data, frame);
165
166 if ( databuf[0] != 0 ) {
167  roar_err_set(ROAR_ERROR_NSVERSION);
168  ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=NSVERSION",
169           mes, (int)mes->datalen, mes->data, data, frame);
170  return -1;
171 }
172
173 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?",
174          mes, (int)mes->datalen, mes->data, data, frame);
175
176 frame->cmd         = databuf[1];
177 frame->ra_errno    = databuf[2];
178 frame->ra_suberrno = databuf[3];
179 frame->p_errno     = ROAR_NET2HOST16(d[2]);
180 frame->flags       = ROAR_NET2HOST16(d[3]);
181
182 frame->datalen     = mes->datalen - 8;
183 frame->data        = &(databuf[8]);
184
185 ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = 0",
186          mes, (int)mes->datalen, mes->data, data, frame);
187 return 0;
188}
189
190#define roar_errno2_impl (&roar_errno)
191int *  roar_errno2(void) {
192 return roar_errno2_impl;
193}
194
195void   roar_err_clear(void) {
196 *roar_errno2_impl = ROAR_ERROR_NONE;
197}
198
199void   roar_err_clear_errno(void) {
200 errno = CLEAN_ERRNO;
201}
202
203void   roar_err_clear_all(void) {
204 roar_err_clear();
205 roar_err_clear_errno();
206}
207
208void   roar_err_update(void) {
209 int * err = roar_errno2_impl;
210
211 // NOTE: _NEVER_ call ROAR_{DBG,INFO,WARN,ERR}() in here! (will result in endless loop)
212 //printf("*err=%i, errno=%i\n", *err, (int)errno);
213
214 if ( *err != ROAR_ERROR_NONE ) {
215  roar_err_to_errno();
216 } else if ( !roar_err_is_errno_clear() ) {
217  roar_err_from_errno();
218#ifdef ROAR_TARGET_WIN32
219 } else {
220  roar_err_convert(err, ROAR_ERROR_TYPE_ROARAUDIO, WSAGetLastError(), ROAR_ERROR_TYPE_WINSOCK);
221  roar_err_to_errno();
222#endif
223 }
224}
225
226int    roar_err_is_errno_clear(void) {
227 return errno == CLEAN_ERRNO ? 1 : 0;
228}
229
230void   roar_err_set(const int error) {
231 *roar_errno2_impl = error;
232}
233
234static int   __errno_to_roar(int error) {
235 int _roar_errno = ROAR_ERROR_NONE;
236
237 switch (error) {
238#ifdef EACCES
239  case EACCES:       _roar_errno = ROAR_ERROR_PERM; break;
240#endif
241#ifdef EPERM
242  case EPERM:        _roar_errno = ROAR_ERROR_PERM; break;
243#endif
244#ifdef ENOENT
245  case ENOENT:       _roar_errno = ROAR_ERROR_NOENT; break;
246#endif
247#ifdef EBADMSG
248  case EBADMSG:      _roar_errno = ROAR_ERROR_BADMSG; break;
249#endif
250#ifdef EBUSY
251  case EBUSY:        _roar_errno = ROAR_ERROR_BUSY; break;
252#endif
253#ifdef ECONNREFUSED
254  case ECONNREFUSED: _roar_errno = ROAR_ERROR_CONNREFUSED; break;
255#endif
256#ifdef ENOSYS
257  case ENOSYS:       _roar_errno = ROAR_ERROR_NOSYS; break;
258#endif
259#ifdef ENOTSUP
260  case ENOTSUP:      _roar_errno = ROAR_ERROR_NOTSUP; break;
261#endif
262#ifdef EPIPE
263  case EPIPE:        _roar_errno = ROAR_ERROR_PIPE; break;
264#endif
265#ifdef EPROTO
266  case EPROTO:       _roar_errno = ROAR_ERROR_PROTO; break;
267#endif
268#ifdef ERANGE
269  case ERANGE:       _roar_errno = ROAR_ERROR_RANGE; break;
270#endif
271#ifdef EMSGSIZE
272  case EMSGSIZE:     _roar_errno = ROAR_ERROR_MSGSIZE; break;
273#endif
274#ifdef ENOMEM
275  case ENOMEM:       _roar_errno = ROAR_ERROR_NOMEM; break;
276#endif
277#ifdef EINVAL
278  case EINVAL:       _roar_errno = ROAR_ERROR_INVAL; break;
279#endif
280#ifdef EALREADY
281  case EALREADY:     _roar_errno = ROAR_ERROR_ALREADY; break;
282#endif
283#ifdef EBADRQC
284  case EBADRQC:      _roar_errno = ROAR_ERROR_BADRQC; break;
285#endif
286#ifdef EDOM
287  case EDOM:         _roar_errno = ROAR_ERROR_DOM; break;
288#endif
289#ifdef EEXIST
290  case EEXIST:       _roar_errno = ROAR_ERROR_EXIST; break;
291#endif
292#ifdef EFAULT
293  case EFAULT:       _roar_errno = ROAR_ERROR_FAULT; break;
294#endif
295#ifdef EIO
296  case EIO:          _roar_errno = ROAR_ERROR_IO; break;
297#endif
298#ifdef EREMOTEIO
299  case EREMOTEIO:    _roar_errno = ROAR_ERROR_RIO; break;
300#endif
301#ifdef EKEYEXPIRED
302  case EKEYEXPIRED:  _roar_errno = ROAR_ERROR_KEYEXPIRED; break;
303#endif
304#ifdef EKEYREJECTED
305  case EKEYREJECTED: _roar_errno = ROAR_ERROR_KEYREJECTED; break;
306#endif
307#ifdef ELOOP
308  case ELOOP:        _roar_errno = ROAR_ERROR_LOOP; break;
309#endif
310#ifdef EMFILE
311  case EMFILE:       _roar_errno = ROAR_ERROR_MFILE; break;
312#endif
313#ifdef ENAMETOOLONG
314  case ENAMETOOLONG: _roar_errno = ROAR_ERROR_NAMETOOLONG; break;
315#endif
316#ifdef ENODATA
317  case ENODATA:      _roar_errno = ROAR_ERROR_NODATA; break;
318#endif
319#ifdef ENODEV
320  case ENODEV:       _roar_errno = ROAR_ERROR_NODEV; break;
321#endif
322#ifdef ENOSPC
323  case ENOSPC:       _roar_errno = ROAR_ERROR_NOSPC; break;
324#endif
325#ifdef ENOTCONN
326  case ENOTCONN:     _roar_errno = ROAR_ERROR_NOTCONN; break;
327#endif
328#ifdef EPROTONOSUPPORT
329  case EPROTONOSUPPORT: _roar_errno = ROAR_ERROR_PROTONOSUP; break;
330#endif
331#ifdef EROFS
332  case EROFS:        _roar_errno = ROAR_ERROR_RO; break;
333#endif
334#ifdef ETIMEDOUT
335  case ETIMEDOUT:    _roar_errno = ROAR_ERROR_TIMEDOUT; break;
336#endif
337#ifdef EAGAIN
338  case EAGAIN:       _roar_errno = ROAR_ERROR_AGAIN; break;
339#endif
340#ifdef ENETDOWN
341  case ENETDOWN:     _roar_errno = ROAR_ERROR_LINKDOWN; break;
342#endif
343#ifdef EINTR
344  case EINTR:        _roar_errno = ROAR_ERROR_INTERRUPTED; break;
345#endif
346#ifdef EDQUOT
347  case EDQUOT:       _roar_errno = ROAR_ERROR_QUOTA; break;
348#endif
349#ifdef ELIBBAD
350  case ELIBBAD:      _roar_errno = ROAR_ERROR_BADLIB; break;
351#endif
352#ifdef ENOMEDIUM
353  case ENOMEDIUM:    _roar_errno = ROAR_ERROR_NOMEDIUM; break;
354#endif
355#ifdef ENOTUNIQ
356  case ENOTUNIQ:     _roar_errno = ROAR_ERROR_NOTUNIQ; break;
357#endif
358#ifdef EILSEQ
359  case EILSEQ:       _roar_errno = ROAR_ERROR_ILLSEQ; break;
360#endif
361#ifdef EADDRINUSE
362  case EADDRINUSE:   _roar_errno = ROAR_ERROR_ADDRINUSE; break;
363#endif
364#ifdef ESPIPE
365  case ESPIPE:       _roar_errno = ROAR_ERROR_BADSEEK; break;
366#endif
367#ifdef ECHERNOBYL
368  case ECHERNOBYL:   _roar_errno = ROAR_ERROR_CHERNOBYL; break;
369#endif
370#ifdef ECRAY
371  case ECRAY:        _roar_errno = ROAR_ERROR_CAUSALITY; break;
372#endif
373#ifdef ENOHORSE
374  case ENOHORSE:     _roar_errno = ROAR_ERROR_NOHORSE; break;
375#endif
376#ifdef ETXTBSY
377  case ETXTBSY:      _roar_errno = ROAR_ERROR_TEXTBUSY; break;
378#endif
379#ifdef ENOTEMPTY
380  case ENOTEMPTY:    _roar_errno = ROAR_ERROR_NOTEMPTY; break;
381#endif
382#ifdef EHOSTUNREACH
383  case EHOSTUNREACH: _roar_errno = ROAR_ERROR_NODEUNREACH; break;
384#endif
385#ifdef EIDRM
386  case EIDRM:        _roar_errno = ROAR_ERROR_IDREMOVED; break;
387#endif
388#ifdef EINPROGRESS
389  case EINPROGRESS:  _roar_errno = ROAR_ERROR_INPROGRESS; break;
390#endif
391#ifdef ECHILD
392  case ECHILD:       _roar_errno = ROAR_ERROR_NOCHILD; break;
393#endif
394#ifdef ENETUNREACH
395  case ENETUNREACH:  _roar_errno = ROAR_ERROR_NETUNREACH; break;
396#endif
397#ifdef ECANCELED
398  case ECANCELED:    _roar_errno = ROAR_ERROR_CANCELED; break;
399#endif
400#ifdef EISDIR
401  case EISDIR:       _roar_errno = ROAR_ERROR_ISDIR; break;
402#endif
403#ifdef ENOTDIR
404  case ENOTDIR:      _roar_errno = ROAR_ERROR_NOTDIR; break;
405#endif
406#ifdef ENOEXEC
407  case ENOEXEC:      _roar_errno = ROAR_ERROR_BADEXEC; break;
408#endif
409#ifdef EISCONN
410  case EISCONN:      _roar_errno = ROAR_ERROR_ISCONN; break;
411#endif
412#ifdef EDEADLK
413  case EDEADLK:      _roar_errno = ROAR_ERROR_DEADLOCK; break;
414#endif
415#ifdef ECONNRESET
416  case ECONNRESET:   _roar_errno = ROAR_ERROR_CONNRST; break;
417#endif
418#ifdef EBADF
419  case EBADF:        _roar_errno = ROAR_ERROR_BADFH; break;
420#endif
421#ifdef ENOTSOCK
422  case ENOTSOCK:     _roar_errno = ROAR_ERROR_NOTSOCK; break;
423#endif
424#ifdef E2BIG
425  case E2BIG:        _roar_errno = ROAR_ERROR_TOOMANYARGS; break;
426#endif
427#ifdef EFBIG
428  case EFBIG:        _roar_errno = ROAR_ERROR_TOOLARGE; break;
429#endif
430#ifdef EDESTADDRREQ
431  case EDESTADDRREQ: _roar_errno = ROAR_ERROR_DESTADDRREQ; break;
432#endif
433#ifdef EAFNOSUPPORT
434  case EAFNOSUPPORT: _roar_errno = ROAR_ERROR_AFNOTSUP; break;
435#endif
436#ifdef ENFILE
437  case ENFILE:       _roar_errno = ROAR_ERROR_NFILE; break;
438#endif
439#ifdef ESTALE
440  case ESTALE:       _roar_errno = ROAR_ERROR_STALE; break;
441#endif
442#ifdef EXDEV
443  case EXDEV:        _roar_errno = ROAR_ERROR_XDEVLINK; break;
444#endif
445#ifdef EMLINK
446  case EMLINK:       _roar_errno = ROAR_ERROR_MLINK; break;
447#endif
448#ifdef ENONET
449  case ENONET:       _roar_errno = ROAR_ERROR_NONET; break;
450#endif
451#ifdef ENETRESET
452  case ENETRESET:    _roar_errno = ROAR_ERROR_CONNRSTNET; break;
453#endif
454#ifdef ECONNABORTED
455  case ECONNABORTED: _roar_errno = ROAR_ERROR_CONNABORTED; break;
456#endif
457  default:
458    _roar_errno = ROAR_ERROR_UNKNOWN;
459   break;
460 }
461
462 return _roar_errno;
463}
464
465void   roar_err_from_errno(void) {
466 roar_err_set(__errno_to_roar(errno));
467}
468
469static int   __roar_to_errno(int error) {
470 switch (error) {
471  case ROAR_ERROR_NONE:
472    return CLEAN_ERRNO;
473   break;
474#ifdef EPERM
475  case ROAR_ERROR_PERM:
476    return EPERM;
477   break;
478#endif
479#ifdef ENOENT
480  case ROAR_ERROR_NOENT:
481    return ENOENT;
482   break;
483#endif
484#ifdef EBADMSG
485  case ROAR_ERROR_BADMSG:
486    return EBADMSG;
487   break;
488#endif
489#ifdef EBUSY
490  case ROAR_ERROR_BUSY:
491    return EBUSY;
492   break;
493#endif
494#ifdef ECONNREFUSED
495  case ROAR_ERROR_CONNREFUSED:
496    return ECONNREFUSED;
497   break;
498#endif
499#ifdef ENOSYS
500  case ROAR_ERROR_NOSYS:
501    return ENOSYS;
502   break;
503#endif
504#ifdef ENOTSUP
505  case ROAR_ERROR_NOTSUP:
506    return ENOTSUP;
507   break;
508#endif
509#ifdef EPIPE
510  case ROAR_ERROR_PIPE:
511    return EPIPE;
512   break;
513#endif
514#ifdef EPROTO
515  case ROAR_ERROR_PROTO:
516    return EPROTO;
517   break;
518#endif
519#ifdef ERANGE
520  case ROAR_ERROR_RANGE:
521    return ERANGE;
522   break;
523#endif
524#ifdef EMSGSIZE
525  case ROAR_ERROR_MSGSIZE:
526    return EMSGSIZE;
527   break;
528#endif
529#ifdef ENOMEM
530  case ROAR_ERROR_NOMEM:
531    return ENOMEM;
532   break;
533#endif
534#ifdef EINVAL
535  case ROAR_ERROR_INVAL:
536    return EINVAL;
537   break;
538#endif
539#ifdef EALREADY
540  case ROAR_ERROR_ALREADY:
541    return EALREADY;
542   break;
543#endif
544#ifdef EBADRQC
545  case ROAR_ERROR_BADRQC:
546    return EBADRQC;
547   break;
548#endif
549#ifdef EDOM
550  case ROAR_ERROR_DOM:
551    return EDOM;
552   break;
553#endif
554#ifdef EEXIST
555  case ROAR_ERROR_EXIST:
556    return EEXIST;
557   break;
558#endif
559#ifdef EFAULT
560  case ROAR_ERROR_FAULT:
561    return EFAULT;
562   break;
563#endif
564#if defined(EREMOTEIO) || defined(EIO)
565  case ROAR_ERROR_RIO:
566#ifdef EREMOTEIO
567    return EREMOTEIO;
568#else
569    return EIO;
570#endif
571   break;
572#endif
573#ifdef EIO
574  case ROAR_ERROR_IO:
575  case ROAR_ERROR_HOLE:
576  case ROAR_ERROR_BADCKSUM:
577  case ROAR_ERROR_LOSTSYNC:
578  case ROAR_ERROR_NOHORSE:
579    return EIO;
580   break;
581#endif
582#ifdef EKEYEXPIRED
583  case ROAR_ERROR_KEYEXPIRED:
584    return EKEYEXPIRED;
585   break;
586#endif
587#ifdef EKEYREJECTED
588  case ROAR_ERROR_KEYREJECTED:
589    return EKEYREJECTED;
590   break;
591#endif
592#ifdef ELOOP
593  case ROAR_ERROR_LOOP:
594    return ELOOP;
595   break;
596#endif
597#ifdef EMFILE
598  case ROAR_ERROR_MFILE:
599    return EMFILE;
600   break;
601#endif
602#ifdef ENAMETOOLONG
603  case ROAR_ERROR_NAMETOOLONG:
604    return ENAMETOOLONG;
605   break;
606#endif
607#ifdef ENODATA
608  case ROAR_ERROR_NODATA:
609    return ENODATA;
610   break;
611#endif
612#ifdef ENODEV
613  case ROAR_ERROR_NODEV:
614  case ROAR_ERROR_NODRV:
615    return ENODEV;
616   break;
617#endif
618#ifdef ENOSPC
619  case ROAR_ERROR_NOSPC:
620    return ENOSPC;
621   break;
622#endif
623#ifdef EINVAL
624  case ROAR_ERROR_TYPEMM:
625    return EINVAL;
626   break;
627#endif
628#ifdef ENOSYS
629  case ROAR_ERROR_NORSYS:
630    return ENOSYS;
631   break;
632#endif
633#ifdef ENOTCONN
634  case ROAR_ERROR_NOTCONN:
635    return ENOTCONN;
636   break;
637#endif
638#ifdef EPROTONOSUPPORT
639  case ROAR_ERROR_PROTONOSUP:
640    return EPROTONOSUPPORT;
641   break;
642#endif
643#ifdef EROFS
644  case ROAR_ERROR_RO:
645    return EROFS;
646   break;
647#endif
648#ifdef ETIMEDOUT
649  case ROAR_ERROR_TIMEDOUT:
650    return ETIMEDOUT;
651   break;
652#endif
653#ifdef EAGAIN
654  case ROAR_ERROR_AGAIN:
655    return EAGAIN;
656   break;
657#endif
658#ifdef ENETDOWN
659  case ROAR_ERROR_LINKDOWN:
660    return ENETDOWN;
661   break;
662#endif
663#ifdef EINTR
664  case ROAR_ERROR_INTERRUPTED:
665    return EINTR;
666   break;
667#endif
668#ifdef EDQUOT
669  case ROAR_ERROR_QUOTA:
670    return EDQUOT;
671   break;
672#endif
673#ifdef ELIBBAD
674  case ROAR_ERROR_BADLIB:
675    return ELIBBAD;
676   break;
677#endif
678#ifdef ENOMEDIUM
679  case ROAR_ERROR_NOMEDIUM:
680    return ENOMEDIUM;
681   break;
682#endif
683#ifdef ENOTUNIQ
684  case ROAR_ERROR_NOTUNIQ:
685    return ENOTUNIQ;
686   break;
687#endif
688#ifdef EILSEQ
689  case ROAR_ERROR_ILLSEQ:
690    return EILSEQ;
691   break;
692#endif
693#ifdef EADDRINUSE
694  case ROAR_ERROR_ADDRINUSE:
695    return EADDRINUSE;
696   break;
697#endif
698#ifdef ESPIPE
699  case ROAR_ERROR_BADSEEK:
700  case ROAR_ERROR_NOSEEK:
701    return ESPIPE;
702   break;
703#endif
704#ifdef ECHERNOBYL
705  case ROAR_ERROR_CHERNOBYL:
706    return ECHERNOBYL;
707   break;
708#endif
709#ifdef ECRAY
710  case ROAR_ERROR_CAUSALITY:
711    return ECRAY;
712   break;
713#endif
714#ifdef ENOHORSE
715  case ROAR_ERROR_NOHORSE:
716    return ENOHORSE;
717   break;
718#endif
719#ifdef ETXTBSY
720  case ROAR_ERROR_TEXTBUSY:
721    return ETXTBSY;
722   break;
723#endif
724#ifdef ENOTEMPTY
725  case ROAR_ERROR_NOTEMPTY:
726    return ENOTEMPTY;
727   break;
728#endif
729#ifdef EHOSTUNREACH
730  case ROAR_ERROR_NODEUNREACH:
731    return EHOSTUNREACH;
732   break;
733#endif
734#ifdef EIDRM
735  case ROAR_ERROR_IDREMOVED:
736    return EIDRM;
737   break;
738#endif
739#ifdef EINPROGRESS
740  case ROAR_ERROR_INPROGRESS:
741    return EINPROGRESS;
742   break;
743#endif
744#ifdef ECHILD
745  case ROAR_ERROR_NOCHILD:
746    return ECHILD;
747   break;
748#endif
749#ifdef ENETUNREACH
750  case ROAR_ERROR_NETUNREACH:
751    return ENETUNREACH;
752   break;
753#endif
754#ifdef ECANCELED
755  case ROAR_ERROR_CANCELED:
756    return ECANCELED;
757   break;
758#endif
759#ifdef EISDIR
760  case ROAR_ERROR_ISDIR:
761    return EISDIR;
762   break;
763#endif
764#ifdef ENOTDOR
765  case ROAR_ERROR_NOTDIR:
766    return ENOTDIR;
767   break;
768#endif
769#ifdef ENOEXEC
770  case ROAR_ERROR_BADEXEC:
771    return ENOEXEC;
772   break;
773#endif
774#ifdef EISCONN
775  case ROAR_ERROR_ISCONN:
776    return EISCONN;
777   break;
778#endif
779#ifdef EDEADLK
780  case ROAR_ERROR_DEADLOCK:
781    return EDEADLK;
782   break;
783#endif
784#ifdef ECONNRESET
785  case ROAR_ERROR_CONNRST:
786    return ECONNRESET;
787   break;
788#endif
789#ifdef EBADF
790  case ROAR_ERROR_BADFH:
791    return EBADF;
792   break;
793#endif
794#ifdef ENOTSOCK
795  case ROAR_ERROR_NOTSOCK:
796    return ENOTSOCK;
797   break;
798#endif
799#ifdef E2BIG
800  case ROAR_ERROR_TOOMANYARGS:
801    return E2BIG;
802   break;
803#endif
804#ifdef EFBIG
805  case ROAR_ERROR_TOOLARGE:
806    return EFBIG;
807   break;
808#endif
809#ifdef EDESTADDRREQ
810  case ROAR_ERROR_DESTADDRREQ:
811    return EDESTADDRREQ;
812   break;
813#endif
814#ifdef EAFNOSUPPORT
815  case ROAR_ERROR_AFNOTSUP:
816    return EAFNOSUPPORT;
817   break;
818#endif
819// FIXME....
820#ifdef ENOPOWER
821  case ROAR_ERROR_NOPOWER:
822    return ENOPOWER;
823   break;
824#endif
825#ifdef EUSER
826  case ROAR_ERROR_USER:
827    return EUSER;
828   break;
829#endif
830
831#ifdef ENFILE
832  case ROAR_ERROR_NFILE:
833    return ENFILE;
834   break;
835#endif
836#ifdef ESTALE
837  case ROAR_ERROR_STALE:
838    return ESTALE;
839   break;
840#endif
841#ifdef EXDEV
842  case ROAR_ERROR_XDEVLINK:
843    return EXDEV;
844   break;
845#endif
846#ifdef EMLINK
847  case ROAR_ERROR_MLINK:
848    return EMLINK;
849   break;
850#endif
851#ifdef ENONET
852  case ROAR_ERROR_NONET:
853    return ENONET;
854   break;
855#endif
856#ifdef ENETRESET
857  case ROAR_ERROR_CONNRSTNET:
858    return ENETRESET;
859   break;
860#endif
861#ifdef ECONNABORTED
862  case ROAR_ERROR_CONNABORTED:
863    return ECONNABORTED;
864   break;
865#endif
866
867  default:
868#ifdef EINVAL
869    return EINVAL;
870#else
871    return -1; // just guess
872#endif
873   break;
874 }
875}
876
877void   roar_err_to_errno(void) {
878 errno = __roar_to_errno(roar_error);
879}
880
881static const struct error_table_entry {
882 const enum roar_error_type type;
883 const int error;
884 const int roarerror;
885} __libroar_error_table[] = {
886 {ROAR_ERROR_TYPE_HTTP, 200, ROAR_ERROR_NONE},
887 {ROAR_ERROR_TYPE_HTTP, 301, ROAR_ERROR_MOVEDPERM},
888 {ROAR_ERROR_TYPE_HTTP, 303, ROAR_ERROR_SEEOTHER},
889 {ROAR_ERROR_TYPE_HTTP, 305, ROAR_ERROR_USEPROXY},
890 {ROAR_ERROR_TYPE_HTTP, 307, ROAR_ERROR_MOVEDTEMP},
891 {ROAR_ERROR_TYPE_HTTP, 400, ROAR_ERROR_INVAL},
892 {ROAR_ERROR_TYPE_HTTP, 403, ROAR_ERROR_PERM},
893 {ROAR_ERROR_TYPE_HTTP, 404, ROAR_ERROR_NOENT},
894 {ROAR_ERROR_TYPE_HTTP, 408, ROAR_ERROR_TIMEDOUT},
895 {ROAR_ERROR_TYPE_HTTP, 410, ROAR_ERROR_GONE},
896 {ROAR_ERROR_TYPE_HTTP, 423, ROAR_ERROR_BUSY},
897 {ROAR_ERROR_TYPE_HTTP, 426, ROAR_ERROR_SWITCHPROTO},
898 {ROAR_ERROR_TYPE_HTTP, 501, ROAR_ERROR_NOSYS},
899 {ROAR_ERROR_TYPE_HTTP, 504, ROAR_ERROR_TIMEDOUT},
900 {ROAR_ERROR_TYPE_HTTP, 505, ROAR_ERROR_NSVERSION},
901 {ROAR_ERROR_TYPE_HTTP, 507, ROAR_ERROR_NOSPC},
902#ifdef NETDB_SUCCESS
903 {ROAR_ERROR_TYPE_HERROR, NETDB_SUCCESS, ROAR_ERROR_NONE},
904#endif
905#ifdef HOST_NOT_FOUND
906 {ROAR_ERROR_TYPE_HERROR, HOST_NOT_FOUND, ROAR_ERROR_NOENT},
907#endif
908#ifdef TRY_AGAIN
909 {ROAR_ERROR_TYPE_HERROR, TRY_AGAIN, ROAR_ERROR_AGAIN},
910#endif
911#ifdef NO_RECOVERY
912// {ROAR_ERROR_TYPE_HERROR, NO_RECOVERY, ROAR_ERROR_???},
913#endif
914#ifdef NO_DATA
915 {ROAR_ERROR_TYPE_HERROR, NO_DATA, ROAR_ERROR_NODATA},
916#endif
917#ifdef NO_ADDRESS
918 {ROAR_ERROR_TYPE_HERROR, NO_ADDRESS, ROAR_ERROR_NOENT},
919#endif
920#ifdef ROAR_TARGET_WIN32
921 {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_HANDLE, ROAR_ERROR_BADFH},
922 {ROAR_ERROR_TYPE_WINSOCK, WSA_NOT_ENOUGH_MEMORY, ROAR_ERROR_NOMEM},
923 {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_PARAMETER, ROAR_ERROR_INVAL},
924 {ROAR_ERROR_TYPE_WINSOCK, WSA_OPERATION_ABORTED, ROAR_ERROR_INTERRUPTED},
925// {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_INCOMPLETE, ROAR_ERROR_???},
926// {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_PENDING, ROAR_ERROR_???},
927 {ROAR_ERROR_TYPE_WINSOCK, WSAEINTR, ROAR_ERROR_INTERRUPTED},
928 {ROAR_ERROR_TYPE_WINSOCK, WSAEBADF, ROAR_ERROR_BADFH},
929 {ROAR_ERROR_TYPE_WINSOCK, WSAEACCES, ROAR_ERROR_PERM},
930 {ROAR_ERROR_TYPE_WINSOCK, WSAEFAULT, ROAR_ERROR_FAULT},
931 {ROAR_ERROR_TYPE_WINSOCK, WSAEINVAL, ROAR_ERROR_INVAL},
932 {ROAR_ERROR_TYPE_WINSOCK, WSAEMFILE, ROAR_ERROR_MFILE},
933 {ROAR_ERROR_TYPE_WINSOCK, WSAEWOULDBLOCK, ROAR_ERROR_AGAIN},
934 {ROAR_ERROR_TYPE_WINSOCK, WSAEINPROGRESS, ROAR_ERROR_INPROGRESS},
935 {ROAR_ERROR_TYPE_WINSOCK, WSAEALREADY, ROAR_ERROR_ALREADY},
936 {ROAR_ERROR_TYPE_WINSOCK, WSAENOTSOCK, ROAR_ERROR_NOTSOCK},
937 {ROAR_ERROR_TYPE_WINSOCK, WSAEDESTADDRREQ, ROAR_ERROR_DESTADDRREQ},
938 {ROAR_ERROR_TYPE_WINSOCK, WSAEMSGSIZE, ROAR_ERROR_MSGSIZE},
939// {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTOTYPE, ROAR_ERROR_???},
940// {ROAR_ERROR_TYPE_WINSOCK, WSAENOPROTOOPT, ROAR_ERROR_???},
941 {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTONOSUPPORT, ROAR_ERROR_PROTONOSUP},
942 {ROAR_ERROR_TYPE_WINSOCK, WSAESOCKTNOSUPPORT, ROAR_ERROR_PROTONOSUP},
943 {ROAR_ERROR_TYPE_WINSOCK, WSAEOPNOTSUPP, ROAR_ERROR_NOTSUP},
944 {ROAR_ERROR_TYPE_WINSOCK, WSAEPFNOSUPPORT, ROAR_ERROR_AFNOTSUP},
945 {ROAR_ERROR_TYPE_WINSOCK, WSAEAFNOSUPPORT, ROAR_ERROR_AFNOTSUP},
946 {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRINUSE, ROAR_ERROR_ADDRINUSE},
947// {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRNOTAVAIL, ROAR_ERROR_???},
948// {ROAR_ERROR_TYPE_WINSOCK, WSAENETDOWN, ROAR_ERROR_???},
949 {ROAR_ERROR_TYPE_WINSOCK, WSAENETUNREACH, ROAR_ERROR_NETUNREACH},
950// {ROAR_ERROR_TYPE_WINSOCK, WSAENETRESET, ROAR_ERROR_???},
951// {ROAR_ERROR_TYPE_WINSOCK, WSAECONNABORTED, ROAR_ERROR_???},
952// {ROAR_ERROR_TYPE_WINSOCK, WSAECONNRESET, ROAR_ERROR_???},
953// {ROAR_ERROR_TYPE_WINSOCK, WSAENOBUFS, ROAR_ERROR_???},
954 {ROAR_ERROR_TYPE_WINSOCK, WSAEISCONN, ROAR_ERROR_ISCONN},
955 {ROAR_ERROR_TYPE_WINSOCK, WSAENOTCONN, ROAR_ERROR_NOTCONN},
956// {ROAR_ERROR_TYPE_WINSOCK, WSAESHUTDOWN, ROAR_ERROR_???},
957// {ROAR_ERROR_TYPE_WINSOCK, WSAETOOMANYREFS, ROAR_ERROR_???},
958 {ROAR_ERROR_TYPE_WINSOCK, WSAETIMEDOUT, ROAR_ERROR_TIMEDOUT},
959 {ROAR_ERROR_TYPE_WINSOCK, WSAECONNREFUSED, ROAR_ERROR_CONNREFUSED},
960 {ROAR_ERROR_TYPE_WINSOCK, WSAELOOP, ROAR_ERROR_LOOP},
961 {ROAR_ERROR_TYPE_WINSOCK, WSAENAMETOOLONG, ROAR_ERROR_NAMETOOLONG},
962// {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTDOWN, ROAR_ERROR_???},
963 {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTUNREACH, ROAR_ERROR_NODEUNREACH},
964 {ROAR_ERROR_TYPE_WINSOCK, WSAENOTEMPTY, ROAR_ERROR_NOTEMPTY},
965// {ROAR_ERROR_TYPE_WINSOCK, WSAEPROCLIM, ROAR_ERROR_???},
966// {ROAR_ERROR_TYPE_WINSOCK, WSAEUSERS, ROAR_ERROR_???},
967// {ROAR_ERROR_TYPE_WINSOCK, WSAEDQUOT, ROAR_ERROR_???},
968 {ROAR_ERROR_TYPE_WINSOCK, WSAESTALE, ROAR_ERROR_STALE},
969// {ROAR_ERROR_TYPE_WINSOCK, WSAEREMOTE, ROAR_ERROR_???},
970// {ROAR_ERROR_TYPE_WINSOCK, WSASYSNOTREADY, ROAR_ERROR_???},
971 {ROAR_ERROR_TYPE_WINSOCK, WSAVERNOTSUPPORTED, ROAR_ERROR_NSVERSION},
972// {ROAR_ERROR_TYPE_WINSOCK, WSANOTINITIALISED, ROAR_ERROR_???},
973// {ROAR_ERROR_TYPE_WINSOCK, WSAEDISCON, ROAR_ERROR_???},
974// {ROAR_ERROR_TYPE_WINSOCK, WSAENOMORE, ROAR_ERROR_???},
975// {ROAR_ERROR_TYPE_WINSOCK, WSAECANCELLED, ROAR_ERROR_???},
976// {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROCTABLE, ROAR_ERROR_???},
977// {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROVIDER, ROAR_ERROR_???},
978// {ROAR_ERROR_TYPE_WINSOCK, WSAEPROVIDERFAILEDINIT, ROAR_ERROR_???},
979// {ROAR_ERROR_TYPE_WINSOCK, WSASYSCALLFAILURE, ROAR_ERROR_???},
980 {ROAR_ERROR_TYPE_WINSOCK, WSASERVICE_NOT_FOUND, ROAR_ERROR_NOENT},
981 {ROAR_ERROR_TYPE_WINSOCK, WSATYPE_NOT_FOUND, ROAR_ERROR_NOENT},
982 {ROAR_ERROR_TYPE_WINSOCK, WSA_E_NO_MORE, ROAR_ERROR_NOENT},
983// {ROAR_ERROR_TYPE_WINSOCK, WSA_E_CANCELLED, ROAR_ERROR_???},
984// {ROAR_ERROR_TYPE_WINSOCK, WSAEREFUSED, ROAR_ERROR_???},
985 {ROAR_ERROR_TYPE_WINSOCK, WSAHOST_NOT_FOUND, ROAR_ERROR_NOENT},
986 {ROAR_ERROR_TYPE_WINSOCK, WSATRY_AGAIN, ROAR_ERROR_AGAIN},
987// {ROAR_ERROR_TYPE_WINSOCK, WSANO_RECOVERY, ROAR_ERROR_???},
988 {ROAR_ERROR_TYPE_WINSOCK, WSANO_DATA, ROAR_ERROR_NODATA},
989#if 0
990 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RECEIVERS, ROAR_ERROR_???},
991 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_SENDERS, ROAR_ERROR_???},
992 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_SENDERS, ROAR_ERROR_???},
993 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_RECEIVERS, ROAR_ERROR_???},
994 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_REQUEST_CONFIRMED, ROAR_ERROR_???},
995 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ADMISSION_FAILURE, ROAR_ERROR_???},
996 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_POLICY_FAILURE, ROAR_ERROR_???},
997 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_STYLE, ROAR_ERROR_???},
998 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_OBJECT, ROAR_ERROR_???},
999 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_TRAFFIC_CTRL_ERROR, ROAR_ERROR_???},
1000 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_GENERIC_ERROR, ROAR_ERROR_???},
1001 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESERVICETYPE, ROAR_ERROR_???},
1002 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWSPEC, ROAR_ERROR_???},
1003 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPROVSPECBUF, ROAR_ERROR_???},
1004 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERSTYLE, ROAR_ERROR_???},
1005 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERTYPE, ROAR_ERROR_???},
1006 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERCOUNT, ROAR_ERROR_???},
1007 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EOBJLENGTH, ROAR_ERROR_???},
1008 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWCOUNT, ROAR_ERROR_???},
1009 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EUNKOWNPSOBJ, ROAR_ERROR_???},
1010 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPOLICYOBJ, ROAR_ERROR_???},
1011 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWDESC, ROAR_ERROR_???},
1012 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFLOWSPEC, ROAR_ERROR_???},
1013 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFILTERSPEC, ROAR_ERROR_???},
1014 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESDMODEOBJ, ROAR_ERROR_???},
1015 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESHAPERATEOBJ, ROAR_ERROR_???},
1016 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RESERVED_PETYPE, ROAR_ERROR_???},
1017#endif
1018#endif
1019 {ROAR_ERROR_TYPE_EAI, 0 /* defined value, see manpage */, ROAR_ERROR_NONE},
1020#ifdef EAI_ADDRFAMILY
1021 {ROAR_ERROR_TYPE_EAI, EAI_ADDRFAMILY, ROAR_ERROR_NOENT},
1022#endif
1023#ifdef EAI_AGAIN
1024 {ROAR_ERROR_TYPE_EAI, EAI_AGAIN, ROAR_ERROR_AGAIN},
1025#endif
1026#ifdef EAI_BADFLAGS
1027 {ROAR_ERROR_TYPE_EAI, EAI_BADFLAGS, ROAR_ERROR_INVAL},
1028#endif
1029#ifdef EAI_FAIL
1030 {ROAR_ERROR_TYPE_EAI, EAI_FAIL, ROAR_ERROR_RIO},
1031#endif
1032#ifdef EAI_FAMILY
1033 {ROAR_ERROR_TYPE_EAI, EAI_FAMILY, ROAR_ERROR_AFNOTSUP},
1034#endif
1035#ifdef EAI_MEMORY
1036 {ROAR_ERROR_TYPE_EAI, EAI_MEMORY, ROAR_ERROR_NOMEM},
1037#endif
1038#ifdef EAI_NODATA
1039 {ROAR_ERROR_TYPE_EAI, EAI_NODATA, ROAR_ERROR_NODATA},
1040#endif
1041#ifdef EAI_NONAME
1042 {ROAR_ERROR_TYPE_EAI, EAI_NONAME, ROAR_ERROR_NOENT},
1043#endif
1044#ifdef EAI_SERVICE
1045 {ROAR_ERROR_TYPE_EAI, EAI_SERVICE, ROAR_ERROR_PROTONOSUP},
1046#endif
1047#ifdef EAI_SOCKTYPE
1048 {ROAR_ERROR_TYPE_EAI, EAI_SOCKTYPE, ROAR_ERROR_INVAL},
1049#endif
1050#ifdef EAI_SYSTEM
1051// {ROAR_ERROR_TYPE_EAI, EAI_SYSTEM, ROAR_ERROR_???},
1052#endif
1053};
1054
1055static int roar_err_convert_table_lookup(const struct error_table_entry ** match,
1056                                         const int error,
1057                                         const enum roar_error_type type,
1058                                         const int to_roar) {
1059 size_t i;
1060
1061 // we have the following loop to times as an inner if() would cost more cycles
1062 // than the outer if we currently have.
1063
1064 if ( to_roar ) {
1065  for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) {
1066   if ( __libroar_error_table[i].type == type && __libroar_error_table[i].error == error) {
1067    *match = &(__libroar_error_table[i]);
1068    return ROAR_ERROR_NONE;
1069   }
1070  }
1071 } else {
1072  for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) {
1073   if ( __libroar_error_table[i].type == type && __libroar_error_table[i].roarerror == error) {
1074    *match = &(__libroar_error_table[i]);
1075    return ROAR_ERROR_NONE;
1076   }
1077  }
1078 }
1079
1080 return ROAR_ERROR_NOENT;
1081}
1082
1083// Convert error codes between diffrent representations.
1084// returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state.
1085int    roar_err_convert(int * out, const enum roar_error_type outtype, const int in, const enum roar_error_type intype) {
1086 const struct error_table_entry * tablematch;
1087 int tmp;
1088 int ret;
1089
1090 if ( out == NULL )
1091  return ROAR_ERROR_FAULT;
1092
1093 if ( outtype == intype ) {
1094  *out = in;
1095  return ROAR_ERROR_NONE;
1096 }
1097
1098 // if not to/from roar, use roar as temp type so we do only need to code two kinds of translators (not any->any).
1099 if ( intype != ROAR_ERROR_TYPE_ROARAUDIO && outtype != ROAR_ERROR_TYPE_ROARAUDIO ) {
1100  ret = roar_err_convert(&tmp, ROAR_ERROR_TYPE_ROARAUDIO, in, intype);
1101  if ( ret != ROAR_ERROR_NONE )
1102   return ret;
1103
1104  return roar_err_convert(out, outtype, tmp, ROAR_ERROR_TYPE_ROARAUDIO);
1105 }
1106
1107 // from here we can asume that if intype != ROAR_ERROR_TYPE_ROARAUDIO outtype is ROAR_ERROR_TYPE_ROARAUDIO
1108 // and the other way around.
1109
1110 if ( intype == ROAR_ERROR_TYPE_ROARAUDIO ) {
1111  ret = roar_err_convert_table_lookup(&tablematch, in, outtype, 0);
1112 } else {
1113  ret = roar_err_convert_table_lookup(&tablematch, in, intype, 1);
1114 }
1115
1116 if ( ret == ROAR_ERROR_NONE ) {
1117  *out = intype == ROAR_ERROR_TYPE_ROARAUDIO ? tablematch->error : tablematch->roarerror;
1118  return ROAR_ERROR_NONE;
1119 }
1120
1121 if ( intype == ROAR_ERROR_TYPE_ROARAUDIO && outtype == ROAR_ERROR_TYPE_ERRNO ) {
1122  // the __roar_to_errno() function always succeeds.
1123  *out = __roar_to_errno(in);
1124  return ROAR_ERROR_NONE;
1125 }
1126
1127 if ( outtype == ROAR_ERROR_TYPE_ROARAUDIO && intype == ROAR_ERROR_TYPE_ERRNO ) {
1128  // the __errno_to_roar() function always succeeds.
1129  *out = __errno_to_roar(in);
1130  return ROAR_ERROR_NONE;
1131 }
1132
1133 roar_err_get_default_error(out, outtype);
1134 return ROAR_ERROR_NOENT;
1135}
1136
1137// Outputs a default error for the given type.
1138// returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state.
1139int    roar_err_get_default_error(int * out, const enum roar_error_type type) {
1140 int is_set = 0;
1141
1142 if ( out == NULL )
1143  return ROAR_ERROR_FAULT;
1144
1145 switch (type) {
1146  case ROAR_ERROR_TYPE_ROARAUDIO: is_set = 1; *out = ROAR_ERROR_UNKNOWN; break;
1147#ifdef EINVAL
1148  case ROAR_ERROR_TYPE_ERRNO: is_set = 1; *out = EINVAL; break;
1149#endif
1150#ifdef NO_RECOVERY
1151  case ROAR_ERROR_TYPE_HERROR: is_set = 1; *out = NO_RECOVERY; break;
1152#endif
1153#ifdef __YIFF__
1154  case ROAR_ERROR_TYPE_YIFF: is_set = 1; *out = YIFF_ERRNO_UNKNOWN; break;
1155#endif
1156  case ROAR_ERROR_TYPE_HTTP: is_set = 1; *out = 500; break;
1157#ifndef DEBUG
1158  // enable compiler warnings in DEBUG mode.
1159  default:
1160   break;
1161#endif
1162 }
1163
1164 if ( is_set ) {
1165  return ROAR_ERROR_NONE;
1166 }
1167
1168 *out = -1; // some default so we do not leave it uninited.
1169 return ROAR_ERROR_NOENT;
1170}
1171
1172// Resets the stored state to 'no error' state. This can be used
1173// to init the state.
1174int    roar_err_initstore(struct roar_error_state * state) {
1175 struct roar_error_state curstate;
1176
1177 if ( state == NULL ) {
1178  roar_err_set(ROAR_ERROR_FAULT);
1179  return -1;
1180 }
1181
1182 roar_err_store(&curstate);
1183 roar_err_clear_all();
1184 roar_err_store(state);
1185 roar_err_restore(&curstate);
1186
1187 return -1;
1188}
1189
1190// store a error state (both libroar and system)
1191int    roar_err_store(struct roar_error_state * state) {
1192 if ( state == NULL )
1193  return ROAR_ERROR_FAULT;
1194
1195 memset(state, 0, sizeof(struct roar_error_state));
1196
1197 state->refc          = 0;
1198 state->libroar_error = roar_error;
1199 state->system_error  = errno;
1200
1201#ifdef ROAR_TARGET_WIN32
1202 state->winsock_error = WSAGetLastError();
1203#endif
1204#ifdef ROAR_HAVE_VAR_H_ERRNO
1205 state->syssock_herror = h_errno;
1206#endif
1207
1208#ifdef __YIFF__
1209 state->yiffc_error = yiffc_error;
1210#endif
1211
1212 return ROAR_ERROR_NONE;
1213}
1214
1215// restore error state to values at time of call to roar_err_store()
1216int    roar_err_restore(struct roar_error_state * state) {
1217 if ( state == NULL )
1218  return ROAR_ERROR_FAULT;
1219
1220 roar_err_set(state->libroar_error);
1221 errno = state->system_error;
1222
1223#ifdef ROAR_TARGET_WIN32
1224 WSASetLastError(state->winsock_error);
1225#endif
1226#ifdef ROAR_HAVE_VAR_H_ERRNO
1227 h_errno = state->syssock_herror;
1228#endif
1229
1230#ifdef __YIFF__
1231 yiffc_error = state->yiffc_error;
1232#endif
1233
1234 return ROAR_ERROR_NONE;
1235}
1236
1237
1238// 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
1239
1240static const char * roar_error2str_ms(const int error, const char * msg) {
1241 static char buf[1024] = "";
1242 int num[8];
1243 size_t i;
1244 int _ra_err = roar_error;
1245 int _sys_err = errno;
1246
1247 for (i = 0; i < (sizeof(num)/sizeof(*num)); i++)
1248  num[i] = roar_random_uint32();
1249
1250 snprintf(buf, sizeof(buf), "\e[44;39;1m\e[2J\e[H"
1251                            "                                   RoarAudio\n"
1252                            "\n\n"
1253                            "Fatal error %.4x: %s\n"
1254                            "RA Error: %.4i, Sys Error: %.4i (%s)\n"
1255                            "Random numbers:\n"
1256                            " A: 0x%.8X B: 0x%.8X\n"
1257                            " C: 0x%.8X D: 0x%.8X\n"
1258                            " E: 0x%.8X F: 0x%.8X\n"
1259                            " G: 0x%.8X H: 0x%.8X\n"
1260                            "\n\n"
1261                            "\e[0m",
1262                            error, msg,
1263                            _ra_err, _sys_err, strerror(_sys_err),
1264                            num[0], num[1], num[2], num[3], num[4], num[5], num[6], num[7]);
1265
1266 return buf;
1267}
1268
1269const char * roar_error2str(const int error) {
1270 struct roar_libroar_config * config = roar_libroar_get_config();
1271 const struct {
1272  const int    err;
1273  const char * msg;
1274 } msgs[] = {
1275  {ROAR_ERROR_NONE,        "No error"},
1276  {ROAR_ERROR_PERM,        "Operation not permitted"},
1277  {ROAR_ERROR_NOENT,       "No such object, file, directory or node"},
1278  {ROAR_ERROR_BADMSG,      "Bad message"},
1279  {ROAR_ERROR_BUSY,        "Device or resource busy"},
1280  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
1281  {ROAR_ERROR_NOSYS,       "Function not implemented"},
1282  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
1283  {ROAR_ERROR_PIPE,        "Broken pipe"},
1284  {ROAR_ERROR_PROTO,       "Protocol error"},
1285  {ROAR_ERROR_RANGE,       "Result too large or parameter out of range"},
1286  {ROAR_ERROR_MSGSIZE,     "Message too long"},
1287  {ROAR_ERROR_NOMEM,       "Not enough space"},
1288  {ROAR_ERROR_INVAL,       "Invalid argument"},
1289  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
1290  {ROAR_ERROR_BADRQC,      "Invalid request code"},
1291  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
1292  {ROAR_ERROR_EXIST,       "File or object exists"},
1293  {ROAR_ERROR_FAULT,       "Bad address"},
1294  {ROAR_ERROR_IO,          "I/O-Error"},
1295  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
1296  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
1297  {ROAR_ERROR_LOOP,        "Too many recursions"},
1298  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
1299  {ROAR_ERROR_NAMETOOLONG, "File or object name too long"},
1300  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
1301  {ROAR_ERROR_NODEV,       "No such device"},
1302  {ROAR_ERROR_NODRV,       "No such driver"},
1303  {ROAR_ERROR_NOSPC,       "No space left on device"},
1304  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
1305  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
1306  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
1307  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
1308  {ROAR_ERROR_RIO,         "Remote I/O Error"},
1309  {ROAR_ERROR_RO,          "File or object is read only"},
1310  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
1311  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
1312  {ROAR_ERROR_NOISE,       "Line too noisy"},
1313  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
1314  {ROAR_ERROR_INTERRUPTED, "Operation was interruped"},
1315  {ROAR_ERROR_CAUSALITY,   "Causality error"},
1316  {ROAR_ERROR_QUOTA,       "Quota exceeded"},
1317  {ROAR_ERROR_BADLIB,      "Accessing a corrupted shared library"},
1318  {ROAR_ERROR_NOMEDIUM,    "No medium found"},
1319  {ROAR_ERROR_NOTUNIQ,     "Name not unique"},
1320  {ROAR_ERROR_ILLSEQ,      "Illegal byte sequence"},
1321  {ROAR_ERROR_ADDRINUSE,   "Address in use"},
1322  {ROAR_ERROR_HOLE,        "Hole in data"},
1323  {ROAR_ERROR_BADVERSION,  "Bad version"},
1324  {ROAR_ERROR_NSVERSION,   "Not supported version"},
1325  {ROAR_ERROR_BADMAGIC,    "Bad magic number"},
1326  {ROAR_ERROR_LOSTSYNC,    "Lost synchronization"},
1327  {ROAR_ERROR_BADSEEK,     "Can not seek to destination position"},
1328  {ROAR_ERROR_NOSEEK,      "Seeking not supported on resource"},
1329  {ROAR_ERROR_BADCKSUM,    "Data integrity error"},
1330  {ROAR_ERROR_NOHORSE,     "Mount failed"},
1331  {ROAR_ERROR_CHERNOBYL,   "Fatal device error"},
1332  {ROAR_ERROR_NOHUG,       "Device needs love"},
1333  {ROAR_ERROR_TEXTBUSY,    "Text file busy"},
1334  {ROAR_ERROR_NOTEMPTY,    "Directory not empty"},
1335  {ROAR_ERROR_NODEUNREACH, "Node is unreachable"},
1336  {ROAR_ERROR_IDREMOVED,   "Identifier removed"},
1337  {ROAR_ERROR_INPROGRESS,  "Operation in progress"},
1338  {ROAR_ERROR_NOCHILD,     "No child processes or object"},
1339  {ROAR_ERROR_NETUNREACH,  "Network unreachable"},
1340  {ROAR_ERROR_CANCELED,    "Operation canceled"},
1341  {ROAR_ERROR_ISDIR,       "Is a directory"},
1342  {ROAR_ERROR_NOTDIR,      "Not a directory"},
1343  {ROAR_ERROR_BADEXEC,     "Executable file format error"},
1344  {ROAR_ERROR_ISCONN,      "Socket or Object is connected"},
1345  {ROAR_ERROR_DEADLOCK,    "Resource deadlock would occur"},
1346  {ROAR_ERROR_CONNRST,     "Connection reset"},
1347  {ROAR_ERROR_BADFH,       "Bad file handle"},
1348  {ROAR_ERROR_NOTSOCK,     "Not a socket"},
1349  {ROAR_ERROR_TOOMANYARGS, "Argument list too long"},
1350  {ROAR_ERROR_TOOLARGE,    "File or Object too large"},
1351  {ROAR_ERROR_DESTADDRREQ, "Destination address required"},
1352  {ROAR_ERROR_AFNOTSUP,    "Address family not supported"},
1353  {ROAR_ERROR_NOPOWER,     "Operation can not be completed because we are low on power"},
1354  {ROAR_ERROR_USER,        "Error in front of screen"},
1355  {ROAR_ERROR_NFILE,       "Too many filesobjects open in system"},
1356  {ROAR_ERROR_STALE,       "Stale file handle or object"},
1357  {ROAR_ERROR_XDEVLINK,    "Cross-device link"},
1358  {ROAR_ERROR_MLINK,       "Too many links to file or object"},
1359  {ROAR_ERROR_NONET,       "Not connected to any network"},
1360  {ROAR_ERROR_CONNRSTNET,  "Connection reset by network"},
1361  {ROAR_ERROR_CONNABORTED, "Connection aborted"},
1362  {ROAR_ERROR_BADHOST,     "Bad host software or hardware"},
1363  {ROAR_ERROR_SWITCHPROTO, "Switch protocol"},
1364  {ROAR_ERROR_MOVEDPERM,   "Moved Permanently"},
1365  {ROAR_ERROR_MOVEDTEMP,   "Moved Temporary"},
1366  {ROAR_ERROR_USEPROXY,    "Use Proxy server"},
1367  {ROAR_ERROR_SEEOTHER,    "See other resource"},
1368  {ROAR_ERROR_GONE,        "Resource gone"},
1369  {ROAR_ERROR_BADLICENSE,  "Bad License"},
1370  {-1, NULL}
1371 }, msgs_funny[] = {
1372//  {ROAR_ERROR_UNKNOWN,     "Unknown (maybe no) error"},
1373  {ROAR_ERROR_NONE,        "No error, huh?"},
1374  {ROAR_ERROR_PERM,        "Little kitty is not allowed to do this"},
1375  {ROAR_ERROR_NOENT,       "Mouse not found"},
1376//  {ROAR_ERROR_BADMSG,      "Bad message"},
1377  {ROAR_ERROR_BUSY,        "Another kitty is playing with this mouse"},
1378//  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
1379//  {ROAR_ERROR_NOSYS,       "Function not implemented"},
1380//  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
1381  {ROAR_ERROR_PIPE,        "Flood"},
1382//  {ROAR_ERROR_PROTO,       "Protocol error"},
1383//  {ROAR_ERROR_RANGE,       "Result too largegeneral out of range"},
1384//  {ROAR_ERROR_MSGSIZE,     "Message too long"},
1385//  {ROAR_ERROR_NOMEM,       "Not enough space"},
1386//  {ROAR_ERROR_INVAL,       "Invalid argument"},
1387//  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
1388  {ROAR_ERROR_BADRQC,      "Stupid staff"},
1389//  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
1390//  {ROAR_ERROR_EXIST,       "File or object exists"},
1391//  {ROAR_ERROR_FAULT,       "Bad address"},
1392//  {ROAR_ERROR_IO,          "IO-Error"},
1393//  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
1394//  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
1395//  {ROAR_ERROR_LOOP,        "Too many recursions"},
1396//  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
1397  {ROAR_ERROR_NAMETOOLONG, "Staff can not remember long names"},
1398//  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
1399  {ROAR_ERROR_NODEV,       "No such mouse"},
1400//  {ROAR_ERROR_NODRV,       "No such driver"},
1401  {ROAR_ERROR_NOSPC,       "Too many fish on desk"},
1402//  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
1403//  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
1404//  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
1405//  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
1406//  {ROAR_ERROR_RIO,         "Remote IO Error"},
1407  {ROAR_ERROR_RO,          "Touching disallowed"},
1408//  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
1409//  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
1410//  {ROAR_ERROR_NOISE,       "Line too noisy"},
1411//  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
1412//  {ROAR_ERROR_INTERRUPTED, "Operation was interruped"},
1413//  {ROAR_ERROR_CAUSALITY,   "Causality error"},
1414//  {ROAR_ERROR_QUOTA,       "Quota exceeded"},
1415//  {ROAR_ERROR_BADLIB,      "Accessing a corrupted shared library"},
1416//  {ROAR_ERROR_NOMEDIUM,    "No medium found"},
1417//  {ROAR_ERROR_NOTUNIQ,     "Name not unique"},
1418//  {ROAR_ERROR_ILLSEQ,      "Illegal byte sequence"},
1419//  {ROAR_ERROR_ADDRINUSE,   "Address in use"},
1420  {ROAR_ERROR_HOLE,        "Hole in wall"},
1421//  {ROAR_ERROR_BADVERSION,  "Bad version"},
1422//  {ROAR_ERROR_NSVERSION,   "Not supported version"},
1423  {ROAR_ERROR_BADMAGIC,    "Magician's fault"},
1424//  {ROAR_ERROR_LOSTSYNC,    "Lost synchronization"},
1425//  {ROAR_ERROR_BADSEEK,     "Can not seek to destination position"},
1426//  {ROAR_ERROR_NOSEEK,      "Seeking not supported on resource"},
1427//  {ROAR_ERROR_BADCKSUM,    "Data integrity error"},
1428  {ROAR_ERROR_NOHORSE,     "No horse"},
1429//  {ROAR_ERROR_CHERNOBYL,   "Fatal device error"},
1430  {ROAR_ERROR_NOHUG,       "No hug"},
1431//  {ROAR_ERROR_TEXTBUSY,    "Text file busy"},
1432//  {ROAR_ERROR_NOTEMPTY,    "Directory not empty"},
1433//  {ROAR_ERROR_NODEUNREACH, "Node is unreachable"},
1434//  {ROAR_ERROR_IDREMOVED,   "Identifier removed"},
1435//  {ROAR_ERROR_INPROGRESS,  "Operation in progress"},
1436//  {ROAR_ERROR_NOCHILD,     "No child processesobject"},
1437//  {ROAR_ERROR_NETUNREACH,  "Network unreachable"},
1438//  {ROAR_ERROR_CANCELED,    "Operation canceled"},
1439//  {ROAR_ERROR_ISDIR,       "Is a directory"},
1440//  {ROAR_ERROR_NOTDIR,      "Not a directory"},
1441//  {ROAR_ERROR_BADEXEC,     "Executable file format error"},
1442//  {ROAR_ERROR_ISCONN,      "Socket/Object is connected"},
1443  {ROAR_ERROR_DEADLOCK,    "Mouse would die"},
1444//  {ROAR_ERROR_CONNRST,     "Connection reset"},
1445//  {ROAR_ERROR_BADFH,       "Bad file handle"},
1446//  {ROAR_ERROR_NOTSOCK,     "Not a socket"},
1447//  {ROAR_ERROR_TOOMANYARGS, "Argument list too long"},
1448//  {ROAR_ERROR_TOOLARGE,    "File/Object too large"},
1449//  {ROAR_ERROR_DESTADDRREQ, "Destination address required"},
1450//  {ROAR_ERROR_AFNOTSUP,    "Address family not supported"},
1451//  {ROAR_ERROR_NOPOWER,     "Operation can not be completed because we are low on power"},
1452//  {ROAR_ERROR_USER,        "Error in front of screen"},
1453//  {ROAR_ERROR_NFILE,       "Too many filesobjects open in system"},
1454//  {ROAR_ERROR_STALE,       "Stale file handle or object"},
1455  {ROAR_ERROR_XDEVLINK,    "Mice tails too short for kinking"},
1456//  {ROAR_ERROR_MLINK,       "Too many links to file or object"},
1457//  {ROAR_ERROR_NONET,       "Not connected to any network"},
1458//  {ROAR_ERROR_CONNRSTNET,  "Connection reset by network"},
1459//  {ROAR_ERROR_CONNABORTED, "Connection aborted"},
1460//  {ROAR_ERROR_BADHOST,     "Bad host software or hardware"},
1461//  {ROAR_ERROR_SWITCHPROTO, "Switch protocol"},
1462//  {ROAR_ERROR_MOVEDPERM,   "Moved Permanently"},
1463//  {ROAR_ERROR_MOVEDTEMP,   "Moved Temporary"},
1464//  {ROAR_ERROR_USEPROXY,    "Use Proxy server"},
1465//  {ROAR_ERROR_SEEOTHER,    "See other resource"},
1466//  {ROAR_ERROR_GONE,        "Resource gone"},
1467  {-1, NULL}
1468 };
1469 int i;
1470
1471 if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_MS ) {
1472  for (i = 0; msgs[i].msg != NULL; i++) {
1473   if ( msgs[i].err == error ) {
1474    return roar_error2str_ms(error, msgs[i].msg);
1475   }
1476  }
1477  return roar_error2str_ms(error, "<<<unknown error>>>");
1478 }
1479
1480 if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_FUNNY )
1481  for (i = 0; msgs_funny[i].msg != NULL; i++)
1482   if ( msgs_funny[i].err == error )
1483    return msgs_funny[i].msg;
1484
1485 for (i = 0; msgs[i].msg != NULL; i++)
1486  if ( msgs[i].err == error )
1487   return msgs[i].msg;
1488
1489 return NULL;
1490}
1491
1492//ll
Note: See TracBrowser for help on using the repository browser.