source: mainline/uspace/lib/c/generic/stdlib.c@ 8dab988

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8dab988 was 7d7bc09, checked in by Jiri Svoboda <jiri@…>, 7 years ago

abs, labs, llabs.

  • Property mode set to 100644
File size: 6.5 KB
RevLine 
[c594489]1/*
[df4ed85]2 * Copyright (c) 2006 Ondrej Palkovsky
[099c834]3 * Copyright (c) 2018 Jiri Svoboda
[c594489]4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
[fadd381]30/** @addtogroup libc
[b2951e2]31 * @{
32 */
33/** @file
34 */
35
[099c834]36#include <adt/list.h>
37#include <fibril_synch.h>
[c594489]38#include <stdlib.h>
[099c834]39#include "private/libc.h"
40#include "private/stdlib.h"
[c594489]41
[c718bda]42static int glbl_seed = 1;
[c594489]43
[099c834]44static LIST_INITIALIZE(exit_handlers);
45static FIBRIL_MUTEX_INITIALIZE(exit_handlers_lock);
46
47static LIST_INITIALIZE(quick_exit_handlers);
48static FIBRIL_MUTEX_INITIALIZE(quick_exit_handlers_lock);
49
50
[c718bda]51int rand(void)
[c594489]52{
[ff98ce8]53 return glbl_seed = ((1366 * glbl_seed + 150889) % RAND_MAX);
[c594489]54}
55
[c718bda]56void srand(unsigned int seed)
[c594489]57{
[ff98ce8]58 glbl_seed = seed % RAND_MAX;
[c594489]59}
[b2951e2]60
[099c834]61/** Register exit handler.
62 *
63 * @param func Function to be called during program terimnation
64 * @return Zero on success, nonzero on failure
65 */
66int atexit(void (*func)(void))
67{
68 __exit_handler_t *entry;
69
70 entry = malloc(sizeof(__exit_handler_t));
71 if (entry == NULL)
72 return -1;
73
74 entry->func = func;
75
76 fibril_mutex_lock(&exit_handlers_lock);
77 list_prepend(&entry->llist, &exit_handlers);
78 fibril_mutex_unlock(&exit_handlers_lock);
79 return 0;
80}
81
82/** Terminate program with exit status.
83 *
84 * @param status Exit status
85 */
86void exit(int status)
87{
88 link_t *link;
89 __exit_handler_t *eh;
90
91 /* Call exit handlers */
92 fibril_mutex_lock(&exit_handlers_lock);
93 while (!list_empty(&exit_handlers)) {
94 link = list_first(&exit_handlers);
95 list_remove(link);
96 fibril_mutex_unlock(&exit_handlers_lock);
97
98 eh = list_get_instance(link, __exit_handler_t, llist);
99 eh->func();
[6c440362]100 free(eh);
[099c834]101 fibril_mutex_lock(&exit_handlers_lock);
102 }
103
104 fibril_mutex_unlock(&exit_handlers_lock);
105
106 _Exit(status);
107}
108
109/** Register quick exit handler.
110 *
111 * @param func Function to be called during quick program terimnation
112 * @return Zero on success, nonzero on failure
113 */
114int at_quick_exit(void (*func)(void))
115{
116 __exit_handler_t *entry;
117
118 entry = malloc(sizeof(__exit_handler_t));
119 if (entry == NULL)
120 return -1;
121
122 entry->func = func;
123
124 fibril_mutex_lock(&exit_handlers_lock);
125 list_prepend(&entry->llist, &exit_handlers);
126 fibril_mutex_unlock(&exit_handlers_lock);
127 return 0;
128}
129
130/** Quickly terminate program with exit status.
131 *
132 * @param status Exit status
133 */
134void quick_exit(int status)
135{
136 link_t *link;
137 __exit_handler_t *eh;
138
139 /* Call quick exit handlers */
140 fibril_mutex_lock(&quick_exit_handlers_lock);
141 while (!list_empty(&quick_exit_handlers)) {
142 link = list_first(&quick_exit_handlers);
143 list_remove(link);
144 fibril_mutex_unlock(&quick_exit_handlers_lock);
145
146 eh = list_get_instance(link, __exit_handler_t, llist);
147 eh->func();
[6c440362]148 free(eh);
[099c834]149 fibril_mutex_lock(&quick_exit_handlers_lock);
150 }
151
152 fibril_mutex_unlock(&quick_exit_handlers_lock);
153
154 _Exit(status);
155}
156
157void _Exit(int status)
158{
159 __libc_exit(status);
160}
161
162/** Abnormal program termination */
163void abort(void)
164{
165 __libc_abort();
166}
167
[75c430e3]168/** Get environment list entry.
169 *
170 * Note that this function is not reentrant. The returned string is only
171 * guaranteed to be valid until the next call to @c getenv.
172 *
173 * @param name Entry name
174 * @return Pointer to string or @c NULL if not found
175 */
176char *getenv(const char *name)
177{
178 (void) name;
179 return NULL;
180}
181
182/** Execute command.
183 *
184 * @param string Command to execute or @c NULL
185 *
186 * @return If @a string is @c NULL, return zero (no command processor
187 * available). If @a string is not @c NULL, return 1 (failure).
188 */
189int system(const char *string)
190{
191 if (string == NULL)
192 return 0;
193
194 return 1;
195}
[099c834]196
[7d7bc09]197/** Compute the absolute value of an integer.
198 *
199 * If the result cannot be represented, the behavior is undefined.
200 *
201 * @param j Integer
202 * @return The absolute value of @a j
203 */
204int abs(int j)
205{
206 int aj;
207
208 if (j < 0) {
209 aj = -j;
210 assert(aj >= 0);
211 } else {
212 aj = j;
213 }
214
215 return aj;
216}
217
218/** Compute the absolute value of a long integer.
219 *
220 * If the result cannot be represented, the behavior is undefined.
221 *
222 * @param j Long integer
223 * @return The absolute value of @a j
224 */
225long labs(long j)
226{
227 long aj;
228
229 if (j < 0) {
230 aj = -j;
231 assert(aj >= 0);
232 } else {
233 aj = j;
234 }
235
236 return aj;
237}
238
239/** Compute the absolute value of a long long integer.
240 *
241 * If the result cannot be represented, the behavior is undefined.
242 *
243 * @param j Long long integer
244 * @return The absolute value of @a j
245 */
246long long llabs(long long j)
247{
248 long long aj;
249
250 if (j < 0) {
251 aj = -j;
252 assert(aj >= 0);
253 } else {
254 aj = j;
255 }
256
257 return aj;
258}
259
[8338a81]260/** Compute quotient and remainder of int division.
261 *
262 * @param numer Numerator
263 * @param denom Denominator
264 * @return Structure containing quotient and remainder
265 */
266div_t div(int numer, int denom)
267{
268 div_t d;
269
270 d.quot = numer / denom;
271 d.rem = numer % denom;
272
273 return d;
274}
275
276/** Compute quotient and remainder of long division.
277 *
278 * @param numer Numerator
279 * @param denom Denominator
280 * @return Structure containing quotient and remainder
281 */
282ldiv_t ldiv(long numer, long denom)
283{
284 ldiv_t d;
285
286 d.quot = numer / denom;
287 d.rem = numer % denom;
288
289 return d;
290}
291
292/** Compute quotient and remainder of long long division.
293 *
294 * @param numer Numerator
295 * @param denom Denominator
296 * @return Structure containing quotient and remainder
297 */
298lldiv_t lldiv(long long numer, long long denom)
299{
300 lldiv_t d;
301
302 d.quot = numer / denom;
303 d.rem = numer % denom;
304
305 return d;
306}
307
[fadd381]308/** @}
[b2951e2]309 */
Note: See TracBrowser for help on using the repository browser.