~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjlib/src/pj/errno.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: errno.c 3664 2011-07-19 03:42:28Z nanang $ */
2
 
/*
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 */
20
 
#include <pj/errno.h>
21
 
#include <pj/log.h>
22
 
#include <pj/string.h>
23
 
#include <pj/compat/string.h>
24
 
#include <pj/compat/stdarg.h>
25
 
#include <pj/assert.h>
26
 
 
27
 
/* Prototype for platform specific error message, which will be defined
28
 
 * in separate file.
29
 
 */
30
 
PJ_BEGIN_DECL
31
 
 
32
 
    PJ_DECL(int) platform_strerror(pj_os_err_type code,
33
 
                                   char *buf, pj_size_t bufsize );
34
 
PJ_END_DECL
35
 
 
36
 
#ifndef PJLIB_MAX_ERR_MSG_HANDLER
37
 
#       define PJLIB_MAX_ERR_MSG_HANDLER   10
38
 
#endif
39
 
 
40
 
/* Error message handler. */
41
 
static unsigned err_msg_hnd_cnt;
42
 
static struct err_msg_hnd
43
 
{
44
 
    pj_status_t     begin;
45
 
    pj_status_t     end;
46
 
    pj_str_t      (*strerror)(pj_status_t, char*, pj_size_t);
47
 
 
48
 
} err_msg_hnd[PJLIB_MAX_ERR_MSG_HANDLER];
49
 
 
50
 
/* PJLIB's own error codes/messages */
51
 
#if defined(PJ_HAS_ERROR_STRING) && PJ_HAS_ERROR_STRING!=0
52
 
 
53
 
static const struct
54
 
{
55
 
    int code;
56
 
    const char *msg;
57
 
} err_str[] =
58
 
{
59
 
    PJ_BUILD_ERR(PJ_EUNKNOWN,      "Unknown Error" ),
60
 
    PJ_BUILD_ERR(PJ_EPENDING,      "Pending operation" ),
61
 
    PJ_BUILD_ERR(PJ_ETOOMANYCONN,  "Too many connecting sockets" ),
62
 
    PJ_BUILD_ERR(PJ_EINVAL,        "Invalid value or argument" ),
63
 
    PJ_BUILD_ERR(PJ_ENAMETOOLONG,  "Name too long" ),
64
 
    PJ_BUILD_ERR(PJ_ENOTFOUND,     "Not found" ),
65
 
    PJ_BUILD_ERR(PJ_ENOMEM,        "Not enough memory" ),
66
 
    PJ_BUILD_ERR(PJ_EBUG,          "BUG DETECTED!" ),
67
 
    PJ_BUILD_ERR(PJ_ETIMEDOUT,     "Operation timed out" ),
68
 
    PJ_BUILD_ERR(PJ_ETOOMANY,      "Too many objects of the specified type"),
69
 
    PJ_BUILD_ERR(PJ_EBUSY,         "Object is busy"),
70
 
    PJ_BUILD_ERR(PJ_ENOTSUP,       "Option/operation is not supported"),
71
 
    PJ_BUILD_ERR(PJ_EINVALIDOP,    "Invalid operation"),
72
 
    PJ_BUILD_ERR(PJ_ECANCELLED,    "Operation cancelled"),
73
 
    PJ_BUILD_ERR(PJ_EEXISTS,       "Object already exists" ),
74
 
    PJ_BUILD_ERR(PJ_EEOF,          "End of file" ),
75
 
    PJ_BUILD_ERR(PJ_ETOOBIG,       "Size is too big"),
76
 
    PJ_BUILD_ERR(PJ_ERESOLVE,      "gethostbyname() has returned error"),
77
 
    PJ_BUILD_ERR(PJ_ETOOSMALL,     "Size is too short"),
78
 
    PJ_BUILD_ERR(PJ_EIGNORED,      "Ignored"),
79
 
    PJ_BUILD_ERR(PJ_EIPV6NOTSUP,   "IPv6 is not supported"),
80
 
    PJ_BUILD_ERR(PJ_EAFNOTSUP,     "Unsupported address family")
81
 
};
82
 
#endif  /* PJ_HAS_ERROR_STRING */
83
 
 
84
 
 
85
 
/*
86
 
 * pjlib_error()
87
 
 *
88
 
 * Retrieve message string for PJLIB's own error code.
89
 
 */
90
 
static int pjlib_error(pj_status_t code, char *buf, pj_size_t size)
91
 
{
92
 
#if defined(PJ_HAS_ERROR_STRING) && PJ_HAS_ERROR_STRING!=0
93
 
    unsigned i;
94
 
 
95
 
    for (i=0; i<sizeof(err_str)/sizeof(err_str[0]); ++i) {
96
 
        if (err_str[i].code == code) {
97
 
            pj_size_t len = strlen(err_str[i].msg);
98
 
            if (len >= size) len = size-1;
99
 
            pj_memcpy(buf, err_str[i].msg, len);
100
 
            buf[len] = '\0';
101
 
            return len;
102
 
        }
103
 
    }
104
 
#endif
105
 
 
106
 
    return pj_ansi_snprintf( buf, size, "Unknown pjlib error %d", code);
107
 
}
108
 
 
109
 
