Review Board 1.7.16


Use the correct lower bound for saturated arithmetic

Review Request #2479 - Created April 29, 2013 and submitted

Sean Bright
1.8
Reviewers
asterisk-dev
Asterisk
The current ast_slinear_saturated_* functions use a lower bound of -32767, where they should be using -32768.  I'm only posting the review in case I am missing something obvious.
Compilation and ran a few calls through ConfBridge

Diff revision 1 (Latest)

  1. /branches/1.8/include/asterisk/utils.h: Loading...
/branches/1.8/include/asterisk/utils.h
Revision 386841 New Change
1
/*
1
/*
2
 * Asterisk -- An open source telephony toolkit.
2
 * Asterisk -- An open source telephony toolkit.
3
 *
3
 *
4
 * Copyright (C) 1999 - 2006, Digium, Inc.
4
 * Copyright (C) 1999 - 2006, Digium, Inc.
5
 *
5
 *
6
 * Mark Spencer <markster@digium.com>
6
 * Mark Spencer <markster@digium.com>
7
 *
7
 *
8
 * See http://www.asterisk.org for more information about
8
 * See http://www.asterisk.org for more information about
9
 * the Asterisk project. Please do not directly contact
9
 * the Asterisk project. Please do not directly contact
10
 * any of the maintainers of this project for assistance;
10
 * any of the maintainers of this project for assistance;
11
 * the project provides a web site, mailing lists and IRC
11
 * the project provides a web site, mailing lists and IRC
12
 * channels for your use.
12
 * channels for your use.
13
 *
13
 *
14
 * This program is free software, distributed under the terms of
14
 * This program is free software, distributed under the terms of
15
 * the GNU General Public License Version 2. See the LICENSE file
15
 * the GNU General Public License Version 2. See the LICENSE file
16
 * at the top of the source tree.
16
 * at the top of the source tree.
17
 */
17
 */
18

    
   
18

   
19
/*! \file
19
/*! \file
20
 * \brief Utility functions
20
 * \brief Utility functions
21
 */
21
 */
22

    
   
22

   
23
#ifndef _ASTERISK_UTILS_H
23
#ifndef _ASTERISK_UTILS_H
24
#define _ASTERISK_UTILS_H
24
#define _ASTERISK_UTILS_H
25

    
   
25

   
26
#include "asterisk/network.h"
26
#include "asterisk/network.h"
27

    
   
27

   
28
#include <time.h>	/* we want to override localtime_r */
28
#include <time.h>	/* we want to override localtime_r */
29
#include <unistd.h>
29
#include <unistd.h>
30
#include <string.h>
30
#include <string.h>
31

    
   
31

   
32
#include "asterisk/lock.h"
32
#include "asterisk/lock.h"
33
#include "asterisk/time.h"
33
#include "asterisk/time.h"
34
#include "asterisk/logger.h"
34
#include "asterisk/logger.h"
35
#include "asterisk/localtime.h"
35
#include "asterisk/localtime.h"
36
#include "asterisk/stringfields.h"
36
#include "asterisk/stringfields.h"
37

    
   
37

   
38
/*!
38
/*!
39
\note \verbatim
39
\note \verbatim
40
   Note:
40
   Note:
41
   It is very important to use only unsigned variables to hold
41
   It is very important to use only unsigned variables to hold
42
   bit flags, as otherwise you can fall prey to the compiler's
42
   bit flags, as otherwise you can fall prey to the compiler's
43
   sign-extension antics if you try to use the top two bits in
43
   sign-extension antics if you try to use the top two bits in
44
   your variable.
44
   your variable.
45

    
   
45

   
46
   The flag macros below use a set of compiler tricks to verify
46
   The flag macros below use a set of compiler tricks to verify
47
   that the caller is using an "unsigned int" variable to hold
47
   that the caller is using an "unsigned int" variable to hold
48
   the flags, and nothing else. If the caller uses any other
48
   the flags, and nothing else. If the caller uses any other
49
   type of variable, a warning message similar to this:
49
   type of variable, a warning message similar to this:
50

    
   
50

   
51
   warning: comparison of distinct pointer types lacks cast
51
   warning: comparison of distinct pointer types lacks cast
52
   will be generated.
52
   will be generated.
53

    
   
53

   
54
   The "dummy" variable below is used to make these comparisons.
54
   The "dummy" variable below is used to make these comparisons.
55

    
   
55

   
56
   Also note that at -O2 or above, this type-safety checking
56
   Also note that at -O2 or above, this type-safety checking
57
   does _not_ produce any additional object code at all.
57
   does _not_ produce any additional object code at all.
58
 \endverbatim
58
 \endverbatim
59
*/
59
*/
60

    
   
60

   
61
extern unsigned int __unsigned_int_flags_dummy;
61
extern unsigned int __unsigned_int_flags_dummy;
62

    
   
62

   
63
#define ast_test_flag(p,flag) 		({ \
63
#define ast_test_flag(p,flag) 		({ \
64
					typeof ((p)->flags) __p = (p)->flags; \
64
					typeof ((p)->flags) __p = (p)->flags; \
65
					typeof (__unsigned_int_flags_dummy) __x = 0; \
65
					typeof (__unsigned_int_flags_dummy) __x = 0; \
66
					(void) (&__p == &__x); \
66
					(void) (&__p == &__x); \
67
					((p)->flags & (flag)); \
67
					((p)->flags & (flag)); \
68
					})
68
					})
69

    
   
69

   
70
#define ast_set_flag(p,flag) 		do { \
70
#define ast_set_flag(p,flag) 		do { \
71
					typeof ((p)->flags) __p = (p)->flags; \
71
					typeof ((p)->flags) __p = (p)->flags; \
72
					typeof (__unsigned_int_flags_dummy) __x = 0; \
72
					typeof (__unsigned_int_flags_dummy) __x = 0; \
73
					(void) (&__p == &__x); \
73
					(void) (&__p == &__x); \
74
					((p)->flags |= (flag)); \
74
					((p)->flags |= (flag)); \
75
					} while(0)
75
					} while(0)
76

    
   
76

   
77
#define ast_clear_flag(p,flag) 		do { \
77
#define ast_clear_flag(p,flag) 		do { \
78
					typeof ((p)->flags) __p = (p)->flags; \
78
					typeof ((p)->flags) __p = (p)->flags; \
79
					typeof (__unsigned_int_flags_dummy) __x = 0; \
79
					typeof (__unsigned_int_flags_dummy) __x = 0; \
80
					(void) (&__p == &__x); \
80
					(void) (&__p == &__x); \
81
					((p)->flags &= ~(flag)); \
81
					((p)->flags &= ~(flag)); \
82
					} while(0)
82
					} while(0)
83

    
   
83

   
84
#define ast_copy_flags(dest,src,flagz)	do { \
84
#define ast_copy_flags(dest,src,flagz)	do { \
85
					typeof ((dest)->flags) __d = (dest)->flags; \
85
					typeof ((dest)->flags) __d = (dest)->flags; \
86
					typeof ((src)->flags) __s = (src)->flags; \
86
					typeof ((src)->flags) __s = (src)->flags; \
87
					typeof (__unsigned_int_flags_dummy) __x = 0; \
87
					typeof (__unsigned_int_flags_dummy) __x = 0; \
88
					(void) (&__d == &__x); \
88
					(void) (&__d == &__x); \
89
					(void) (&__s == &__x); \
