source: mainline/uspace/lib/c/generic/stdlib.c@ 6c440362

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

Free exit handler structure after running exit handler.

  • Property mode set to 100644
File size: 5.0 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
168
[8338a81]169/** Compute quotient and remainder of int division.
170 *
171 * @param numer Numerator
172 * @param denom Denominator
173 * @return Structure containing quotient and remainder
174 */
175div_t div(int numer, int denom)
176{
177 div_t d;
178
179 d.quot = numer / denom;
180 d.rem = numer % denom;
181
182 return d;
183}
184
185/** Compute quotient and remainder of long division.
186 *
187 * @param numer Numerator
188 * @param denom Denominator
189 * @return Structure containing quotient and remainder
190 */
191ldiv_t ldiv(long numer, long denom)
192{
193 ldiv_t d;
194
195 d.quot = numer / denom;
196 d.rem = numer % denom;
197
198 return d;
199}
200
201/** Compute quotient and remainder of long long division.
202 *
203 * @param numer Numerator
204 * @param denom Denominator
205 * @return Structure containing quotient and remainder
206 */
207lldiv_t lldiv(long long numer, long long denom)
208{
209 lldiv_t d;
210
211 d.quot = numer / denom;
212 d.rem = numer % denom;
213
214 return d;
215}
216
[fadd381]217/** @}
[b2951e2]218 */
Note: See TracBrowser for help on using the repository browser.