Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/stdlib.c

    rc718bda r7d7bc09  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
     3 * Copyright (c) 2018 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3334 */
    3435
     36#include <adt/list.h>
     37#include <fibril_synch.h>
    3538#include <stdlib.h>
     39#include "private/libc.h"
     40#include "private/stdlib.h"
    3641
    3742static int glbl_seed = 1;
    3843
     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
    3951int rand(void)
    4052{
     
    4759}
    4860
     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();
     100                free(eh);
     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();
     148                free(eh);
     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/** 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}
     196
     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
     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
    49308/** @}
    50309 */
Note: See TracChangeset for help on using the changeset viewer.