89
					(void) (&__s == &__x); \
90
					(dest)->flags &= ~(flagz); \
90
					(dest)->flags &= ~(flagz); \
91
					(dest)->flags |= ((src)->flags & (flagz)); \
91
					(dest)->flags |= ((src)->flags & (flagz)); \
92
					} while (0)
92
					} while (0)
93

    
   
93

   
94
#define ast_set2_flag(p,value,flag)	do { \
94
#define ast_set2_flag(p,value,flag)	do { \
95
					typeof ((p)->flags) __p = (p)->flags; \
95
					typeof ((p)->flags) __p = (p)->flags; \
96
					typeof (__unsigned_int_flags_dummy) __x = 0; \
96
					typeof (__unsigned_int_flags_dummy) __x = 0; \
97
					(void) (&__p == &__x); \
97
					(void) (&__p == &__x); \
98
					if (value) \
98
					if (value) \
99
						(p)->flags |= (flag); \
99
						(p)->flags |= (flag); \
100
					else \
100
					else \
101
						(p)->flags &= ~(flag); \
101
						(p)->flags &= ~(flag); \
102
					} while (0)
102
					} while (0)
103

    
   
103

   
104
#define ast_set_flags_to(p,flag,value)	do { \
104
#define ast_set_flags_to(p,flag,value)	do { \
105
					typeof ((p)->flags) __p = (p)->flags; \
105
					typeof ((p)->flags) __p = (p)->flags; \
106
					typeof (__unsigned_int_flags_dummy) __x = 0; \
106
					typeof (__unsigned_int_flags_dummy) __x = 0; \
107
					(void) (&__p == &__x); \
107
					(void) (&__p == &__x); \
108
					(p)->flags &= ~(flag); \
108
					(p)->flags &= ~(flag); \
109
					(p)->flags |= (value); \
109
					(p)->flags |= (value); \
110
					} while (0)
110
					} while (0)
111

    
   
111

   
112

    
   
112

   
113
/* The following 64-bit flag code can most likely be erased after app_dial
113
/* The following 64-bit flag code can most likely be erased after app_dial
114
   is reorganized to either reduce the large number of options, or handle
114
   is reorganized to either reduce the large number of options, or handle
115
   them in some other way. At the time of this writing, app_dial would be
115
   them in some other way. At the time of this writing, app_dial would be
116
   the only user of 64-bit option flags */
116
   the only user of 64-bit option flags */
117

    
   
117

   
118
extern uint64_t __unsigned_int_flags_dummy64;
118
extern uint64_t __unsigned_int_flags_dummy64;
119

    
   
119

   
120
#define ast_test_flag64(p,flag) 		({ \
120
#define ast_test_flag64(p,flag) 		({ \
121
					typeof ((p)->flags) __p = (p)->flags; \
121
					typeof ((p)->flags) __p = (p)->flags; \
122
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
122
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
123
					(void) (&__p == &__x); \
123
					(void) (&__p == &__x); \
124
					((p)->flags & (flag)); \
124
					((p)->flags & (flag)); \
125
					})
125
					})
126

    
   
126

   
127
#define ast_set_flag64(p,flag) 		do { \
127
#define ast_set_flag64(p,flag) 		do { \
128
					typeof ((p)->flags) __p = (p)->flags; \
128
					typeof ((p)->flags) __p = (p)->flags; \
129
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
129
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
130
					(void) (&__p == &__x); \
130
					(void) (&__p == &__x); \
131
					((p)->flags |= (flag)); \
131
					((p)->flags |= (flag)); \
132
					} while(0)
132
					} while(0)
133

    
   
133

   
134
#define ast_clear_flag64(p,flag) 		do { \
134
#define ast_clear_flag64(p,flag) 		do { \
135
					typeof ((p)->flags) __p = (p)->flags; \
135
					typeof ((p)->flags) __p = (p)->flags; \
136
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
136
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
137
					(void) (&__p == &__x); \
137
					(void) (&__p == &__x); \
138
					((p)->flags &= ~(flag)); \
138
					((p)->flags &= ~(flag)); \
139
					} while(0)
139
					} while(0)
140

    
   
140

   
141
#define ast_copy_flags64(dest,src,flagz)	do { \
141
#define ast_copy_flags64(dest,src,flagz)	do { \
142
					typeof ((dest)->flags) __d = (dest)->flags; \
142
					typeof ((dest)->flags) __d = (dest)->flags; \
143
					typeof ((src)->flags) __s = (src)->flags; \
143
					typeof ((src)->flags) __s = (src)->flags; \
144
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
144
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
145
					(void) (&__d == &__x); \
145
					(void) (&__d == &__x); \
146
					(void) (&__s == &__x); \
146
					(void) (&__s == &__x); \
147
					(dest)->flags &= ~(flagz); \
147
					(dest)->flags &= ~(flagz); \
148
					(dest)->flags |= ((src)->flags & (flagz)); \
148
					(dest)->flags |= ((src)->flags & (flagz)); \
149
					} while (0)
149
					} while (0)
150

    
   
150

   
151
#define ast_set2_flag64(p,value,flag)	do { \
151
#define ast_set2_flag64(p,value,flag)	do { \
152
					typeof ((p)->flags) __p = (p)->flags; \
152
					typeof ((p)->flags) __p = (p)->flags; \
153
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
153
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
154
					(void) (&__p == &__x); \
154
					(void) (&__p == &__x); \
155
					if (value) \
155
					if (value) \
156
						(p)->flags |= (flag); \
156
						(p)->flags |= (flag); \
157
					else \
157
					else \
158
						(p)->flags &= ~(flag); \
158
						(p)->flags &= ~(flag); \
159
					} while (0)
159
					} while (0)
160

    
   
160

   
161
#define ast_set_flags_to64(p,flag,value)	do { \
161
#define ast_set_flags_to64(p,flag,value)	do { \
162
					typeof ((p)->flags) __p = (p)->flags; \
162
					typeof ((p)->flags) __p = (p)->flags; \
163
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
163
					typeof (__unsigned_int_flags_dummy64) __x = 0; \
164
					(void) (&__p == &__x); \
164
					(void) (&__p == &__x); \
165
					(p)->flags &= ~(flag); \
165
					(p)->flags &= ~(flag); \
166
					(p)->flags |= (value); \
166
					(p)->flags |= (value); \
167
					} while (0)
167
					} while (0)
168

    
   
168

   
169

    
   
169

   
170
/* Non-type checking variations for non-unsigned int flags.  You
170
/* Non-type checking variations for non-unsigned int flags.  You
171
   should only use non-unsigned int flags where required by 
171
   should only use non-unsigned int flags where required by 
172
   protocol etc and if you know what you're doing :)  */
172
   protocol etc and if you know what you're doing :)  */
173
#define ast_test_flag_nonstd(p,flag) \
173
#define ast_test_flag_nonstd(p,flag) \
174
					((p)->flags & (flag))
174
					((p)->flags & (flag))
175

    
   
175

   
176
#define ast_set_flag_nonstd(p,flag) 		do { \
176
#define ast_set_flag_nonstd(p,flag) 		do { \
177
					((p)->flags |= (flag)); \
177
					((p)->flags |= (flag)); \
178
					} while(0)
178
					} while(0)
179

    
   
179

   
180
#define ast_clear_flag_nonstd(p,flag) 		do { \
180
#define ast_clear_flag_nonstd(p,flag) 		do { \
181
					((p)->flags &= ~(flag)); \
