source: mainline/uspace/lib/c/generic/stdlib.c@ 1be7bee

Last change on this file since 1be7bee was bd41ac52, checked in by Jakub Jermar <jakub@…>, 7 years ago

Get rid of sys/time.h

This commit moves the POSIX-like time functionality from libc's
sys/time.h to libposix and introduces C11-like or HelenOS-specific
interfaces to libc.

Specifically, use of sys/time.h, struct timeval, suseconds_t and
gettimeofday is replaced by time.h (C11), struct timespec (C11), usec_t
(HelenOS) and getuptime / getrealtime (HelenOS).

Also attempt to fix the implementation of clock() to return microseconds
(clocks) rather than processor cycles and move it to libc.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 * Copyright (c) 2006 Ondrej Palkovsky
3 * Copyright (c) 2018 Jiri Svoboda
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
30/** @addtogroup libc
31 * @{
32 */
33/** @file
34 */
35
36#include <adt/list.h>
37#include <fibril_synch.h>
38#include <stdlib.h>
39#include <errno.h>
40#include "private/libc.h"
41#include "private/scanf.h"
42#include "private/stdlib.h"
43#include "private/stdio.h"
44#include "private/sstream.h"
45
46static int glbl_seed = 1;
47
48static LIST_INITIALIZE(exit_handlers);
49static FIBRIL_MUTEX_INITIALIZE(exit_handlers_lock);
50
51static LIST_INITIALIZE(quick_exit_handlers);
52static FIBRIL_MUTEX_INITIALIZE(quick_exit_handlers_lock);
53
54/** Convert string to long double.
55 *
56 */
57long double strtold(const char *nptr, char **endptr)
58{
59 int numchar;
60 long double ld;
61 errno_t rc;
62 FILE f;
63
64 numchar = 0;
65 __sstream_init(nptr, &f);
66
67 rc = __fstrtold(&f, &numchar, SIZE_MAX, &ld);
68 if (rc != EOK) {
69 ld = 0;
70 if (endptr != NULL)
71 *endptr = (char *) nptr;
72 errno = rc;
73 } else {
74 if (endptr != NULL)
75 *endptr = (char *) __sstream_getpos(&f);
76 }
77
78 return ld;
79}
80
81int rand(void)
82{
83 return glbl_seed = ((1366 * glbl_seed + 150889) % RAND_MAX);
84}
85
86void srand(unsigned int seed)
87{
88 glbl_seed = seed % RAND_MAX;
89}
90
91/** Register exit handler.
92 *
93 * @param func Function to be called during program terimnation
94 * @return Zero on success, nonzero on failure
95 */
96int atexit(void (*func)(void))
97{
98 __exit_handler_t *entry;
99
100 entry = malloc(sizeof(__exit_handler_t));
101 if (entry == NULL)
102 return -1;
103
104 entry->func = func;
105
106 fibril_mutex_lock(&exit_handlers_lock);
107 list_prepend(&entry->llist, &exit_handlers);
108 fibril_mutex_unlock(&exit_handlers_lock);
109 return 0;
110}
111
112/** Terminate program with exit status.
113 *
114 * @param status Exit status
115 */
116void exit(int status)
117{
118 link_t *link;
119 __exit_handler_t *eh;
120
121 /* Call exit handlers */
122 fibril_mutex_lock(&exit_handlers_lock);
123 while (!list_empty(&exit_handlers)) {
124 link = list_first(&exit_handlers);
125 list_remove(link);
126 fibril_mutex_unlock(&exit_handlers_lock);
127
128 eh = list_get_instance(link, __exit_handler_t, llist);
129 eh->func();
130 free(eh);
131 fibril_mutex_lock(&exit_handlers_lock);
132 }
133
134 fibril_mutex_unlock(&exit_handlers_lock);
135
136 _Exit(status);
137}
138
139/** Register quick exit handler.
140 *
141 * @param func Function to be called during quick program terimnation
142 * @return Zero on success, nonzero on failure
143 */
144int at_quick_exit(void (*func)(void))
145{
146 __exit_handler_t *entry;
147
148 entry = malloc(sizeof(__exit_handler_t));
149 if (entry == NULL)
150 return -1;
151
152 entry->func = func;
153
154 fibril_mutex_lock(&exit_handlers_lock);
155 list_prepend(&entry->llist, &exit_handlers);
156 fibril_mutex_unlock(&exit_handlers_lock);
157 return 0;
158}
159
160/** Quickly terminate program with exit status.
161 *
162 * @param status Exit status
163 */
164void quick_exit(int status)
165{
166 link_t *link;
167 __exit_handler_t *eh;
168
169 /* Call quick exit handlers */
170 fibril_mutex_lock(&quick_exit_handlers_lock);
171 while (!list_empty(&quick_exit_handlers)) {
172 link = list_first(&quick_exit_handlers);
173 list_remove(link);
174 fibril_mutex_unlock(&quick_exit_handlers_lock);
175
176 eh = list_get_instance(link, __exit_handler_t, llist);
177 eh->func();
178 free(eh);
179 fibril_mutex_lock(&quick_exit_handlers_lock);
180 }
181
182 fibril_mutex_unlock(&quick_exit_handlers_lock);
183
184 _Exit(status);
185}
186
187void _Exit(int status)
188{
189 __libc_exit(status);
190}
191
192/** Abnormal program termination */
193void abort(void)
194{
195 __libc_abort();
196}
197
198/** Get environment list entry.
199 *
200 * Note that this function is not reentrant. The returned string is only
201 * guaranteed to be valid until the next call to @c getenv.
202 *
203 * @param name Entry name
204 * @return Pointer to string or @c NULL if not found
205 */
206char *getenv(const char *name)
207{
208 (void) name;
209 return NULL;
210}
211
212/** Execute command.
213 *
214 * @param string Command to execute or @c NULL
215 *
216 * @return If @a string is @c NULL, return zero (no command processor
217 * available). If @a string is not @c NULL, return 1 (failure).
218 */
219int system(const char *string)
220{
221 if (string == NULL)
222 return 0;
223
224 return 1;
225}
226
227/** Compute the absolute value of an integer.
228 *
229 * If the result cannot be represented, the behavior is undefined.
230 *
231 * @param j Integer
232 * @return The absolute value of @a j
233 */
234int abs(int j)
235{
236 int aj;
237
238 if (j < 0) {
239 aj = -j;
240 assert(aj >= 0);
241 } else {
242 aj = j;
243 }
244
245 return aj;
246}
247
248/** Compute the absolute value of a long integer.
249 *
250 * If the result cannot be represented, the behavior is undefined.
251 *
252 * @param j Long integer
253 * @return The absolute value of @a j
254 */
255long labs(long j)
256{
257 long aj;
258
259 if (j < 0) {
260 aj = -j;
261 assert(aj >= 0);
262 } else {
263 aj = j;
264 }
265
266 return aj;
267}
268
269/** Compute the absolute value of a long long integer.
270 *
271 * If the result cannot be represented, the behavior is undefined.
272 *
273 * @param j Long long integer
274 * @return The absolute value of @a j
275 */
276long long llabs(long long j)
277{
278 long long aj;
279
280 if (j < 0) {
281 aj = -j;
282 assert(aj >= 0);
283 } else {
284 aj = j;
285 }
286
287 return aj;
288}
289
290/** Compute quotient and remainder of int division.
291 *
292 * @param numer Numerator
293 * @param denom Denominator
294 * @return Structure containing quotient and remainder
295 */
296div_t div(int numer, int denom)
297{
298 div_t d;
299
300 d.quot = numer / denom;
301 d.rem = numer % denom;
302
303 return d;
304}
305
306/** Compute quotient and remainder of long division.
307 *
308 * @param numer Numerator
309 * @param denom Denominator
310 * @return Structure containing quotient and remainder
311 */
312ldiv_t ldiv(long numer, long denom)
313{
314 ldiv_t d;
315
316 d.quot = numer / denom;
317 d.rem = numer % denom;
318
319 return d;
320}
321
322/** Compute quotient and remainder of long long division.
323 *
324 * @param numer Numerator
325 * @param denom Denominator
326 * @return Structure containing quotient and remainder
327 */
328lldiv_t lldiv(long long numer, long long denom)
329{
330 lldiv_t d;
331
332 d.quot = numer / denom;
333 d.rem = numer % denom;
334
335 return d;
336}
337
338/** @}
339 */
Note: See TracBrowser for help on using the repository browser.