Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / librols / comerr.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)comerr.c 1.29 03/06/15 Copyright 1985-1989, 1995-2003 J. Schilling */
14 /*
15  *      Routines for printing command errors
16  *
17  *      Copyright (c) 1985-1989, 1995-2003 J. Schilling
18  */
19 /*
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License version 2
22  * as published by the Free Software Foundation.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License along with
30  * this program; see the file COPYING.  If not, write to the Free Software
31  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32  */
33
34 #include <mconfig.h>
35 #include <unixstd.h>            /* include <sys/types.h> try to get size_t */
36 #include <stdio.h>              /* Try again for size_t */
37 #include <stdxlib.h>            /* Try again for size_t */
38 #include <standard.h>
39 #include <vadefs.h>
40 #include <strdefs.h>
41 #include <schily.h>
42 #include <errno.h>
43 #ifndef HAVE_STRERROR
44 extern  char    *sys_errlist[];
45 extern  int     sys_nerr;
46 #endif
47
48 EXPORT  int     on_comerr       __PR((void (*fun)(int, void *), void *arg));
49 EXPORT  void    comerr          __PR((const char *, ...));
50 EXPORT  void    comerrno        __PR((int, const char *, ...));
51 EXPORT  int     errmsg          __PR((const char *, ...));
52 EXPORT  int     errmsgno        __PR((int, const char *, ...));
53 LOCAL   int     _comerr         __PR((int, int, const char *, va_list));
54 EXPORT  void    comexit         __PR((int));
55 EXPORT  char    *errmsgstr      __PR((int));
56
57 typedef struct ex {
58         struct ex *next;
59         void    (*func) __PR((int, void *));
60         void    *arg;
61 } ex_t;
62
63 LOCAL   ex_t    *exfuncs;
64
65 EXPORT  int
66 on_comerr(func, arg)
67         void    (*func) __PR((int, void *));
68         void    *arg;
69 {
70         ex_t    *fp;
71
72         fp = malloc(sizeof (*fp));
73         if (fp == NULL)
74                 return (-1);
75
76         fp->func = func;
77         fp->arg  = arg;
78         fp->next = exfuncs;
79         exfuncs = fp;
80         return (0);
81 }
82
83 /* VARARGS1 */
84 #ifdef  PROTOTYPES
85 EXPORT void
86 comerr(const char *msg, ...)
87 #else
88 EXPORT void
89 comerr(msg, va_alist)
90         char    *msg;
91         va_dcl
92 #endif
93 {
94         va_list args;
95
96 #ifdef  PROTOTYPES
97         va_start(args, msg);
98 #else
99         va_start(args);
100 #endif
101         (void) _comerr(TRUE, geterrno(), msg, args);
102         /* NOTREACHED */
103         va_end(args);
104 }
105
106 /* VARARGS2 */
107 #ifdef  PROTOTYPES
108 EXPORT void
109 comerrno(int err, const char *msg, ...)
110 #else
111 EXPORT void
112 comerrno(err, msg, va_alist)
113         int     err;
114         char    *msg;
115         va_dcl
116 #endif
117 {
118         va_list args;
119
120 #ifdef  PROTOTYPES
121         va_start(args, msg);
122 #else
123         va_start(args);
124 #endif
125         (void) _comerr(TRUE, err, msg, args);
126         /* NOTREACHED */
127         va_end(args);
128 }
129
130 /* VARARGS1 */
131 #ifdef  PROTOTYPES
132 EXPORT int
133 errmsg(const char *msg, ...)
134 #else
135 EXPORT int
136 errmsg(msg, va_alist)
137         char    *msg;
138         va_dcl
139 #endif
140 {
141         va_list args;
142         int     ret;
143
144 #ifdef  PROTOTYPES
145         va_start(args, msg);
146 #else
147         va_start(args);
148 #endif
149         ret = _comerr(FALSE, geterrno(), msg, args);
150         va_end(args);
151         return (ret);
152 }
153
154 /* VARARGS2 */
155 #ifdef  PROTOTYPES
156 EXPORT int
157 errmsgno(int err, const char *msg, ...)
158 #else
159 EXPORT int
160 errmsgno(err, msg, va_alist)
161         int     err;
162         char    *msg;
163         va_dcl
164 #endif
165 {
166         va_list args;
167         int     ret;
168
169 #ifdef  PROTOTYPES
170         va_start(args, msg);
171 #else
172         va_start(args);
173 #endif
174         ret = _comerr(FALSE, err, msg, args);
175         va_end(args);
176         return (ret);
177 }
178
179 #ifdef  __BEOS__
180         /*
181          * On BeOS errno is a big negative number (0x80000000 + small number).
182          * We assume that small negative numbers are safe to be used as special
183          * values that prevent printing the errno text.
184          *
185          * We tried to use #if EIO < 0 but this does not work because EIO is
186          * defined to a enum. ENODEV may work as ENODEV is defined to a number
187          * directly.
188          */
189 #define silent_schily_error(e)          ((e) < 0 && (e) >= -1024)
190 #else
191         /*
192          * On UNIX errno is a small non-negative number, so we assume that
193          * negative values cannot be a valid errno and don't print the error
194          * string in this case. However the value may still be used as exit()
195          * code if 'exflg' is set.
196          */
197 #define silent_schily_error(e)          ((e) < 0)
198 #endif
199 LOCAL int
200 _comerr(exflg, err, msg, args)
201         int             exflg;
202         int             err;
203         const char      *msg;
204         va_list         args;
205 {
206         char    errbuf[20];
207         char    *errnam;
208         char    *prognam = get_progname();
209
210         if (silent_schily_error(err)) {
211                 fprintf(stderr, "%s: ", prognam);
212                 vfprintf(stderr, msg, args);
213         } else {
214                 errnam = errmsgstr(err);
215                 if (errnam == NULL) {
216                         (void) snprintf(errbuf, sizeof (errbuf),
217                                                 "Error %d", err);
218                         errnam = errbuf;
219                 }
220                 fprintf(stderr, "%s: %s. ", prognam, errnam);
221                 vfprintf(stderr, msg, args);
222         }
223         if (exflg) {
224                 comexit(err);
225                 /* NOTREACHED */
226         }
227         return (err);
228 }
229
230 EXPORT void
231 comexit(err)
232         int     err;
233 {
234         while (exfuncs) {
235                 (*exfuncs->func)(err, exfuncs->arg);
236                 exfuncs = exfuncs->next;
237         }
238         exit(err);
239         /* NOTREACHED */
240 }
241
242 EXPORT char *
243 errmsgstr(err)
244         int     err;
245 {
246 #ifdef  HAVE_STRERROR
247         /*
248          * POSIX compliance may look strange...
249          */
250         int     errsav = geterrno();
251         char    *ret;
252
253         seterrno(0);
254         ret = strerror(err);
255         err = geterrno();
256         seterrno(errsav);
257
258         if (ret == NULL || err)
259                 return (NULL);
260         return (ret);
261 #else
262         if (err < 0 || err >= sys_nerr) {
263                 return (NULL);
264         } else {
265                 return (sys_errlist[err]);
266         }
267 #endif
268 }