181
					((p)->flags &= ~(flag)); \
182
					} while(0)
182
					} while(0)
183

    
   
183

   
184
#define ast_copy_flags_nonstd(dest,src,flagz)	do { \
184
#define ast_copy_flags_nonstd(dest,src,flagz)	do { \
185
					(dest)->flags &= ~(flagz); \
185
					(dest)->flags &= ~(flagz); \
186
					(dest)->flags |= ((src)->flags & (flagz)); \
186
					(dest)->flags |= ((src)->flags & (flagz)); \
187
					} while (0)
187
					} while (0)
188

    
   
188

   
189
#define ast_set2_flag_nonstd(p,value,flag)	do { \
189
#define ast_set2_flag_nonstd(p,value,flag)	do { \
190
					if (value) \
190
					if (value) \
191
						(p)->flags |= (flag); \
191
						(p)->flags |= (flag); \
192
					else \
192
					else \
193
						(p)->flags &= ~(flag); \
193
						(p)->flags &= ~(flag); \
194
					} while (0)
194
					} while (0)
195

    
   
195

   
196
#define AST_FLAGS_ALL UINT_MAX
196
#define AST_FLAGS_ALL UINT_MAX
197

    
   
197

   
198
/*! \brief Structure used to handle boolean flags 
198
/*! \brief Structure used to handle boolean flags 
199
*/
199
*/
200
struct ast_flags {
200
struct ast_flags {
201
	unsigned int flags;
201
	unsigned int flags;
202
};
202
};
203

    
   
203

   
204
/*! \brief Structure used to handle a large number of boolean flags == used only in app_dial?
204
/*! \brief Structure used to handle a large number of boolean flags == used only in app_dial?
205
*/
205
*/
206
struct ast_flags64 {
206
struct ast_flags64 {
207
	uint64_t flags;
207
	uint64_t flags;
208
};
208
};
209

    
   
209

   
210
struct ast_hostent {
210
struct ast_hostent {
211
	struct hostent hp;
211
	struct hostent hp;
212
	char buf[1024];
212
	char buf[1024];
213
};
213
};
214

    
   
214

   
215
/*! \brief Thread-safe gethostbyname function to use in Asterisk */
215
/*! \brief Thread-safe gethostbyname function to use in Asterisk */
216
struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
216
struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
217

    
   
217

   
218
/*!  \brief Produces MD5 hash based on input string */
218
/*!  \brief Produces MD5 hash based on input string */
219
void ast_md5_hash(char *output, const char *input);
219
void ast_md5_hash(char *output, const char *input);
220
/*! \brief Produces SHA1 hash based on input string */
220
/*! \brief Produces SHA1 hash based on input string */
221
void ast_sha1_hash(char *output, const char *input);
221
void ast_sha1_hash(char *output, const char *input);
222

    
   
222

   
223
int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
223
int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
224

    
   
224

   
225
#undef MIN
225
#undef MIN
226
#define MIN(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a > __b) ? __b : __a);})
226
#define MIN(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a > __b) ? __b : __a);})
227
#undef MAX
227
#undef MAX
228
#define MAX(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a < __b) ? __b : __a);})
228
#define MAX(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a < __b) ? __b : __a);})
229

    
   
229

   
230
/*!
230
/*!
231
 * \brief Encode data in base64
231
 * \brief Encode data in base64
232
 * \param dst the destination buffer
232
 * \param dst the destination buffer
233
 * \param src the source data to be encoded
233
 * \param src the source data to be encoded
234
 * \param srclen the number of bytes present in the source buffer
234
 * \param srclen the number of bytes present in the source buffer
235
 * \param max the maximum number of bytes to write into the destination
235
 * \param max the maximum number of bytes to write into the destination
236
 *        buffer, *including* the terminating NULL character.
236
 *        buffer, *including* the terminating NULL character.
237
 */
237
 */
238
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
238
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
239

    
   
239

   
240
/*!
240
/*!
241
 * \brief Decode data from base64
241
 * \brief Decode data from base64
242
 * \param dst the destination buffer
242
 * \param dst the destination buffer
243
 * \param src the source buffer
243
 * \param src the source buffer
244
 * \param max The maximum number of bytes to write into the destination
244
 * \param max The maximum number of bytes to write into the destination
245
 *            buffer.  Note that this function will not ensure that the
245
 *            buffer.  Note that this function will not ensure that the
246
 *            destination buffer is NULL terminated.  So, in general,
246
 *            destination buffer is NULL terminated.  So, in general,
247
 *            this parameter should be sizeof(dst) - 1.
247
 *            this parameter should be sizeof(dst) - 1.
248
 */
248
 */
249
int ast_base64decode(unsigned char *dst, const char *src, int max);
249
int ast_base64decode(unsigned char *dst, const char *src, int max);
250

    
   
250

   
251
/*! \brief Turn text string to URI-encoded %XX version
251
/*! \brief Turn text string to URI-encoded %XX version
252
 *
252
 *
253
 * \note
253
 * \note
254
 *  At this point, this function is encoding agnostic; it does not
254
 *  At this point, this function is encoding agnostic; it does not
255
 *  check whether it is fed legal UTF-8. We escape control
255
 *  check whether it is fed legal UTF-8. We escape control
256
 *  characters (\x00-\x1F\x7F), '%', and all characters above 0x7F.
256
 *  characters (\x00-\x1F\x7F), '%', and all characters above 0x7F.
257
 *  If do_special_char == 1 we will convert all characters except alnum
257
 *  If do_special_char == 1 we will convert all characters except alnum
258
 *  and the mark set.
258
 *  and the mark set.
259
 *  Outbuf needs to have more memory allocated than the instring
259
 *  Outbuf needs to have more memory allocated than the instring
260
 *  to have room for the expansion. Every char that is converted
260
 *  to have room for the expansion. Every char that is converted
261
 *  is replaced by three ASCII characters.
261
 *  is replaced by three ASCII characters.
262
 *
262
 *
263
 *  \param string	String to be converted
263
 *  \param string	String to be converted
264
 *  \param outbuf	Resulting encoded string
264
 *  \param outbuf	Resulting encoded string
265
 *  \param buflen	Size of output buffer
265
 *  \param buflen	Size of output buffer
266
 *  \param do_special_char	Convert all non alphanum characters execept
266
 *  \param do_special_char	Convert all non alphanum characters execept
267
 *         those in the mark set as defined by rfc 3261 section 25.1
267
 *         those in the mark set as defined by rfc 3261 section 25.1
268
 */
268
 */
269
char *ast_uri_encode(const char *string, char *outbuf, int buflen, int do_special_char);
269
char *ast_uri_encode(const char *string, char *outbuf, int buflen, int do_special_char);
270

    
   
270

   
271
/*!	\brief Decode URI, URN, URL (overwrite string)
271
/*!	\brief Decode URI, URN, URL (overwrite string)
272
	\param s	String to be decoded
272
	\param s	String to be decoded
273
 */
273
 */
274
void ast_uri_decode(char *s);
274
void ast_uri_decode(char *s);
275

    
   