#define IN_RANGE(val,start,end)     ((val)>=(start) && (val)<(end))
110
 
 
111
 
/* Register strerror handle. */
112
 
PJ_DEF(pj_status_t) pj_register_strerror( pj_status_t start,
113
 
                                          pj_status_t space,
114
 
                                          pj_error_callback f)
115
 
{
116
 
    unsigned i;
117
 
 
118
 
    /* Check arguments. */
119
 
    PJ_ASSERT_RETURN(start && space && f, PJ_EINVAL);
120
 
 
121
 
    /* Check if there aren't too many handlers registered. */
122
 
    PJ_ASSERT_RETURN(err_msg_hnd_cnt < PJ_ARRAY_SIZE(err_msg_hnd),
123
 
                     PJ_ETOOMANY);
124
 
 
125
 
    /* Start error must be greater than PJ_ERRNO_START_USER */
126
 
    PJ_ASSERT_RETURN(start >= PJ_ERRNO_START_USER, PJ_EEXISTS);
127
 
 
128
 
    /* Check that no existing handler has covered the specified range. */
129
 
    for (i=0; i<err_msg_hnd_cnt; ++i) {
130
 
        if (IN_RANGE(start, err_msg_hnd[i].begin, err_msg_hnd[i].end) ||
131
 
            IN_RANGE(start+space-1, err_msg_hnd[i].begin, err_msg_hnd[i].end))
132
 
        {
133
 
            if (err_msg_hnd[i].begin == start &&
134
 
                err_msg_hnd[i].end == (start+space) &&
135
 
                err_msg_hnd[i].strerror == f)
136
 
            {
137
 
                /* The same range and handler has already been registered */
138
 
                return PJ_SUCCESS;
139
 
            }
140
 
 
141
 
            return PJ_EEXISTS;
142
 
        }
143
 
    }
144
 
 
145
 
    /* Register the handler. */
146
 
    err_msg_hnd[err_msg_hnd_cnt].begin = start;
147
 
    err_msg_hnd[err_msg_hnd_cnt].end = start + space;
148
 
    err_msg_hnd[err_msg_hnd_cnt].strerror = f;
149
 
 
150
 
    ++err_msg_hnd_cnt;
151
 
 
152
 
    return PJ_SUCCESS;
153
 
}
154
 
 
155
 
/* Internal PJLIB function called by pj_shutdown() to clear error handlers */
156
 
void pj_errno_clear_handlers(void)
157
 
{
158
 
    err_msg_hnd_cnt = 0;
159
 
    pj_bzero(err_msg_hnd, sizeof(err_msg_hnd));
160
 
}
161
 
 
162
 
 
163
 
/*
164
 
 * pj_strerror()
165
 
 */
166
 
PJ_DEF(pj_str_t) pj_strerror( pj_status_t statcode,
167
 
                              char *buf, pj_size_t bufsize )
168
 
{
169
 
    int len = -1;
170
 
    pj_str_t errstr;
171
 
 
172
 
    pj_assert(buf && bufsize);
173
 
 
174
 
    if (statcode == PJ_SUCCESS) {
175
 
        len = pj_ansi_snprintf( buf, bufsize, "Success");
176
 
 
177
 
    } else if (statcode < PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE) {
178
 
        len = pj_ansi_snprintf( buf, bufsize, "Unknown error %d", statcode);
179
 
 
180
 
    } else if (statcode < PJ_ERRNO_START_STATUS + PJ_ERRNO_SPACE_SIZE) {
181
 
        len = pjlib_error(statcode, buf, bufsize);
182
 
 
183
 
    } else if (statcode < PJ_ERRNO_START_SYS + PJ_ERRNO_SPACE_SIZE) {
184
 
        len = platform_strerror(PJ_STATUS_TO_OS(statcode), buf, bufsize);
185
 
 
186
 
    } else {
187
 
        unsigned i;
188
 
 
189
 
        /* Find user handler to get the error message. */
190
 
        for (i=0; i<err_msg_hnd_cnt; ++i) {
191
 
            if (IN_RANGE(statcode, err_msg_hnd[i].begin, err_msg_hnd[i].end)) {
192
 
                return (*err_msg_hnd[i].strerror)(statcode, buf, bufsize);
193
 
            }
194
 
        }
195
 
 
196
 
        /* Handler not found! */
197
 
        len = pj_ansi_snprintf( buf, bufsize, "Unknown error %d", statcode);
198
 
    }
199
 
 
200
 
    if (len < 1) {
201
 
        *buf = '\0';
202
 
        len = 0;
203
 
    }
204
 
 
205
 
    errstr.ptr = buf;
206
 
    errstr.slen = len;
207
 
 
208
 
    return errstr;
209
 
}
210
 
 
211
 
