Changeset 099c834 in mainline


Ignore:
Timestamp:
2018-06-18T13:56:02Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6c440362
Parents:
379db9ef
git-author:
Jiri Svoboda <jiri@…> (2018-06-16 22:43:05)
git-committer:
Jiri Svoboda <jiri@…> (2018-06-18 13:56:02)
Message:

atexit, exit, _Exit, at_quick_exit, quick_exit, tests for strtol and friends.

Location:
uspace/lib
Files:
1 added
7 edited

Legend:

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

    r379db9ef r099c834  
    130130}
    131131
    132 void exit(int status)
     132void __libc_exit(int status)
    133133{
    134134        if (env_setup) {
     
    145145}
    146146
    147 void abort(void)
     147void __libc_abort(void)
    148148{
    149149        __SYSCALL1(SYS_TASK_EXIT, true);
  • uspace/lib/c/generic/private/libc.h

    r379db9ef r099c834  
    3838extern unsigned char _end[];
    3939extern void __libc_main(void *) __attribute__((noreturn));
     40extern void __libc_exit(int) __attribute__((noreturn));
     41extern void __libc_abort(void) __attribute__((noreturn));
    4042extern int main(int, char *[]);
    4143
  • uspace/lib/c/generic/stdlib.c

    r379db9ef r099c834  
    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{
     
    4658        glbl_seed = seed % RAND_MAX;
    4759}
     60
     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                fibril_mutex_lock(&exit_handlers_lock);
     101        }
     102
     103        fibril_mutex_unlock(&exit_handlers_lock);
     104
     105        _Exit(status);
     106}
     107
     108/** Register quick exit handler.
     109 *
     110 * @param func Function to be called during quick program terimnation
     111 * @return Zero on success, nonzero on failure
     112 */
     113int at_quick_exit(void (*func)(void))
     114{
     115        __exit_handler_t *entry;
     116
     117        entry = malloc(sizeof(__exit_handler_t));
     118        if (entry == NULL)
     119                return -1;
     120
     121        entry->func = func;
     122
     123        fibril_mutex_lock(&exit_handlers_lock);
     124        list_prepend(&entry->llist, &exit_handlers);
     125        fibril_mutex_unlock(&exit_handlers_lock);
     126        return 0;
     127}
     128
     129/** Quickly terminate program with exit status.
     130 *
     131 * @param status Exit status
     132 */
     133void quick_exit(int status)
     134{
     135        link_t *link;
     136        __exit_handler_t *eh;
     137
     138        /* Call quick exit handlers */
     139        fibril_mutex_lock(&quick_exit_handlers_lock);
     140        while (!list_empty(&quick_exit_handlers)) {
     141                link = list_first(&quick_exit_handlers);
     142                list_remove(link);
     143                fibril_mutex_unlock(&quick_exit_handlers_lock);
     144
     145                eh = list_get_instance(link, __exit_handler_t, llist);
     146                eh->func();
     147                fibril_mutex_lock(&quick_exit_handlers_lock);
     148        }
     149
     150        fibril_mutex_unlock(&quick_exit_handlers_lock);
     151
     152        _Exit(status);
     153}
     154
     155void _Exit(int status)
     156{
     157        __libc_exit(status);
     158}
     159
     160/** Abnormal program termination */
     161void abort(void)
     162{
     163        __libc_abort();
     164}
     165
    48166
    49167/** Compute quotient and remainder of int division.
  • uspace/lib/c/include/stdlib.h

    r379db9ef r099c834  
    7777
    7878extern void abort(void) __attribute__((noreturn));
     79extern int atexit(void (*)(void));
    7980extern void exit(int) __attribute__((noreturn));
     81extern void _Exit(int) __attribute__((noreturn));
     82extern int at_quick_exit(void (*)(void));
     83extern void quick_exit(int);
    8084
    8185extern int atoi(const char *);
  • uspace/lib/c/test/stdlib.c

    r379db9ef r099c834  
    6363}
    6464
     65/** atoi function */
     66PCUT_TEST(atoi)
     67{
     68        int i;
     69
     70        i = atoi(" \t42");
     71        PCUT_ASSERT_TRUE(i == 42);
     72}
     73
     74/** atol function */
     75PCUT_TEST(atol)
     76{
     77        long li;
     78
     79        li = atol(" \t42");
     80        PCUT_ASSERT_TRUE(li == 42);
     81}
     82
     83/** atoll function */
     84PCUT_TEST(atoll)
     85{
     86        long long lli;
     87
     88        lli = atoll(" \t42");
     89        PCUT_ASSERT_TRUE(lli == 42);
     90}
     91
     92/** strtol function */
     93PCUT_TEST(strtol)
     94{
     95        long li;
     96        char *ep;
     97
     98        li = strtol(" \t42x", &ep, 10);
     99        PCUT_ASSERT_TRUE(li == 42);
     100        PCUT_ASSERT_TRUE(*ep == 'x');
     101}
     102
     103/** strtol function with auto-detected base 10 */
     104PCUT_TEST(strtol_dec_auto)
     105{
     106        long li;
     107        char *ep;
     108
     109        li = strtol(" \t42x", &ep, 0);
     110        PCUT_ASSERT_TRUE(li == 42);
     111        PCUT_ASSERT_TRUE(*ep == 'x');
     112}
     113
     114/** strtol function with octal number */
     115PCUT_TEST(strtol_oct)
     116{
     117        long li;
     118        char *ep;
     119
     120        li = strtol(" \t052x", &ep, 8);
     121        PCUT_ASSERT_TRUE(li == 052);
     122        PCUT_ASSERT_TRUE(*ep == 'x');
     123}
     124
     125/** strtol function with octal number with prefix */
     126#include <stdio.h>
     127PCUT_TEST(strtol_oct_prefix)
     128{
     129        long li;
     130        char *ep;
     131
     132        li = strtol(" \t052x", &ep, 0);
     133        printf("li=%ld (0%lo)\n", li, li);
     134        PCUT_ASSERT_TRUE(li == 052);
     135        PCUT_ASSERT_TRUE(*ep == 'x');
     136}
     137
     138/** strtol function with hex number */
     139PCUT_TEST(strtol_hex)
     140{
     141        long li;
     142        char *ep;
     143
     144        li = strtol(" \t2ax", &ep, 16);
     145        PCUT_ASSERT_TRUE(li == 0x2a);
     146        PCUT_ASSERT_TRUE(*ep == 'x');
     147}
     148
     149/** strtol function with hex number with hex prefix */
     150PCUT_TEST(strtol_hex_prefixed)
     151{
     152        long li;
     153        char *ep;
     154
     155        li = strtol(" \t0x2ax", &ep, 0);
     156        PCUT_ASSERT_TRUE(li == 0x2a);
     157        PCUT_ASSERT_TRUE(*ep == 'x');
     158}
     159
     160/** strtol function with base 16 and number with 0x prefix */
     161PCUT_TEST(strtol_base16_prefix)
     162{
     163        long li;
     164        char *ep;
     165
     166        li = strtol(" \t0x1y", &ep, 16);
     167        printf("li=%ld\n", li);
     168        PCUT_ASSERT_TRUE(li == 1);
     169        PCUT_ASSERT_TRUE(*ep == 'y');
     170}
     171
     172/** strtol function with base 36 number */
     173PCUT_TEST(strtol_base36)
     174{
     175        long li;
     176        char *ep;
     177
     178        li = strtol(" \tz1.", &ep, 36);
     179        PCUT_ASSERT_TRUE(li == 35 * 36 + 1);
     180        PCUT_ASSERT_TRUE(*ep == '.');
     181}
     182
     183/** rand function */
     184PCUT_TEST(rand)
     185{
     186        int i;
     187        int r;
     188
     189        for (i = 0; i < 100; i++) {
     190                r = rand();
     191                PCUT_ASSERT_TRUE(r >= 0);
     192                PCUT_ASSERT_TRUE(r <= RAND_MAX);
     193        }
     194
     195        PCUT_ASSERT_TRUE(RAND_MAX >= 32767);
     196}
     197
     198/** srand function */
     199PCUT_TEST(srand)
     200{
     201        int r1;
     202        int r2;
     203
     204        srand(1);
     205        r1 = rand();
     206        srand(1);
     207        r2 = rand();
     208
     209        PCUT_ASSERT_INT_EQUALS(r2, r1);
     210
     211        srand(42);
     212        r1 = rand();
     213        srand(42);
     214        r2 = rand();
     215
     216        PCUT_ASSERT_INT_EQUALS(r2, r1);
     217}
     218
     219/** Just make sure we have memory allocation function prototypes */
     220PCUT_TEST(malloc)
     221{
     222        void *p;
     223
     224#if 0
     225        // TODO
     226        p = aligned_alloc(4, 8);
     227        PCUT_ASSERT_NOT_NULL(p);
     228        free(p);
     229#endif
     230        p = calloc(4, 4);
     231        PCUT_ASSERT_NOT_NULL(p);
     232        free(p);
     233
     234        p = malloc(4);
     235        PCUT_ASSERT_NOT_NULL(p);
     236        p = realloc(p, 2);
     237        PCUT_ASSERT_NOT_NULL(p);
     238        free(p);
     239}
     240
     241/** Just check abort() is defined */
     242PCUT_TEST(abort)
     243{
     244        if (0)
     245                abort();
     246}
     247
     248static void dummy_exit_handler(void)
     249{
     250}
     251
     252/** atexit function */
     253PCUT_TEST(atexit)
     254{
     255        int rc;
     256
     257        rc = atexit(dummy_exit_handler);
     258        PCUT_ASSERT_INT_EQUALS(0, rc);
     259}
     260
     261/** exit function -- just make sure it is declared */
     262PCUT_TEST(exit)
     263{
     264        if (0)
     265                exit(0);
     266}
     267
     268/** at_quick_exit function */
     269PCUT_TEST(at_quick_exit)
     270{
     271        int rc;
     272
     273        rc = at_quick_exit(dummy_exit_handler);
     274        PCUT_ASSERT_INT_EQUALS(0, rc);
     275}
     276
     277/** quick_exit function -- just make sure it is declared */
     278PCUT_TEST(quick_exit)
     279{
     280        if (0)
     281                quick_exit(0);
     282}
     283
    65284/** Integer division */
    66285PCUT_TEST(div_func)
  • uspace/lib/posix/include/posix/stdlib.h

    r379db9ef r099c834  
    4242#include <_bits/NULL.h>
    4343
    44 /* Process Termination */
    45 #define _Exit exit
    46 
    47 extern int atexit(void (*func)(void));
    48 
    4944/* Absolute Value */
    5045extern int abs(int i);
  • uspace/lib/posix/src/stdlib.c

    r379db9ef r099c834  
    4949#include "libc/vfs/vfs.h"
    5050#include "libc/stats.h"
    51 
    52 /**
    53  *
    54  * @param array
    55  * @param count
    56  * @param size
    57  * @param compare
    58  */
    59 int atexit(void (*func)(void))
    60 {
    61         // TODO: low priority, just a compile-time dependency of binutils
    62         not_implemented();
    63         return 0;
    64 }
    6551
    6652/**
Note: See TracChangeset for help on using the changeset viewer.