275

   
276
/*! ast_xml_escape
276
/*! ast_xml_escape
277
	\brief Escape reserved characters for use in XML.
277
	\brief Escape reserved characters for use in XML.
278

    
   
278

   
279
	If \a outbuf is too short, the output string will be truncated.
279
	If \a outbuf is too short, the output string will be truncated.
280
	Regardless, the output will always be null terminated.
280
	Regardless, the output will always be null terminated.
281

    
   
281

   
282
	\param string String to be converted
282
	\param string String to be converted
283
	\param outbuf Resulting encoded string
283
	\param outbuf Resulting encoded string
284
	\param buflen Size of output buffer
284
	\param buflen Size of output buffer
285
	\return 0 for success
285
	\return 0 for success
286
	\return -1 if buflen is too short.
286
	\return -1 if buflen is too short.
287
 */
287
 */
288
int ast_xml_escape(const char *string, char *outbuf, size_t buflen);
288
int ast_xml_escape(const char *string, char *outbuf, size_t buflen);
289

    
   
289

   
290
/*!
290
/*!
291
 * \brief Escape characters found in a quoted string.
291
 * \brief Escape characters found in a quoted string.
292
 *
292
 *
293
 * \note This function escapes quoted characters based on the 'qdtext' set of
293
 * \note This function escapes quoted characters based on the 'qdtext' set of
294
 * allowed characters from RFC 3261 section 25.1.
294
 * allowed characters from RFC 3261 section 25.1.
295
 *
295
 *
296
 * \param string string to be escaped
296
 * \param string string to be escaped
297
 * \param outbuf resulting escaped string
297
 * \param outbuf resulting escaped string
298
 * \param buflen size of output buffer
298
 * \param buflen size of output buffer
299
 * \return a pointer to the escaped string
299
 * \return a pointer to the escaped string
300
 */
300
 */
301
char *ast_escape_quoted(const char *string, char *outbuf, int buflen);
301
char *ast_escape_quoted(const char *string, char *outbuf, int buflen);
302

    
   
302

   
303
static force_inline void ast_slinear_saturated_add(short *input, short *value)
303
static force_inline void ast_slinear_saturated_add(short *input, short *value)
304
{
304
{
305
	int res;
305
	int res;
306

    
   
306

   
307
	res = (int) *input + *value;
307
	res = (int) *input + *value;
308
	if (res > 32767)
308
	if (res > 32767)
309
		*input = 32767;
309
		*input = 32767;
310
	else if (res < -32767)
310
	else if (res < -32768)
311
		*input = -32767;
311
		*input = -32768;
312
	else
312
	else
313
		*input = (short) res;
313
		*input = (short) res;
314
}
314
}
315

    
   
315

   
316
static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
316
static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
317
{
317
{
318
	int res;
318
	int res;
319

    
   
319

   
320
	res = (int) *input - *value;
320
	res = (int) *input - *value;
321
	if (res > 32767)
321
	if (res > 32767)
322
		*input = 32767;
322
		*input = 32767;
323
	else if (res < -32767)
323
	else if (res < -32768)
324
		*input = -32767;
324
		*input = -32768;
325
	else
325
	else
326
		*input = (short) res;
326
		*input = (short) res;
327
}
327
}
328
	
328
	
329
static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
329
static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
330
{
330
{
331
	int res;
331
	int res;
332

    
   
332

   
333
	res = (int) *input * *value;
333
	res = (int) *input * *value;
334
	if (res > 32767)
334
	if (res > 32767)
335
		*input = 32767;
335
		*input = 32767;
336
	else if (res < -32767)
336
	else if (res < -32768)
337
		*input = -32767;
337
		*input = -32768;
338
	else
338
	else
339
		*input = (short) res;
339
		*input = (short) res;
340
}
340
}
341

    
   
341

   
342
static force_inline void ast_slinear_saturated_divide(short *input, short *value)
342
static force_inline void ast_slinear_saturated_divide(short *input, short *value)
343
{
343
{
344
	*input /= *value;
344
	*input /= *value;
345
}
345
}
346

    
   
346

   
347
#ifdef localtime_r
347
#ifdef localtime_r
348
#undef localtime_r
348
#undef localtime_r
349
#endif
349
#endif
350
#define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
350
#define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
351

    
   
351

   
352
int ast_utils_init(void);
352
int ast_utils_init(void);
353
int ast_wait_for_input(int fd, int ms);
353
int ast_wait_for_input(int fd, int ms);
354

    
   
354

   
355
/*!
355
/*!
356
	\brief Try to write string, but wait no more than ms milliseconds
356
	\brief Try to write string, but wait no more than ms milliseconds
357
	before timing out.
357
	before timing out.
358

    
   
358

   
359
	\note If you are calling ast_carefulwrite, it is assumed that you are calling
359
	\note If you are calling ast_carefulwrite, it is assumed that you are calling
360
	it on a file descriptor that _DOES_ have NONBLOCK set.  This way,
360
	it on a file descriptor that _DOES_ have NONBLOCK set.  This way,
361
	there is only one system call made to do a write, unless we actually
361
	there is only one system call made to do a write, unless we actually
362
	have a need to wait.  This way, we get better performance.
362
	have a need to wait.  This way, we get better performance.
363
*/
363
*/
364
int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
364
int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
365

    
   
365

   
366
/*!
366
/*!
367
 * \brief Write data to a file stream with a timeout
367
 * \brief Write data to a file stream with a timeout
368
 *
368
 *
369
 * \param f the file stream to write to
369
 * \param f the file stream to write to
370
 * \param fd the file description to poll on to know when the file stream can
370
 * \param fd the file description to poll on to know when the file stream can
371
 *        be written to without blocking.
371
 *        be written to without blocking.
372
 * \param s the buffer to write from
372
 * \param s the buffer to write from
373
 * \param len the number of bytes to write
373
 * \param len the number of bytes to write
374
 * \param timeoutms The maximum amount of time to block in this function trying
374
 * \param timeoutms The maximum amount of time to block in this function trying
375
 *        to write, specified in milliseconds.
375
 *        to write, specified in milliseconds.
376
 *
376
 *
377
 * \note This function assumes that the associated file stream has been set up
377
 * \note This function assumes that the associated file stream has been set up
378
 *       as non-blocking.
378
 *       as non-blocking.
379
 *
379
 *
380
 * \retval 0 success
380
 * \retval 0 success
381
 * \retval -1 error
381
 * \retval -1 error
382
 */
382
 */
383
int ast_careful_fwrite(FILE *f, int fd, const char *s, size_t len, int timeoutms);
383
int ast_careful_fwrite(FILE *f, int fd, const char *s, size_t len, int timeoutms);
384

    
   
384

   
385
/*
385
/*
386
 * Thread management support (should be moved to lock.h or a different header)
386
 * Thread management support (should be moved to lock.h or a different header)
387
 */
387
 */
388

    
   
388

   
389
#define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
389
#define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
390

    
   
390

   
391
#if defined(LOW_MEMORY)
391
#if defined(LOW_MEMORY)
392
#define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
392
#define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
393
#else
393
#else
394
#define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
394
#define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
395
#endif
395
#endif
396

    
   
396

   
397
void ast_register_thread(char *name);
397
void ast_register_thread(char *name);
398
void ast_unregister_thread(void *id);
398
void ast_unregister_thread(void *id);
399

    
   
399

   
400
int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
400
int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
401
			     void *data, size_t stacksize, const char *file, const char *caller,
401
			     void *data, size_t stacksize, const char *file, const char *caller,
402
			     int line, const char *start_fn);
402
			     int line, const char *start_fn);