#if PJ_LOG_MAX_LEVEL >= 1
212
 
static void invoke_log(const char *sender, int level, const char *format, ...)
213
 
{
214
 
    va_list arg;
215
 
    va_start(arg, format);
216
 
    pj_log(sender, level, format, arg);
217
 
    va_end(arg);
218
 
}
219
 
 
220
 
static void pj_perror_imp(int log_level, const char *sender,
221
 
                          pj_status_t status,
222
 
                          const char *title_fmt, va_list marker)
223
 
{
224
 
    char titlebuf[PJ_PERROR_TITLE_BUF_SIZE];
225
 
    char errmsg[PJ_ERR_MSG_SIZE];
226
 
    int len;
227
 
 
228
 
    /* Build the title */
229
 
    len = pj_ansi_vsnprintf(titlebuf, sizeof(titlebuf), title_fmt, marker);
230
 
    if (len < 0 || len >= (int)sizeof(titlebuf))
231
 
        pj_ansi_strcpy(titlebuf, "Error");
232
 
 
233
 
    /* Get the error */
234
 
    pj_strerror(status, errmsg, sizeof(errmsg));
235
 
 
236
 
    /* Send to log */
237
 
    invoke_log(sender, log_level, "%s: %s", titlebuf, errmsg);
238
 
}
239
 
 
240
 
PJ_DEF(void) pj_perror(int log_level, const char *sender, pj_status_t status,
241
 
                       const char *title_fmt, ...)
242
 
{
243
 
    va_list marker;
244
 
    va_start(marker, title_fmt);
245
 
    pj_perror_imp(log_level, sender, status, title_fmt, marker);
246
 
    va_end(marker);
247
 
}
248
 
 
249
 
PJ_DEF(void) pj_perror_1(const char *sender, pj_status_t status,
250
 
                         const char *title_fmt, ...)
251
 
{
252
 
    va_list marker;
253
 
    va_start(marker, title_fmt);
254
 
    pj_perror_imp(1, sender, status, title_fmt, marker);
255
 
    va_end(marker);
256
 
}
257
 
 
258
 
#else /* #if PJ_LOG_MAX_LEVEL >= 1 */
259
 
PJ_DEF(void) pj_perror(int log_level, const char *sender, pj_status_t status,
260
 
                       const char *title_fmt, ...)
261
 
{
262
 
}
263
 
#endif  /* #if PJ_LOG_MAX_LEVEL >= 1 */
264
 
 
265
 
 
266
 
#if PJ_LOG_MAX_LEVEL >= 2
267
 
PJ_DEF(void) pj_perror_2(const char *sender, pj_status_t status,
268
 
                         const char *title_fmt, ...)
269
 
{
270
 
    va_list marker;
271
 
    va_start(marker, title_fmt);
272
 
    pj_perror_imp(2, sender, status, title_fmt, marker);
273
 
    va_end(marker);
274
 
}
275
 
#endif
276
 
 
277
 
#if PJ_LOG_MAX_LEVEL >= 3
278
 
PJ_DEF(void) pj_perror_3(const char *sender, pj_status_t status,
279
 
                         const char *title_fmt, ...)
280
 
{
281
 
    va_list marker;
282
 
    va_start(marker, title_fmt);
283
 
    pj_perror_imp(3, sender, status, title_fmt, marker);
284
 
    va_end(marker);
285
 
}
286
 
#endif
287
 
 
288
 
#if PJ_LOG_MAX_LEVEL >= 4
289
 
PJ_DEF(void) pj_perror_4(const char *sender, pj_status_t status,
290
 
                         const char *title_fmt, ...)
291
 
{
292
 
    va_list marker;
293
 
    va_start(marker, title_fmt);
294
 
    pj_perror_imp(4, sender, status, title_fmt, marker);
295
 
    va_end(marker);
296
 
}
297
 
#endif
298
 
 
299
 
#if PJ_LOG_MAX_LEVEL >= 5
300
 
PJ_DEF(void) pj_perror_5(const char *sender, pj_status_t status,
301
 
                         const char *title_fmt, ...)
302
 
{
303
 
    va_list marker;
304
 
    va_start(marker, title_fmt);
305
 
    pj_perror_imp(5, sender, status, title_fmt, marker);
306
 
    va_end(marker);
307
 
}
308
 
#endif
309
 
 
310
 
#if PJ_LOG_MAX_LEVEL >= 6
311
 
PJ_DEF(void) pj_perror_6(const char *sender, pj_status_t status,
312
 
                         const char *title_fmt, ...)
313
 
{
314
 
    va_list marker;
315
 
    va_start(marker, title_fmt);
316
 
    pj_perror_imp(6, sender, status, title_fmt, marker);
317
 
    va_end(marker);
318
 
}
319
 
#endif