source: roaraudio/libroar/error.c @ 4876:06a2f29d0450

Last change on this file since 4876:06a2f29d0450 was 4876:06a2f29d0450, checked in by phi, 13 years ago

some updates to handle error values better with DSTR

File size: 11.9 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
128 // NOTE: _NEVER_ call ROAR_{DBG,INFO,WARN,ERRO}() in here! (will result in endless loop)
129 //printf("*err=%i, errno=%i\n", *err, (int)errno);
130
131 if ( *err != ROAR_ERROR_NONE ) {
132  roar_err_to_errno();
133 } else if ( !roar_err_is_errno_clean() ) {
134  roar_err_from_errno();
135 }
136}
137
138int    roar_err_is_errno_clean(void) {
139 return errno == CLEAN_ERRNO ? 1 : 0;
140}
141
142void   roar_err_set(const int error) {
143 *roar_errno2() = error;
144}
145
146void   roar_err_from_errno(void) {
147 int _roar_errno = ROAR_ERROR_NONE;
148
149 switch (errno) {
150#ifdef EACCES
151  case EACCES:       _roar_errno = ROAR_ERROR_PERM; break;
152#endif
153#ifdef EPERM
154  case EPERM:        _roar_errno = ROAR_ERROR_PERM; break;
155#endif
156#ifdef ENOENT
157  case ENOENT:       _roar_errno = ROAR_ERROR_NOENT; break;
158#endif
159#ifdef EBADMSG
160  case EBADMSG:      _roar_errno = ROAR_ERROR_BADMSG; break;
161#endif
162#ifdef EBUSY
163  case EBUSY:        _roar_errno = ROAR_ERROR_BUSY; break;
164#endif
165#ifdef ECONNREFUSED
166  case ECONNREFUSED: _roar_errno = ROAR_ERROR_CONNREFUSED; break;
167#endif
168#ifdef ENOSYS
169  case ENOSYS:       _roar_errno = ROAR_ERROR_NOSYS; break;
170#endif
171#ifdef ENOTSUP
172  case ENOTSUP:      _roar_errno = ROAR_ERROR_NOTSUP; break;
173#endif
174#ifdef EPIPE
175  case EPIPE:        _roar_errno = ROAR_ERROR_PIPE; break;
176#endif
177#ifdef EPROTO
178  case EPROTO:       _roar_errno = ROAR_ERROR_PROTO; break;
179#endif
180#ifdef ERANGE
181  case ERANGE:       _roar_errno = ROAR_ERROR_RANGE; break;
182#endif
183#ifdef EMSGSIZE
184  case EMSGSIZE:     _roar_errno = ROAR_ERROR_MSGSIZE; break;
185#endif
186#ifdef ENOMEM
187  case ENOMEM:       _roar_errno = ROAR_ERROR_NOMEM; break;
188#endif
189#ifdef EINVAL
190  case EINVAL:       _roar_errno = ROAR_ERROR_INVAL; break;
191#endif
192#ifdef EALREADY
193  case EALREADY:     _roar_errno = ROAR_ERROR_ALREADY; break;
194#endif
195#ifdef EBADRQC
196  case EBADRQC:      _roar_errno = ROAR_ERROR_BADRQC; break;
197#endif
198#ifdef EDOM
199  case EDOM:         _roar_errno = ROAR_ERROR_DOM; break;
200#endif
201#ifdef EEXIST
202  case EEXIST:       _roar_errno = ROAR_ERROR_EXIST; break;
203#endif
204#ifdef EFAULT
205  case EFAULT:       _roar_errno = ROAR_ERROR_FAULT; break;
206#endif
207#ifdef EIO
208  case EIO:          _roar_errno = ROAR_ERROR_IO; break;
209#endif
210#ifdef EKEYEXPIRED
211  case EKEYEXPIRED:  _roar_errno = ROAR_ERROR_KEYEXPIRED; break;
212#endif
213#ifdef EKEYREJECTED
214  case EKEYREJECTED: _roar_errno = ROAR_ERROR_KEYREJECTED; break;
215#endif
216#ifdef ELOOP
217  case ELOOP:        _roar_errno = ROAR_ERROR_LOOP; break;
218#endif
219#ifdef EMFILE
220  case EMFILE:       _roar_errno = ROAR_ERROR_MFILE; break;
221#endif
222#ifdef ENAMETOOLONG
223  case ENAMETOOLONG: _roar_errno = ROAR_ERROR_NAMETOOLONG; break;
224#endif
225#ifdef ENODATA
226  case ENODATA:      _roar_errno = ROAR_ERROR_NODATA; break;
227#endif
228#ifdef ENODEV
229  case ENODEV:       _roar_errno = ROAR_ERROR_NODEV; break;
230#endif
231#ifdef ENOSPC
232  case ENOSPC:       _roar_errno = ROAR_ERROR_NOSPC; break;
233#endif
234#ifdef ENOTCONN
235  case ENOTCONN:     _roar_errno = ROAR_ERROR_NOTCONN; break;
236#endif
237#ifdef EPROTONOSUPPORT
238  case EPROTONOSUPPORT: _roar_errno = ROAR_ERROR_PROTONOSUP; break;
239#endif
240#ifdef EROFS
241  case EROFS:        _roar_errno = ROAR_ERROR_RO; break;
242#endif
243#ifdef ETIMEDOUT
244  case ETIMEDOUT:    _roar_errno = ROAR_ERROR_TIMEDOUT; break;
245#endif
246#ifdef EAGAIN
247  case EAGAIN:       _roar_errno = ROAR_ERROR_AGAIN; break;
248#endif
249#ifdef ENETDOWN
250  case ENETDOWN:     _roar_errno = ROAR_ERROR_LINKDOWN; break;
251#endif
252  default:
253    _roar_errno = ROAR_ERROR_UNKNOWN;
254   break;
255 }
256
257 roar_err_set(_roar_errno);
258}
259
260void   roar_err_to_errno(void) {
261 int * err = roar_errno2();
262 switch (*err) {
263  case ROAR_ERROR_NONE:
264    roar_err_clear_errno();
265   break;
266#ifdef EPERM
267  case ROAR_ERROR_PERM:
268    errno = EPERM;
269   break;
270#endif
271#ifdef ENOENT
272  case ROAR_ERROR_NOENT:
273    errno = ENOENT;
274   break;
275#endif
276#ifdef EBADMSG
277  case ROAR_ERROR_BADMSG:
278    errno = EBADMSG;
279   break;
280#endif
281#ifdef EBUSY
282  case ROAR_ERROR_BUSY:
283    errno = EBUSY;
284   break;
285#endif
286#ifdef ECONNREFUSED
287  case ROAR_ERROR_CONNREFUSED:
288    errno = ECONNREFUSED;
289   break;
290#endif
291#ifdef ENOSYS
292  case ROAR_ERROR_NOSYS:
293    errno = ENOSYS;
294   break;
295#endif
296#ifdef ENOTSUP
297  case ROAR_ERROR_NOTSUP:
298    errno = ENOTSUP;
299   break;
300#endif
301#ifdef EPIPE
302  case ROAR_ERROR_PIPE:
303    errno = EPIPE;
304   break;
305#endif
306#ifdef EPROTO
307  case ROAR_ERROR_PROTO:
308    errno = EPROTO;
309   break;
310#endif
311#ifdef ERANGE
312  case ROAR_ERROR_RANGE:
313    errno = ERANGE;
314   break;
315#endif
316#ifdef EMSGSIZE
317  case ROAR_ERROR_MSGSIZE:
318    errno = EMSGSIZE;
319   break;
320#endif
321#ifdef ENOMEM
322  case ROAR_ERROR_NOMEM:
323    errno = ENOMEM;
324   break;
325#endif
326#ifdef EINVAL
327  case ROAR_ERROR_INVAL:
328    errno = EINVAL;
329   break;
330#endif
331#ifdef EALREADY
332  case ROAR_ERROR_ALREADY:
333    errno = EALREADY;
334   break;
335#endif
336#ifdef EBADRQC
337  case ROAR_ERROR_BADRQC:
338    errno = EBADRQC;
339   break;
340#endif
341#ifdef EDOM
342  case ROAR_ERROR_DOM:
343    errno = EDOM;
344   break;
345#endif
346#ifdef EEXIST
347  case ROAR_ERROR_EXIST:
348    errno = EEXIST;
349   break;
350#endif
351#ifdef EFAULT
352  case ROAR_ERROR_FAULT:
353    errno = EFAULT;
354   break;
355#endif
356#ifdef EIO
357  case ROAR_ERROR_IO:
358  case ROAR_ERROR_RIO:
359    errno = EIO;
360   break;
361#endif
362#ifdef EKEYEXPIRED
363  case ROAR_ERROR_KEYEXPIRED:
364    errno = EKEYEXPIRED;
365   break;
366#endif
367#ifdef EKEYREJECTED
368  case ROAR_ERROR_KEYREJECTED:
369    errno = EKEYREJECTED;
370   break;
371#endif
372#ifdef ELOOP
373  case ROAR_ERROR_LOOP:
374    errno = ELOOP;
375   break;
376#endif
377#ifdef EMFILE
378  case ROAR_ERROR_MFILE:
379    errno = EMFILE;
380   break;
381#endif
382#ifdef ENAMETOOLONG
383  case ROAR_ERROR_NAMETOOLONG:
384    errno = ENAMETOOLONG;
385   break;
386#endif
387#ifdef ENODATA
388  case ROAR_ERROR_NODATA:
389    errno = ENODATA;
390   break;
391#endif
392#ifdef ENODEV
393  case ROAR_ERROR_NODEV:
394  case ROAR_ERROR_NODRV:
395    errno = ENODEV;
396   break;
397#endif
398#ifdef ENOSPC
399  case ROAR_ERROR_NOSPC:
400    errno = ENOSPC;
401   break;
402#endif
403#ifdef EINVAL
404  case ROAR_ERROR_TYPEMM:
405    errno = EINVAL;
406   break;
407#endif
408#ifdef ENOSYS
409  case ROAR_ERROR_NORSYS:
410    errno = ENOSYS;
411   break;
412#endif
413#ifdef ENOTCONN
414  case ROAR_ERROR_NOTCONN:
415    errno = ENOTCONN;
416   break;
417#endif
418#ifdef EPROTONOSUPPORT
419  case ROAR_ERROR_PROTONOSUP:
420    errno = EPROTONOSUPPORT;
421   break;
422#endif
423#ifdef EROFS
424  case ROAR_ERROR_RO:
425    errno = EROFS;
426   break;
427#endif
428#ifdef ETIMEDOUT
429  case ROAR_ERROR_TIMEDOUT:
430    errno = ETIMEDOUT;
431   break;
432#endif
433#ifdef EAGAIN
434  case ROAR_ERROR_AGAIN:
435    errno = EAGAIN;
436   break;
437#endif
438#ifdef ENETDOWN
439  case ROAR_ERROR_LINKDOWN:
440    errno = ENETDOWN;
441   break;
442#endif
443  default:
444#ifdef EINVAL
445    errno = EINVAL;
446#else
447    errno = -1; // just guess
448#endif
449   break;
450 }
451}
452
453
454const char * roar_error2str(const int error) {
455 const struct {
456  const int    err;
457  const char * msg;
458 } msgs[] = {
459  {ROAR_ERROR_NONE,        "No error"},
460  {ROAR_ERROR_PERM,        "Operation not permitted"},
461  {ROAR_ERROR_NOENT,       "No such object, file or directory"},
462  {ROAR_ERROR_BADMSG,      "Bad message"},
463  {ROAR_ERROR_BUSY,        "Device or resource busy"},
464  {ROAR_ERROR_CONNREFUSED, "Connection refused"},
465  {ROAR_ERROR_NOSYS,       "Function not implemented"},
466  {ROAR_ERROR_NOTSUP,      "Operation not supported"},
467  {ROAR_ERROR_PIPE,        "Broken pipe"},
468  {ROAR_ERROR_PROTO,       "Protocol error"},
469  {ROAR_ERROR_RANGE,       "Result too large or parameter out of range"},
470  {ROAR_ERROR_MSGSIZE,     "Message too long"},
471  {ROAR_ERROR_NOMEM,       "Not enough space"},
472  {ROAR_ERROR_INVAL,       "Invalid argument"},
473  {ROAR_ERROR_ALREADY,     "Connection already in progress"},
474  {ROAR_ERROR_BADRQC,      "Invalid request code"},
475  {ROAR_ERROR_DOM,         "Mathematics argument out of domain of function"},
476  {ROAR_ERROR_EXIST,       "File or object exists"},
477  {ROAR_ERROR_FAULT,       "Bad address"},
478  {ROAR_ERROR_IO,          "I/O-Error"},
479  {ROAR_ERROR_KEYEXPIRED,  "Key has expired"},
480  {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"},
481  {ROAR_ERROR_LOOP,        "Too many recursions"},
482  {ROAR_ERROR_MFILE,       "Too many open files or objects"},
483  {ROAR_ERROR_NAMETOOLONG, "File or object name too long"},
484  {ROAR_ERROR_NODATA,      "No message is available on the read queue"},
485  {ROAR_ERROR_NODEV,       "No such device"},
486  {ROAR_ERROR_NODRV,       "No such driver"},
487  {ROAR_ERROR_NOSPC,       "No space left on device"},
488  {ROAR_ERROR_TYPEMM,      "Type missmatch. Object of diffrent type required"},
489  {ROAR_ERROR_NORSYS,      "Feature not implemented by remote end"},
490  {ROAR_ERROR_NOTCONN,     "Socket or object not connected"},
491  {ROAR_ERROR_PROTONOSUP,  "Protocol not supported"},
492  {ROAR_ERROR_RIO,         "Remote I/O Error"},
493  {ROAR_ERROR_RO,          "File or object is read only"},
494  {ROAR_ERROR_TIMEDOUT,    "Connection timed out"},
495  {ROAR_ERROR_AGAIN,       "Resource temporarily unavailable"},
496  {ROAR_ERROR_NOISE,       "Line too noisy"},
497  {ROAR_ERROR_LINKDOWN,    "Physical or logical link down"},
498  {-1, NULL}
499 };
500 int i;
501
502 for (i = 0; msgs[i].msg != NULL; i++)
503  if ( msgs[i].err == error )
504   return msgs[i].msg;
505
506 return NULL;
507}
508
509//ll
Note: See TracBrowser for help on using the repository browser.