403

    
   
403

   
404
int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *),
404
int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *),
405
				 void *data, size_t stacksize, const char *file, const char *caller,
405
				 void *data, size_t stacksize, const char *file, const char *caller,
406
				 int line, const char *start_fn);
406
				 int line, const char *start_fn);
407

    
   
407

   
408
#define ast_pthread_create(a, b, c, d) 				\
408
#define ast_pthread_create(a, b, c, d) 				\
409
	ast_pthread_create_stack(a, b, c, d,			\
409
	ast_pthread_create_stack(a, b, c, d,			\
410
		0, __FILE__, __FUNCTION__, __LINE__, #c)
410
		0, __FILE__, __FUNCTION__, __LINE__, #c)
411

    
   
411

   
412
#define ast_pthread_create_detached(a, b, c, d)			\
412
#define ast_pthread_create_detached(a, b, c, d)			\
413
	ast_pthread_create_detached_stack(a, b, c, d,		\
413
	ast_pthread_create_detached_stack(a, b, c, d,		\
414
		0, __FILE__, __FUNCTION__, __LINE__, #c)
414
		0, __FILE__, __FUNCTION__, __LINE__, #c)
415

    
   
415

   
416
#define ast_pthread_create_background(a, b, c, d)		\
416
#define ast_pthread_create_background(a, b, c, d)		\
417
	ast_pthread_create_stack(a, b, c, d,			\
417
	ast_pthread_create_stack(a, b, c, d,			\
418
		AST_BACKGROUND_STACKSIZE,			\
418
		AST_BACKGROUND_STACKSIZE,			\
419
		__FILE__, __FUNCTION__, __LINE__, #c)
419
		__FILE__, __FUNCTION__, __LINE__, #c)
420

    
   
420

   
421
#define ast_pthread_create_detached_background(a, b, c, d)	\
421
#define ast_pthread_create_detached_background(a, b, c, d)	\
422
	ast_pthread_create_detached_stack(a, b, c, d,		\
422
	ast_pthread_create_detached_stack(a, b, c, d,		\
423
		AST_BACKGROUND_STACKSIZE,			\
423
		AST_BACKGROUND_STACKSIZE,			\
424
		__FILE__, __FUNCTION__, __LINE__, #c)
424
		__FILE__, __FUNCTION__, __LINE__, #c)
425

    
   
425

   
426
/* End of thread management support */
426
/* End of thread management support */
427

    
   
427

   
428
/*!
428
/*!
429
	\brief Process a string to find and replace characters
429
	\brief Process a string to find and replace characters
430
	\param start The string to analyze
430
	\param start The string to analyze
431
	\param find The character to find
431
	\param find The character to find
432
	\param replace_with The character that will replace the one we are looking for
432
	\param replace_with The character that will replace the one we are looking for
433
*/
433
*/
434
char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
434
char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
435

    
   
435

   
436
long int ast_random(void);
436
long int ast_random(void);
437

    
   
437

   
438

    
   
438

   
439
/*! 
439
/*! 
440
 * \brief free() wrapper
440
 * \brief free() wrapper
441
 *
441
 *
442
 * ast_free_ptr should be used when a function pointer for free() needs to be passed
442
 * ast_free_ptr should be used when a function pointer for free() needs to be passed
443
 * as the argument to a function. Otherwise, astmm will cause seg faults.
443
 * as the argument to a function. Otherwise, astmm will cause seg faults.
444
 */
444
 */
445
#ifdef __AST_DEBUG_MALLOC
445
#ifdef __AST_DEBUG_MALLOC
446
static void ast_free_ptr(void *ptr) attribute_unused;
446
static void ast_free_ptr(void *ptr) attribute_unused;
447
static void ast_free_ptr(void *ptr)
447
static void ast_free_ptr(void *ptr)
448
{
448
{
449
	ast_free(ptr);
449
	ast_free(ptr);
450
}
450
}
451
#else
451
#else
452
#define ast_free free
452
#define ast_free free
453
#define ast_free_ptr ast_free
453
#define ast_free_ptr ast_free
454
#endif
454
#endif
455

    
   
455

   
456
#ifndef __AST_DEBUG_MALLOC
456
#ifndef __AST_DEBUG_MALLOC
457

    
   
457

   
458
#define MALLOC_FAILURE_MSG \
458
#define MALLOC_FAILURE_MSG \
459
	ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
459
	ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
460
/*!
460
/*!
461
 * \brief A wrapper for malloc()
461
 * \brief A wrapper for malloc()
462
 *
462
 *
463
 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
463
 * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
464
 * message in the case that the allocation fails.
464
 * message in the case that the allocation fails.
465
 *
465
 *
466
 * The argument and return value are the same as malloc()
466
 * The argument and return value are the same as malloc()
467
 */
467
 */
468
#define ast_malloc(len) \
468
#define ast_malloc(len) \
469
	_ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
469
	_ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
470

    
   
470

   
471
AST_INLINE_API(
471
AST_INLINE_API(
472
void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
472
void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
473
{
473
{
474
	void *p;
474
	void *p;
475

    
   
475

   
476
	if (!(p = malloc(len)))
476
	if (!(p = malloc(len)))
477
		MALLOC_FAILURE_MSG;
477
		MALLOC_FAILURE_MSG;
478

    
   
478

   
479
	return p;
479
	return p;
480
}
480
}
481
)
481
)
482

    
   
482

   
483
/*!
483
/*!
484
 * \brief A wrapper for calloc()
484
 * \brief A wrapper for calloc()
485
 *
485
 *
486
 * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
486
 * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
487
 * message in the case that the allocation fails.
487
 * message in the case that the allocation fails.
488
 *
488
 *
489
 * The arguments and return value are the same as calloc()
489
 * The arguments and return value are the same as calloc()
490
 */
490
 */
491
#define ast_calloc(num, len) \
491
#define ast_calloc(num, len) \
492
	_ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
492
	_ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
493

    
   
493

   
494
AST_INLINE_API(
494
AST_INLINE_API(
495
void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
495
void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
496
{
496
{
497
	void *p;
497
	void *p;
498

    
   
498

   
499
	if (!(p = calloc(num, len)))
499
	if (!(p = calloc(num, len)))
500
		MALLOC_FAILURE_MSG;
500
		MALLOC_FAILURE_MSG;
501

    
   
501

   
502
	return p;
502
	return p;
503
}
503
}
504
)
504
)
505

    
   
505

   
506
/*!
506
/*!
507
 * \brief A wrapper for calloc() for use in cache pools
507
 * \brief A wrapper for calloc() for use in cache pools
508
 *
508
 *
509
 * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
509
 * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
510
 * message in the case that the allocation fails. When memory debugging is in use,
510
 * message in the case that the allocation fails. When memory debugging is in use,
511
 * the memory allocated by this function will be marked as 'cache' so it can be
511
 * the memory allocated by this function will be marked as 'cache' so it can be
512
 * distinguished from normal memory allocations.
512
 * distinguished from normal memory allocations.
513
 *
513
 *
514
 * The arguments and return value are the same as calloc()
514
 * The arguments and return value are the same as calloc()
515
 */
515
 */
516
#define ast_calloc_cache(num, len) \
516
#define ast_calloc_cache(num, len) \
517
	_ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
517
	_ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
518

    
   
518

   
519
/*!
519
/*!
520
 * \brief A wrapper for realloc()
520
 * \brief A wrapper for realloc()
521
 *
521
 *
522
 * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
522
 * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
523
 * message in the case that the allocation fails.
523
 * message in the case that the allocation fails.
524
 *
524
 *
525
 * The arguments and return value are the same as realloc()
525
 * The arguments and return value are the same as realloc()
526
 */
526
 */
527
#define ast_realloc(p, len) \
527
#define ast_realloc(p, len) \
528
	_ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
528
	_ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
529

    
   
529

   
530
AST_INLINE_API(
530
AST_INLINE_API(
531
void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
531
void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
532
{
532
{
533
	void *newp;
533
	void *newp;
534

    
   
534

   
535
	if (!(newp = realloc(p, len)))
535
	if (!(newp = realloc(p, len)))
536
		MALLOC_FAILURE_MSG;
536
		MALLOC_FAILURE_MSG;
537

    
   
537

   
538
	return newp;
538
	return newp;
539
}
539
}
540
)
540
)
541

    
   
541

   
542
/*!
542
/*!
543
 * \brief A wrapper for strdup()
543
 * \brief A wrapper for strdup()
544
 *
544
 *
545
 * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
545
 * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
546
 * message in the case that the allocation fails.
546
 * message in the case that the allocation fails.
547
 *
547
 *
548
 * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
548
 * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
549
 * argument is provided, ast_strdup will return NULL without generating any
549
 * argument is provided, ast_strdup will return NULL without generating any
550
 * kind of error log message.
550
 * kind of error log message.
551
 *
551
 *
552
 * The argument and return value are the same as strdup()
552
 * The argument and return value are the same as strdup()
553
 */
553
 */
554
#define ast_strdup(str) \
554
#define ast_strdup(str) \
555
	_ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
555
	_ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
556

    
   
556

   
557
AST_INLINE_API(
557
AST_INLINE_API(
558
char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
558
char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
559
{
559
{
560
	char *newstr = NULL;
560
	char *newstr = NULL;
561

    
   
561

   
562
	if (str) {
562
	if (str) {
563
		if (!(newstr = strdup(str)))
563
		if (!(newstr = strdup(str)))
564
			MALLOC_FAILURE_MSG;
564
			MALLOC_FAILURE_MSG;
565
	}
565
	}
566

    
   
566

   
567
	return newstr;
567
	return newstr;
568
}
568
}
569
)
569
)
570

    
   
570

   
571
/*!
571
/*!
572
 * \brief A wrapper for strndup()
572
 * \brief A wrapper for strndup()
573
 *
573
 *
574
 * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
574
 * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
575
 * message in the case that the allocation fails.
575
 * message in the case that the allocation fails.
576
 *
576
 *
577
 * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
577
 * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
578
 * string to duplicate. If a NULL argument is provided, ast_strdup will return  
578
 * string to duplicate. If a NULL argument is provided, ast_strdup will return  
579
 * NULL without generating any kind of error log message.
579
 * NULL without generating any kind of error log message.
580
 *
580
 *
581
 * The arguments and return value are the same as strndup()
581
 * The arguments and return value are the same as strndup()
582
 */
582
 */
583
#define ast_strndup(str, len) \
583
#define ast_strndup(str, len) \
584
	_ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
584
	_ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
585

    
   
585

   
586
AST_INLINE_API(
586
AST_INLINE_API(
587
char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
587
char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
588
{
588
{
589
	char *newstr = NULL;
589
	char *newstr = NULL;
590

    
   
590

   
591
	if (str) {
591
	if (str) {
592
		if (!(newstr = strndup(str, len)))
592
		if (!(newstr = strndup(str, len)))
593
			MALLOC_FAILURE_MSG;
593
			MALLOC_FAILURE_MSG;
594
	}
594
	}
595

    
   
595

   
596
	return newstr;
596
	return newstr;
597
}
597
}
598
)
598
)
599

    
   
599

   
600
/*!
600
/*!
601
 * \brief A wrapper for asprintf()
601
 * \brief A wrapper for asprintf()
602
 *
602
 *
603
 * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
603
 * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
604
 * message in the case that the allocation fails.
604
 * message in the case that the allocation fails.
605
 *
605
 *
606
 * The arguments and return value are the same as asprintf()
606
 * The arguments and return value are the same as asprintf()
607
 */
607
 */
608
#define ast_asprintf(ret, fmt, ...) \
608
#define ast_asprintf(ret, fmt, ...) \
609
	_ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
609
	_ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
610

    
   
610

   
611
int __attribute__((format(printf, 5, 6)))
611
int __attribute__((format(printf, 5, 6)))
612
	_ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...);
612
	_ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...);
613

    
   
613

   
614
/*!
614
/*!
615
 * \brief A wrapper for vasprintf()
615
 * \brief A wrapper for vasprintf()
616
 *
616
 *
617
 * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
617
 * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
618
 * message in the case that the allocation fails.
618
 * message in the case that the allocation fails.
619
 *
619
 *
620
 * The arguments and return value are the same as vasprintf()
620
 * The arguments and return value are the same as vasprintf()
621
 */
621
 */
622
#define ast_vasprintf(ret, fmt, ap) \
622
#define ast_vasprintf(ret, fmt, ap) \
623
	_ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
623
	_ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
624

    
   
624

   
625
AST_INLINE_API(
625
AST_INLINE_API(
626
__attribute__((format(printf, 5, 0)))
626
__attribute__((format(printf, 5, 0)))
627
int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
627
int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
628
{
628
{
629
	int res;
629
	int res;
630

    
   
630

   
631
	if ((res = vasprintf(ret, fmt, ap)) == -1)
631
	if ((res = vasprintf(ret, fmt, ap)) == -1)
632
		MALLOC_FAILURE_MSG;
632
		MALLOC_FAILURE_MSG;
633

    
   
633

   
634
	return res;
634
	return res;
635
}
635
}
636
)
636
)
637

    
   
637

   
638
#endif /* AST_DEBUG_MALLOC */
638
#endif /* AST_DEBUG_MALLOC */
639

    
   
639

   
640
/*!
640
/*!
641
  \brief call __builtin_alloca to ensure we get gcc builtin semantics
641
  \brief call __builtin_alloca to ensure we get gcc builtin semantics
642
  \param size The size of the buffer we want allocated
642
  \param size The size of the buffer we want allocated
643

    
   
643

   
644
  This macro will attempt to allocate memory from the stack.  If it fails
644
  This macro will attempt to allocate memory from the stack.  If it fails
645
  you won't get a NULL returned, but a SEGFAULT if you're lucky.
645
  you won't get a NULL returned, but a SEGFAULT if you're lucky.
646
*/
646
*/
647
#define ast_alloca(size) __builtin_alloca(size)
647
#define ast_alloca(size) __builtin_alloca(size)
648

    
   
648

   
649
#if !defined(ast_strdupa) && defined(__GNUC__)
649
#if !defined(ast_strdupa) && defined(__GNUC__)
650
/*!
650
/*!
651
  \brief duplicate a string in memory from the stack
651
  \brief duplicate a string in memory from the stack
652
  \param s The string to duplicate
652
  \param s The string to duplicate
653

    
   
653

   
654
  This macro will duplicate the given string.  It returns a pointer to stack
654
  This macro will duplicate the given string.  It returns a pointer to stack
655
  allocated memory for the new string.
655
  allocated memory for the new string.
656
*/
656
*/
657
#define ast_strdupa(s)                                                    \
657
#define ast_strdupa(s)                                                    \
658
	(__extension__                                                    \
658
	(__extension__                                                    \
659
	({                                                                \
659
	({                                                                \
660
		const char *__old = (s);                                  \
660
		const char *__old = (s);                                  \
661
		size_t __len = strlen(__old) + 1;                         \
661
		size_t __len = strlen(__old) + 1;                         \
662
		char *__new = __builtin_alloca(__len);                    \
662
		char *__new = __builtin_alloca(__len);                    \
663
		memcpy (__new, __old, __len);                             \
663
		memcpy (__new, __old, __len);                             \
664
		__new;                                                    \
664
		__new;                                                    \
665
	}))
665
	}))
666
#endif
666
#endif
667

    
   
667

   
668
/*!
668
/*!
669
  \brief Disable PMTU discovery on a socket
669
  \brief Disable PMTU discovery on a socket
670
  \param sock The socket to manipulate
670
  \param sock The socket to manipulate
671
  \return Nothing
671
  \return Nothing
672

    
   
672

   
673
  On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
673
  On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
674
  bit set. This is supposedly done to allow the application to do PMTU
674
  bit set. This is supposedly done to allow the application to do PMTU
675
  discovery, but Asterisk does not do this.
675
  discovery, but Asterisk does not do this.
676

    
   
676

   
677
  Because of this, UDP packets sent by Asterisk that are larger than the MTU
677
  Because of this, UDP packets sent by Asterisk that are larger than the MTU
678
  of any hop in the path will be lost. This function can be called on a socket
678
  of any hop in the path will be lost. This function can be called on a socket
679
  to ensure that the DF bit will not be set.
679
  to ensure that the DF bit will not be set.
680
 */
680
 */
681
void ast_enable_packet_fragmentation(int sock);
681
void ast_enable_packet_fragmentation(int sock);
682

    
   
682

   
683
/*!
683
/*!
684
  \brief Recursively create directory path
684
  \brief Recursively create directory path
685
  \param path The directory path to create
685
  \param path The directory path to create
686
  \param mode The permissions with which to try to create the directory
686
  \param mode The permissions with which to try to create the directory
687
  \return 0 on success or an error code otherwise
687
  \return 0 on success or an error code otherwise
688

    
   
688

   
689
  Creates a directory path, creating parent directories as needed.
689
  Creates a directory path, creating parent directories as needed.
690
 */
690
 */
691
int ast_mkdir(const char *path, int mode);
691
int ast_mkdir(const char *path, int mode);
692

    
   
692

   
693
#define ARRAY_LEN(a) (size_t) (sizeof(a) / sizeof(0[a]))
693
#define ARRAY_LEN(a) (size_t) (sizeof(a) / sizeof(0[a]))
694

    
   
694

   
695

    
   
695

   
696
/* Definition for Digest authorization */
696
/* Definition for Digest authorization */
697
struct ast_http_digest {
697
struct ast_http_digest {
698
	AST_DECLARE_STRING_FIELDS(
698
	AST_DECLARE_STRING_FIELDS(
699
		AST_STRING_FIELD(username);
699
		AST_STRING_FIELD(username);
700
		AST_STRING_FIELD(nonce);
700
		AST_STRING_FIELD(nonce);
701
		AST_STRING_FIELD(uri);
701
		AST_STRING_FIELD(uri);
702
		AST_STRING_FIELD(realm);
702
		AST_STRING_FIELD(realm);
703
		AST_STRING_FIELD(domain);
703
		AST_STRING_FIELD(domain);
704
		AST_STRING_FIELD(response);
704
		AST_STRING_FIELD(response);
705
		AST_STRING_FIELD(cnonce);
705
		AST_STRING_FIELD(cnonce);
706
		AST_STRING_FIELD(opaque);
706
		AST_STRING_FIELD(opaque);
707
		AST_STRING_FIELD(nc);
707
		AST_STRING_FIELD(nc);
708
	);
708
	);
709
	int qop;		/* Flag set to 1, if we send/recv qop="quth" */
709
	int qop;		/* Flag set to 1, if we send/recv qop="quth" */
710
};
710
};
711

    
   
711

   
712
/*!
712
/*!
713
 *\brief Parse digest authorization header.
713
 *\brief Parse digest authorization header.
714
 *\return Returns -1 if we have no auth or something wrong with digest.
714
 *\return Returns -1 if we have no auth or something wrong with digest.
715
 *\note This function may be used for Digest request and responce header.
715
 *\note This function may be used for Digest request and responce header.
716
 * request arg is set to nonzero, if we parse Digest Request.
716
 * request arg is set to nonzero, if we parse Digest Request.
717
 * pedantic arg can be set to nonzero if we need to do addition Digest check.
717
 * pedantic arg can be set to nonzero if we need to do addition Digest check.
718
 */
718
 */
719
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic);
719
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic);
720

    
   
720

   
721

    
   
721

   
722
#ifdef AST_DEVMODE
722
#ifdef AST_DEVMODE
723
void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function);
723
void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function);
724
#define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
724
#define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
725
static void force_inline _ast_assert(int condition, const char *condition_str, const char *file, int line, const char *function)
725
static void force_inline _ast_assert(int condition, const char *condition_str, const char *file, int line, const char *function)
726
{
726
{
727
	if (__builtin_expect(!condition, 1)) {
727
	if (__builtin_expect(!condition, 1)) {
728
		__ast_assert_failed(condition, condition_str, file, line, function);
728
		__ast_assert_failed(condition, condition_str, file, line, function);
729
	}
729
	}
730
}
730
}
731
#else
731
#else
732
#define ast_assert(a)
732
#define ast_assert(a)
733
#endif
733
#endif
734

    
   
734

   
735
/*!
735
/*!
736
 * \brief Force a crash if DO_CRASH is defined.
736
 * \brief Force a crash if DO_CRASH is defined.
737
 *
737
 *
738
 * \note If DO_CRASH is not defined then the function returns.
738
 * \note If DO_CRASH is not defined then the function returns.
739
 *
739
 *
740
 * \return Nothing
740
 * \return Nothing
741
 */
741
 */
742
void ast_do_crash(void);
742
void ast_do_crash(void);
743

    
   
743

   
744
#include "asterisk/strings.h"
744
#include "asterisk/strings.h"
745

    
   
745

   
746
/*!
746
/*!
747
 * \brief Return the number of bytes used in the alignment of type.
747
 * \brief Return the number of bytes used in the alignment of type.
748
 * \param type
748
 * \param type
749
 * \return The number of bytes required for alignment.
749
 * \return The number of bytes required for alignment.
750
 *
750
 *
751
 * This is really just __alignof__(), but tucked away in this header so we
751
 * This is really just __alignof__(), but tucked away in this header so we
752
 * don't have to look at the nasty underscores in the source.
752
 * don't have to look at the nasty underscores in the source.
753
 */
753
 */
754
#define ast_alignof(type) __alignof__(type)
754
#define ast_alignof(type) __alignof__(type)
755

    
   
755

   
756
/*!
756
/*!
757
 * \brief Increase offset so it is a multiple of the required alignment of type.
757
 * \brief Increase offset so it is a multiple of the required alignment of type.
758
 * \param offset The value that should be increased.
758
 * \param offset The value that should be increased.
759
 * \param type The data type that offset should be aligned to.
759
 * \param type The data type that offset should be aligned to.
760
 * \return The smallest multiple of alignof(type) larger than or equal to offset.
760
 * \return The smallest multiple of alignof(type) larger than or equal to offset.
761
 * \see ast_make_room_for()
761
 * \see ast_make_room_for()
762
 *
762
 *
763
 * Many systems prefer integers to be stored on aligned on memory locations.
763
 * Many systems prefer integers to be stored on aligned on memory locations.
764
 * This macro will increase an offset so a value of the supplied type can be
764
 * This macro will increase an offset so a value of the supplied type can be
765
 * safely be stored on such a memory location.
765
 * safely be stored on such a memory location.
766
 *
766
 *
767
 * Examples:
767
 * Examples:
768
 * ast_align_for(0x17, int64_t) ==> 0x18
768
 * ast_align_for(0x17, int64_t) ==> 0x18
769
 * ast_align_for(0x18, int64_t) ==> 0x18
769
 * ast_align_for(0x18, int64_t) ==> 0x18
770
 * ast_align_for(0x19, int64_t) ==> 0x20
770
 * ast_align_for(0x19, int64_t) ==> 0x20
771
 *
771
 *
772
 * Don't mind the ugliness, the compiler will optimize it.
772
 * Don't mind the ugliness, the compiler will optimize it.
773
 */
773
 */
774
#define ast_align_for(offset, type) (((offset + __alignof__(type) - 1) / __alignof__(type)) * __alignof__(type))
774
#define ast_align_for(offset, type) (((offset + __alignof__(type) - 1) / __alignof__(type)) * __alignof__(type))
775

    
   
775

   
776
/*!
776
/*!
777
 * \brief Increase offset by the required alignment of type and make sure it is
777
 * \brief Increase offset by the required alignment of type and make sure it is
778
 *        a multiple of said alignment.
778
 *        a multiple of said alignment.
779
 * \param offset The value that should be increased.
779
 * \param offset The value that should be increased.
780
 * \param type The data type that room should be reserved for.
780
 * \param type The data type that room should be reserved for.
781
 * \return The smallest multiple of alignof(type) larger than or equal to offset
781
 * \return The smallest multiple of alignof(type) larger than or equal to offset
782
 *         plus alignof(type).
782
 *         plus alignof(type).
783
 * \see ast_align_for()
783
 * \see ast_align_for()
784
 *
784
 *
785
 * A use case for this is when prepending length fields of type int to a buffer.
785
 * A use case for this is when prepending length fields of type int to a buffer.
786
 * If you keep the offset a multiple of the alignment of the integer type,
786
 * If you keep the offset a multiple of the alignment of the integer type,
787
 * a next block of length+buffer will have the length field automatically
787
 * a next block of length+buffer will have the length field automatically
788
 * aligned.
788
 * aligned.
789
 *
789
 *
790
 * Examples:
790
 * Examples:
791
 * ast_make_room_for(0x17, int64_t) ==> 0x20
791
 * ast_make_room_for(0x17, int64_t) ==> 0x20
792
 * ast_make_room_for(0x18, int64_t) ==> 0x20
792
 * ast_make_room_for(0x18, int64_t) ==> 0x20
793
 * ast_make_room_for(0x19, int64_t) ==> 0x28
793
 * ast_make_room_for(0x19, int64_t) ==> 0x28
794
 *
794
 *
795
 * Don't mind the ugliness, the compiler will optimize it.
795
 * Don't mind the ugliness, the compiler will optimize it.
796
 */
796
 */
797
#define ast_make_room_for(offset, type) (((offset + (2 * __alignof__(type) - 1)) / __alignof__(type)) * __alignof__(type))
797
#define ast_make_room_for(offset, type) (((offset + (2 * __alignof__(type) - 1)) / __alignof__(type)) * __alignof__(type))
798

    
   
798

   
799
/*!
799
/*!
800
 * \brief An Entity ID is essentially a MAC address, brief and unique 
800
 * \brief An Entity ID is essentially a MAC address, brief and unique 
801
 */
801
 */
802
struct ast_eid {
802
struct ast_eid {
803
	unsigned char eid[6];
803
	unsigned char eid[6];
804
} __attribute__((__packed__));
804
} __attribute__((__packed__));
805

    
   
805

   
806
/*!
806
/*!
807
 * \brief Global EID
807
 * \brief Global EID
808
 *
808
 *
809
 * This is set in asterisk.conf, or determined automatically by taking the mac
809
 * This is set in asterisk.conf, or determined automatically by taking the mac
810
 * address of an Ethernet interface on the system.
810
 * address of an Ethernet interface on the system.
811
 */
811
 */
812
extern struct ast_eid ast_eid_default;
812
extern struct ast_eid ast_eid_default;
813

    
   
813

   
814
/*!
814
/*!
815
 * \brief Fill in an ast_eid with the default eid of this machine
815
 * \brief Fill in an ast_eid with the default eid of this machine
816
 * \since 1.6.1
816
 * \since 1.6.1
817
 */
817
 */
818
void ast_set_default_eid(struct ast_eid *eid);
818
void ast_set_default_eid(struct ast_eid *eid);
819

    
   
819

   
820
/*!
820
/*!
821
 * /brief Convert an EID to a string
821
 * /brief Convert an EID to a string
822
 * \since 1.6.1
822
 * \since 1.6.1
823
 */
823
 */
824
char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid);
824
char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid);
825

    
   
