Main Page
Related Pages
Modules
Classes
Files
File List
File Members
ts_functions.c
Go to the documentation of this file.
1
/* ========================================================================== */
2
/*! \file
3
* \brief Thread safe replacement functions
4
*
5
* Copyright (c) 2012-2022 by the developers. See the LICENSE file for details.
6
* If nothing else is specified, functions return zero to indicate success
7
* and a negative value to indicate an error.
8
*/
9
10
11
/* ========================================================================== */
12
/* Include headers */
13
14
#include "posix.h"
/* Include this first because of feature test macros */
15
16
#include "main.h"
17
18
19
/* ========================================================================== */
20
/*! \addtogroup MAIN
21
*
22
* The POSIX \c getenv() function is not required to be thread safe. Therefore
23
* we must provide our own. It was considered to clone the getenv_r() function
24
* from BSD, but this function has no buffer management and is inconvenient to
25
* use. The function \c ts_getenv() dynamically allocate or resize the thread
26
* local buffer internally.
27
*
28
* \note
29
* A copy of the enviroment is used, therefore all modifications of the
30
* enviroment at runtime are invisible via \c ts_getenv(). \c ts_environ_init()
31
* and \c ts_environ_exit() must be called to create and destroy this copy of
32
* the enviroment.
33
*/
34
/*! @{ */
35
36
37
/* ========================================================================== */
38
/* Constants */
39
40
/*! \brief Message prefix for MAIN module */
41
#define MAIN_ERR_PREFIX "MAIN: "
42
43
44
/* ========================================================================== */
45
/* Variables */
46
47
static
char
** environ_copy = NULL;
48
static
char
* environ_data = NULL;
49
50
51
/* ========================================================================== */
52
/*! \brief Copy environment variables
53
*
54
* Must be called once before \c ts_getenv() is used and before additional
55
* threads are created.
56
*/
57
58
void
ts_environ_init
(
void
)
59
{
60
size_t
i = 0;
61
size_t
di;
62
size_t
len = 0;
63
size_t
alen;
64
65
/* Calculate size of strings */
66
while
(NULL != posix_environ[i])
67
{
68
len += strlen(posix_environ[i]) + (size_t) 1;
69
++i;
70
}
71
/* Calculate size of NULL-terminated pointer array */
72
alen =
sizeof
(
char
*) * ++i;
73
74
/* Allocate memory for pointer array */
75
environ_copy = (
char
**) malloc(alen);
76
if
(NULL != environ_copy)
77
{
78
environ_copy[0] = NULL;
79
80
/* Allocate memory for string data */
81
environ_data = (
char
*) malloc(len);
82
if
(NULL != environ_data)
83
{
84
i = 0;
85
di = 0;
86
while
(NULL != posix_environ[i])
87
{
88
strcpy(&environ_data[di], posix_environ[i]);
89
environ_copy[i] = &environ_data[di];
90
di += strlen(posix_environ[i]) + (size_t) 1;
91
++i;
92
}
93
environ_copy[i] = NULL;
94
}
95
}
96
97
return
;
98
}
99
100
101
/* ========================================================================== */
102
/*! \brief Destroy copy of environment variables
103
*
104
* Call this function once after last use of \c ts_getenv() .
105
*/
106
107
void
ts_environ_exit
(
void
)
108
{
109
posix_free((
void
*) environ_data);
110
posix_free((
void
*) environ_copy);
111
112
return
;
113
}
114
115
116
/* ========================================================================== */
117
/*! \brief Thread safe replacement for \c getenv()
118
*
119
* \param[in] name Name of the requested environment variable
120
* \param[in,out] buf Pointer to pointer to buffer for result
121
*
122
* Dereferenced \e buf must be either \c NULL or an existing dynamically
123
* allocated buffer that can be resized with \c realloc() if required.
124
*
125
* The buffer pointed to by \e buf is created or resized so that it can hold the
126
* result and the value of the environment variable \e name is copied to it.
127
*
128
* The caller is responsible to free the memory allocated for the buffer on
129
* success.
130
*
131
* \return
132
* - 0 on success
133
* - Negative value on error
134
*/
135
136
int
ts_getenv
(
const
char
* name,
const
char
** buf)
137
{
138
int
res = -1;
139
size_t
i;
140
size_t
len;
141
char
* content;
142
char
* tmp;
143
144
if
(NULL != environ_copy && NULL != buf)
145
{
146
/* Search for variable in copy of environment */
147
i = 0;
148
while
(NULL != environ_copy[i])
149
{
150
len = strlen(name);
151
if
(!strncmp(environ_copy[i], name, len))
152
{
153
if
(
'='
== environ_copy[i][len])
154
{
155
/* Found => Copy content to target buffer */
156
content = &environ_copy[i][++len];
157
len = strlen(content);
158
tmp = (
char
*) posix_realloc((
void
*) *buf, ++len);
159
if
(NULL != tmp)
160
{
161
strcpy(tmp, content);
162
*buf = tmp;
163
res = 0;
164
}
165
break
;
166
}
167
}
168
++i;
169
}
170
/* Check for error */
171
if
(res)
172
{
173
posix_free((
void
*) *buf);
174
*buf = NULL;
175
}
176
}
177
178
return
(res);
179
}
180
181
182
/*! @} */
183
184
/* EOF */
ts_environ_exit
void ts_environ_exit(void)
Destroy copy of environment variables.
Definition:
ts_functions.c:107
ts_environ_init
void ts_environ_init(void)
Copy environment variables.
Definition:
ts_functions.c:58
ts_getenv
int ts_getenv(const char *name, const char **buf)
Thread safe replacement for getenv()
Definition:
ts_functions.c:136
Generated at 2024-04-27 using