825

   
826
/*!
826
/*!
827
 * \brief Convert a string into an EID
827
 * \brief Convert a string into an EID
828
 *
828
 *
829
 * This function expects an EID in the format:
829
 * This function expects an EID in the format:
830
 *    00:11:22:33:44:55
830
 *    00:11:22:33:44:55
831
 *
831
 *
832
 * \return 0 success, non-zero failure
832
 * \return 0 success, non-zero failure
833
 * \since 1.6.1
833
 * \since 1.6.1
834
 */
834
 */
835
int ast_str_to_eid(struct ast_eid *eid, const char *s);
835
int ast_str_to_eid(struct ast_eid *eid, const char *s);
836

    
   
836

   
837
/*!
837
/*!
838
 * \brief Compare two EIDs
838
 * \brief Compare two EIDs
839
 *
839
 *
840
 * \return 0 if the two are the same, non-zero otherwise
840
 * \return 0 if the two are the same, non-zero otherwise
841
 * \since 1.6.1
841
 * \since 1.6.1
842
 */
842
 */
843
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
843
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
844

    
   
844

   
845
/*!\brief Resolve a binary to a full pathname
845
/*!\brief Resolve a binary to a full pathname
846
 * \param binary Name of the executable to resolve
846
 * \param binary Name of the executable to resolve
847
 * \param fullpath Buffer to hold the complete pathname
847
 * \param fullpath Buffer to hold the complete pathname
848
 * \param fullpath_size Size of \a fullpath
848
 * \param fullpath_size Size of \a fullpath
849
 * \retval NULL \a binary was not found or the environment variable PATH is not set
849
 * \retval NULL \a binary was not found or the environment variable PATH is not set
850
 * \return \a fullpath
850
 * \return \a fullpath
851
 */
851
 */
852
char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size);
852
char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size);
853

    
   
853

   
854
#endif /* _ASTERISK_UTILS_H */
854
#endif /* _ASTERISK_UTILS_H */
  1. /branches/1.8/include/asterisk/utils.h: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.