Changeset 3e828ea in mainline for uspace/lib/c


Ignore:
Timestamp:
2019-09-23T12:49:29Z (7 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/fix-logger-deadlock, topic/msim-upgrade, topic/simplify-dev-export
Children:
9be2358
Parents:
9259d20 (diff), 1a4ec93f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jiri Svoboda <jiri@…> (2019-09-22 12:49:07)
git-committer:
Jiri Svoboda <jiri@…> (2019-09-23 12:49:29)
Message:

Merge changes from master, especially Meson build

Location:
uspace/lib/c
Files:
24 added
26 deleted
50 edited
22 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/arch/abs32le/meson.build

    r9259d20 r3e828ea  
    2727#
    2828
    29 USPACE_PREFIX = ../..
    30 LIBS =
    31 EXTRA_CFLAGS =
    32 BINARY = killall
     29arch_src += files(
     30        'src/entryjmp.c',
     31        'src/thread_entry.c',
     32        'src/fibril.c',
     33        'src/tls.c',
     34        'src/syscall.c',
     35        'src/stacktrace.c',
     36)
    3337
    34 SOURCES = \
    35         killall.c
    36 
    37 include $(USPACE_PREFIX)/Makefile.common
     38arch_start_src = files('src/crt0.c')
  • uspace/lib/c/arch/amd64/src/rtld/reloc.c

    r9259d20 r3e828ea  
    234234}
    235235
     236/** Get the adress of a function.
     237 *
     238 * @param sym Symbol
     239 * @param m Module in which the symbol is located
     240 * @return Address of function
     241 */
     242void *func_get_addr(elf_symbol_t *sym, module_t *m)
     243{
     244        return symbol_get_addr(sym, m, __tcb_get());
     245}
     246
    236247/** @}
    237248 */
  • uspace/lib/c/arch/arm32/include/libarch/fibril_context.h

    r9259d20 r3e828ea  
    3333
    3434/*
    35  * Only registers preserved accross function calls are included. r9 is
     35 * Only registers preserved across function calls are included. r9 is
    3636 * used to store a TLS address. -ffixed-r9 gcc forces gcc not to use this
    3737 * register. -mtp=soft forces gcc to use #__aeabi_read_tp to obtain
  • uspace/lib/c/arch/arm32/meson.build

    r9259d20 r3e828ea  
    2828#
    2929
    30 COMMON_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -mapcs-frame \
    31         -mcpu=$(subst _,-,$(PROCESSOR)) -Wl,-z,max-page-size=0x1000
     30arch_src += files(
     31        'src/atomic.c',
     32        'src/entryjmp.S',
     33        'src/thread_entry.S',
     34        'src/syscall.c',
     35        'src/fibril.S',
     36        'src/tls.c',
     37        'src/eabi.S',
     38        'src/stacktrace.c',
     39        'src/stacktrace_asm.S',
     40        'src/rtld/dynamic.c',
     41        'src/rtld/reloc.c',
     42)
    3243
    33 LDFLAGS += -Wl,--gc-sections
    34 
    35 ifeq ($(CONFIG_FPU),y)
    36         COMMON_CFLAGS += -mfloat-abi=hard
    37 endif
    38 
    39 ENDIANESS = LE
    40 
    41 BFD_NAME = elf32-littlearm
    42 BFD_ARCH = arm
     44arch_start_src = files('src/crt0.S')
  • uspace/lib/c/arch/arm32/src/rtld/reloc.c

    r9259d20 r3e828ea  
    216216}
    217217
     218/** Get the adress of a function.
     219 *
     220 * @param sym Symbol
     221 * @param m Module in which the symbol is located
     222 * @return Address of function
     223 */
     224void *func_get_addr(elf_symbol_t *sym, module_t *m)
     225{
     226        return symbol_get_addr(sym, m, __tcb_get());
     227}
     228
    218229/** @}
    219230 */
  • uspace/lib/c/arch/arm64/include/libarch/syscall.h

    r9259d20 r3e828ea  
    11/*
    2  * Copyright (c) 2012 Petr Koupy
     2 * Copyright (c) 2015 Petr Pavlu
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup draw
     29/** @addtogroup libcarm64
    3030 * @{
    3131 */
    32 /**
    33  * @file
     32/** @file
     33 * @brief
    3434 */
    3535
    36 #ifndef DRAW_FONT_EMBEDDED_H_
    37 #define DRAW_FONT_EMBEDDED_H_
     36#ifndef _LIBC_arm64_SYSCALL_H_
     37#define _LIBC_arm64_SYSCALL_H_
    3838
    39 #include "../font.h"
     39#define LIBARCH_SYSCALL_GENERIC
    4040
    41 extern errno_t embedded_font_create(font_t **, uint16_t points);
     41#include <syscall.h>
    4242
    4343#endif
  • uspace/lib/c/arch/arm64/include/libarch/tls.h

    r9259d20 r3e828ea  
    11/*
    2  * Copyright (c) 2012 Petr Koupy
    3  * Copyright (c) 2014 Martin Sucha
     2 * Copyright (c) 2015 Petr Pavlu
    43 * All rights reserved.
    54 *
     
    2827 */
    2928
    30 /** @addtogroup draw
     29/** @addtogroup libcarm64
    3130 * @{
    3231 */
    33 /**
    34  * @file
     32/** @file
     33 * @brief Thread-local storage.
    3534 */
    3635
    37 #ifndef DRAW_FONT_BITMAP_BACKEND_H_
    38 #define DRAW_FONT_BITMAP_BACKEND_H_
     36#ifndef _LIBC_arm64_TLS_H_
     37#define _LIBC_arm64_TLS_H_
    3938
    40 #include <stdint.h>
     39#define CONFIG_TLS_VARIANT_1
    4140
    42 #include "../font.h"
    43 #include "../surface.h"
    44 #include "../source.h"
     41/** Offsets for accessing thread-local variables are shifted 16 bytes higher. */
     42#define ARCH_TP_OFFSET  (sizeof(tcb_t) - 16)
    4543
     44/** TCB (Thread Control Block) struct.
     45 *
     46 * TLS starts just after this struct.
     47 */
    4648typedef struct {
    47         errno_t (*resolve_glyph)(void *, const wchar_t, glyph_id_t *);
    48         errno_t (*load_glyph_surface)(void *, glyph_id_t, surface_t **);
    49         errno_t (*load_glyph_metrics)(void *, glyph_id_t, glyph_metrics_t *);
    50         void (*release)(void *);
    51 } bitmap_font_decoder_t;
     49        /** Fibril data. */
     50        void *fibril_data;
     51} tcb_t;
    5252
    53 extern errno_t bitmap_font_create(bitmap_font_decoder_t *, void *, uint32_t,
    54     font_metrics_t, uint16_t, font_t **);
     53static inline void __tcb_raw_set(void *tls)
     54{
     55        asm volatile ("msr tpidr_el0, %[tls]" : : [tls] "r" (tls));
     56}
     57
     58static inline void *__tcb_raw_get(void)
     59{
     60        void *retval;
     61        asm volatile ("mrs %[tls], tpidr_el0" : [tls] "=r" (retval));
     62        return retval;
     63}
    5564
    5665#endif
  • uspace/lib/c/arch/arm64/src/crt0.S

    r9259d20 r3e828ea  
    11#
    2 # Copyright (c) 2017 Jiri Svoboda
     2# Copyright (c) 2015 Petr Pavlu
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 cfg_file = doxygen.cfg
    30 gen_cfg = doxygen.cfg.gen
    31 patch_file = doxygen.cfg.diff
    32 output_dirs = latex html
     29#include <abi/asmtool.h>
    3330
    34 all: doxygen.cfg
    35         doxygen $^
     31.text
    3632
    37 clean:
    38         rm -f $(gen_cfg) $(cfg_file)
    39         rm -rf $(output_dirs)
     33.org 0
    4034
    41 $(cfg_file): $(gen_cfg)
    42         cp $^ $@
    43         patch $@ $(patch_file)
     35## User-space task entry point
     36#
     37# x0 contains the PCB pointer
     38#
     39SYMBOL(_start)
     40        #
     41        # Create the first stack frame.
     42        #
     43        mov x29, #0
     44        stp x29, x30, [sp, #-16]!
     45        mov x29, sp
    4446
    45 $(gen_cfg):
    46         doxygen -g $@
     47        # Pass pcb_ptr to __c_start as the first argument (in x0)
     48        bl __c_start
  • uspace/lib/c/arch/arm64/src/stacktrace_asm.S

    r9259d20 r3e828ea  
    11#
    2 # Copyright (c) 2014 Martin Sucha
     2# Copyright (c) 2015 Petr Pavlu
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29#include <abi/asmtool.h>
    3030
    31 # TODO: Should be just "gui", rest is transitive dependencies.
    32 LIBS = gui draw softrend compress math
     31.text
    3332
    34 BINARY = fontviewer
     33FUNCTION_BEGIN(stacktrace_prepare)
     34        ret
     35FUNCTION_END(stacktrace_prepare)
    3536
    36 SOURCES = \
    37         fontviewer.c
     37FUNCTION_BEGIN(stacktrace_fp_get)
     38        mov x0, x29
     39        ret
     40FUNCTION_END(stacktrace_fp_get)
    3841
    39 include $(USPACE_PREFIX)/Makefile.common
     42FUNCTION_BEGIN(stacktrace_pc_get)
     43        mov x0, x30
     44        ret
     45FUNCTION_END(stacktrace_pc_get)
  • uspace/lib/c/arch/arm64/src/thread_entry.S

    r9259d20 r3e828ea  
    11#
    2 # Copyright (c) 2018 Jaroslav Jindrak
     2# Copyright (c) 2015 Petr Pavlu
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29#include <abi/asmtool.h>
    3030
    31 BINARY = cpptest
     31.text
    3232
    33 SOURCES = \
    34         main.cpp
     33## User-space thread entry point for all but the first thread.
     34#
     35#
     36SYMBOL(__thread_entry)
     37        #
     38        # Create the first stack frame.
     39        #
     40        mov x29, #0
     41        stp x29, x30, [sp, #-16]!
     42        mov x29, sp
    3543
    36 
    37 include $(USPACE_PREFIX)/Makefile.common
     44        b __thread_main
  • uspace/lib/c/arch/arm64/src/tls.c

    r9259d20 r3e828ea  
    11/*
    2  * Copyright (c) 2011 Martin Decky
    3  * Copyright (c) 2011 Petr Koupy
     2 * Copyright (c) 2015 Petr Pavlu
    43 * All rights reserved.
    54 *
     
    2827 */
    2928
    30 /** @addtogroup draw
    31  * @{
     29/** @addtogroup libcarm64
    3230 */
    33 /**
    34  * @file
     31/** @file
     32 * @brief Thread-local storage.
    3533 */
    3634
    37 #ifndef DRAW_CODEC_TGA_H_
    38 #define DRAW_CODEC_TGA_H_
     35#include <tls.h>
     36#include <stddef.h>
    3937
    40 #include <stddef.h>
    41 #include "../surface.h"
     38tcb_t *tls_alloc_arch(size_t size, size_t align)
     39{
     40        return tls_alloc_variant_1(size, align);
     41}
    4242
    43 extern surface_t *decode_tga(void *, size_t, surface_flags_t);
    44 extern bool encode_tga(surface_t *, void **, size_t *);
    45 
    46 #endif
     43void tls_free_arch(tcb_t *tcb, size_t size, size_t align)
     44{
     45        tls_free_variant_1(tcb, size, align);
     46}
    4747
    4848/** @}
  • uspace/lib/c/arch/ia32/src/rtld/reloc.c

    r9259d20 r3e828ea  
    216216}
    217217
     218/** Get the adress of a function.
     219 *
     220 * @param sym Symbol
     221 * @param m Module in which the symbol is located
     222 * @return Address of function
     223 */
     224void *func_get_addr(elf_symbol_t *sym, module_t *m)
     225{
     226        return symbol_get_addr(sym, m, __tcb_get());
     227}
     228
    218229/** @}
    219230 */
  • uspace/lib/c/arch/ia64/include/libarch/tls.h

    r9259d20 r3e828ea  
    4242/* This structure must be exactly 16 bytes long */
    4343typedef struct {
    44         void *dtv; /* unused in static linking*/
     44        void **dtv;
    4545        void *fibril_data;
    4646} tcb_t;
  • uspace/lib/c/arch/ia64/src/rtld/dynamic.c

    r9259d20 r3e828ea  
    11/*
    2  * Copyright (c) 2014 Martin Decky
     2 * Copyright (c) 2019 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup draw
     29/** @addtogroup libcia64
     30 * @brief
    3031 * @{
    3132 */
     
    3435 */
    3536
    36 #ifndef DRAW_CODEC_WEBP_H_
    37 #define DRAW_CODEC_WEBP_H_
     37#include <stdio.h>
     38#include <stdlib.h>
    3839
    39 #include <stddef.h>
    40 #include "../surface.h"
     40#include <rtld/elf_dyn.h>
     41#include <rtld/dynamic.h>
    4142
    42 extern surface_t *decode_webp(void *, size_t, surface_flags_t);
    43 extern bool encode_webp(surface_t *, void **, size_t *);
    44 
    45 #endif
     43void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
     44{
     45        (void) dp;
     46        (void) bias;
     47        (void) info;
     48}
    4649
    4750/** @}
  • uspace/lib/c/arch/ia64/src/thread_entry.S

    r9259d20 r3e828ea  
    3434#
    3535#
    36 SYMBOL(__thread_entry)
     36SYMBOL_BEGIN(__thread_entry)
    3737        alloc loc0 = ar.pfs, 0, 1, 1, 0
    3838
     39#ifndef CONFIG_RTLD
     40        # XXX This does not work in a shared library
    3941        movl gp = __gp
     42#endif
    4043
    4144        #
     
    4447
    4548        mov out0 = r8 ;;
     49        # XXX br.call.sptk.many b0 = FUNCTION_REF(__thread_main)
    4650        br.call.sptk.many b0 = __thread_main
    4751
     
    5054        #
    5155
     56SYMBOL_END(__thread_entry)
  • uspace/lib/c/arch/ia64/src/tls.c

    r9259d20 r3e828ea  
    11/*
     2 * Copyright (c) 2019 Jiri Svoboda
    23 * Copyright (c) 2006 Ondrej Palkovsky
    34 * All rights reserved.
     
    3738#include <tls.h>
    3839
     40#ifdef CONFIG_RTLD
     41#include <rtld/rtld.h>
     42#endif
     43
    3944tcb_t *tls_alloc_arch(size_t size, size_t align)
    4045{
     
    4752}
    4853
     54/*
     55 * Rtld TLS support
     56 */
     57
     58typedef struct {
     59        unsigned long int ti_module;
     60        unsigned long int ti_offset;
     61} tls_index;
     62
     63void *__tls_get_addr(tls_index *ti);
     64
     65void *__tls_get_addr(tls_index *ti)
     66{
     67        uint8_t *tls;
     68
     69#ifdef CONFIG_RTLD
     70        if (runtime_env != NULL) {
     71                return rtld_tls_get_addr(runtime_env, __tcb_get(),
     72                    ti->ti_module, ti->ti_offset);
     73        }
     74#endif
     75        /* Get address of static TLS block */
     76        tls = tls_get();
     77        return tls + ti->ti_offset;
     78}
     79
    4980/** @}
    5081 */
  • uspace/lib/c/arch/ppc32/meson.build

    r9259d20 r3e828ea  
    2727#
    2828
    29 $(INITRD).img:
    30 ifeq ($(RDFMT),tmpfs)
    31         tar -c -f $@ -C $(DIST_PATH) .
    32 endif
    33 ifeq ($(RDFMT),fat)
    34         $(MKFAT) 1048576 $(DIST_PATH) $@
    35 endif
    36 ifeq ($(RDFMT),ext4fs)
    37         $(MKEXT4) 1048576 $(DIST_PATH) $@
    38 endif
     29arch_src += [ autocheck.process('include/libarch/fibril_context.h') ]
     30
     31arch_src += files(
     32        'src/entryjmp.S',
     33        'src/thread_entry.S',
     34        'src/syscall.c',
     35        'src/fibril.S',
     36        'src/tls.c',
     37        'src/stacktrace.c',
     38        'src/stacktrace_asm.S',
     39        'src/rtld/dynamic.c',
     40        'src/rtld/reloc.c',
     41)
     42
     43arch_start_src = files('src/crt0.S')
  • uspace/lib/c/arch/ppc32/src/rtld/reloc.c

    r9259d20 r3e828ea  
    240240                        }
    241241
    242                         sym_size = sym->st_size;
    243                         if (sym_size != sym_def->st_size) {
    244 #if 0
    245                                 printf("Warning: Mismatched symbol sizes.\n");
    246 #endif
    247                                 /* Take the lower value. */
    248                                 if (sym_size > sym_def->st_size)
    249                                         sym_size = sym_def->st_size;
    250                         }
    251 
    252242                        DPRINTF("sym_addr = 0x%zx\n", sym_addr);
    253243                        DPRINTF("r_offset=0x%zx\n", r_offset);
     
    428418}
    429419
     420/** Get the adress of a function.
     421 *
     422 * @param sym Symbol
     423 * @param m Module in which the symbol is located
     424 * @return Address of function
     425 */
     426void *func_get_addr(elf_symbol_t *sym, module_t *m)
     427{
     428        return symbol_get_addr(sym, m, __tcb_get());
     429}
     430
    430431/** @}
    431432 */
  • uspace/lib/c/arch/riscv64/meson.build

    r9259d20 r3e828ea  
    2727#
    2828
    29 ARCH_SOURCES = \
    30         arch/$(UARCH)/src/entryjmp.c \
    31         arch/$(UARCH)/src/thread_entry.c \
    32         arch/$(UARCH)/src/fibril.c \
    33         arch/$(UARCH)/src/tls.c \
    34         arch/$(UARCH)/src/syscall.c \
    35         arch/$(UARCH)/src/stacktrace.c
     29arch_src += [ autocheck.process('include/libarch/fibril_context.h') ]
    3630
    37 ARCH_AUTOCHECK_HEADERS = \
    38         arch/$(UARCH)/include/libarch/fibril_context.h
     31arch_src += files(
     32        'src/entryjmp.c',
     33        'src/thread_entry.c',
     34        'src/fibril.c',
     35        'src/tls.c',
     36        'src/syscall.c',
     37        'src/stacktrace.c',
     38)
     39
     40arch_start_src = files('src/crt0.c')
  • uspace/lib/c/arch/sparc64/meson.build

    r9259d20 r3e828ea  
    2727#
    2828
    29 ifeq ($(CONFIG_FPU),y)
    30         FLOATS=hard
    31 else
    32         FLOATS=soft
    33 endif
     29arch_src += [ autocheck.process('include/libarch/fibril_context.h') ]
    3430
    35 COMMON_CFLAGS += -mcpu=powerpc -m$(FLOATS)-float -m32 -Wl,-z,max-page-size=0x1000
    36 AFLAGS += -a32
    37 LDFLAGS += -Wl,--gc-sections
     31arch_src += files(
     32        'src/entryjmp.S',
     33        'src/thread_entry.S',
     34        'src/fibril.S',
     35        'src/tls.c',
     36        'src/stacktrace.c',
     37        'src/stacktrace_asm.S',
     38        'src/rtld/dynamic.c',
     39        'src/rtld/reloc.c',
     40)
    3841
    39 ENDIANESS = BE
    40 
    41 BFD_NAME = elf32-powerpc
    42 BFD_ARCH = powerpc:common
     42arch_start_src = files('src/crt0.S')
  • uspace/lib/c/arch/sparc64/src/rtld/reloc.c

    r9259d20 r3e828ea  
    206206                        }
    207207
    208                         sym_size = sym->st_size;
    209                         if (sym_size != sym_def->st_size) {
    210                                 printf("Warning: Mismatched symbol sizes.\n");
    211                                 /* Take the lower value. */
    212                                 if (sym_size > sym_def->st_size)
    213                                         sym_size = sym_def->st_size;
    214                         }
    215 
    216208                        DPRINTF("sym_addr = 0x%zx\n", sym_addr);
    217209                        DPRINTF("r_offset=0x%zx\n", r_offset);
     
    307299}
    308300
     301/** Get the adress of a function.
     302 *
     303 * @param sym Symbol
     304 * @param m Module in which the symbol is located
     305 * @return Address of function
     306 */
     307void *func_get_addr(elf_symbol_t *sym, module_t *m)
     308{
     309        return symbol_get_addr(sym, m, __tcb_get());
     310}
     311
    309312/** @}
    310313 */
  • uspace/lib/c/doc/doxygroups.h

    r9259d20 r3e828ea  
    1717/**
    1818 * @addtogroup libcarm32 arm32
     19 * @ingroup libc
     20 */
     21
     22/**
     23 * @addtogroup libcarm64 arm64
    1924 * @ingroup libc
    2025 */
  • uspace/lib/c/generic/async/server.c

    r9259d20 r3e828ea  
    114114#include <stdlib.h>
    115115#include <mem.h>
    116 #include <stdlib.h>
    117116#include <macros.h>
    118117#include <str_error.h>
  • uspace/lib/c/generic/ctype.c

    r9259d20 r3e828ea  
    9090        case '\v':
    9191                return 1;
    92                 break;
    9392        default:
    9493                return 0;
  • uspace/lib/c/generic/dirent.c

    r9259d20 r3e828ea  
    3939#include <errno.h>
    4040#include <assert.h>
     41#include <string.h>
    4142
    4243struct __dirstream {
     
    9293        ssize_t len = 0;
    9394
    94         rc = vfs_read_short(dirp->fd, dirp->pos, &dirp->res.d_name[0],
    95             NAME_MAX + 1, &len);
     95        rc = vfs_read_short(dirp->fd, dirp->pos, dirp->res.d_name,
     96            sizeof(dirp->res.d_name), &len);
    9697        if (rc != EOK) {
    9798                errno = rc;
    9899                return NULL;
    99100        }
     101
     102        assert(strnlen(dirp->res.d_name, sizeof(dirp->res.d_name)) < sizeof(dirp->res.d_name));
    100103
    101104        dirp->pos += len;
  • uspace/lib/c/generic/dlfcn.c

    r9259d20 r3e828ea  
    3535 */
    3636
     37#include <errno.h>
    3738#include <stdio.h>
    3839#include <stdlib.h>
     
    4445#include <rtld/module.h>
    4546#include <rtld/rtld.h>
     47#include <rtld/rtld_arch.h>
    4648#include <rtld/symbol.h>
    4749
     
    5355        if (m == NULL) {
    5456                m = module_load(runtime_env, path, mlf_local);
    55                 module_load_deps(m, mlf_local);
     57                if (m == NULL) {
     58                        return NULL;
     59                }
     60
     61                if (module_load_deps(m, mlf_local) != EOK) {
     62                        return NULL;
     63                }
     64
    5665                /* Now relocate. */
    5766                module_process_relocs(m);
     
    7180        sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm);
    7281        if (sd != NULL) {
    73                 return symbol_get_addr(sd, sm, __tcb_get());
     82                if (elf_st_type(sd->st_info) == STT_FUNC)
     83                        return func_get_addr(sd, sm);
     84                else
     85                        return symbol_get_addr(sd, sm, __tcb_get());
    7486        }
    7587
  • uspace/lib/c/generic/elf/elf_load.c

    r9259d20 r3e828ea  
    5353 * @param file File handle
    5454 * @param info Place to store ELF program information
    55  * @return EE_OK on success or an EE_x error code
     55 * @return EOK on success or an error code
    5656 */
    57 int elf_load(int file, elf_info_t *info)
     57errno_t elf_load(int file, elf_info_t *info)
    5858{
    5959#ifdef CONFIG_RTLD
    6060        rtld_t *env;
    6161#endif
    62         int rc;
     62        errno_t rc;
    6363
    6464        rc = elf_load_file(file, 0, &info->finfo);
    65         if (rc != EE_OK) {
     65        if (rc != EOK) {
    6666                DPRINTF("Failed to load executable '%s'.\n", file_name);
    6767                return rc;
     
    7272                DPRINTF("Binary is statically linked.\n");
    7373                info->env = NULL;
    74                 return EE_OK;
     74                return EOK;
    7575        }
    7676
     
    7979        DPRINTF("- prog dynamic: %p\n", info->finfo.dynamic);
    8080
    81         errno_t rc2 = rtld_prog_process(&info->finfo, &env);
    82         switch (rc2) {
    83         case EOK:
    84                 rc = EE_OK;
    85                 break;
    86         case ENOMEM:
    87                 rc = EE_MEMORY;
    88                 break;
    89         default:
    90                 DPRINTF("Unexpected error code from rtld_prog_process(): %s\n", str_error_name(rc2));
    91                 rc = EE_INVALID;
    92         }
    93 
     81        rc = rtld_prog_process(&info->finfo, &env);
    9482        info->env = env;
    9583#else
    96         rc = EE_UNSUPPORTED;
     84        rc = ENOTSUP;
    9785#endif
    9886        return rc;
  • uspace/lib/c/generic/elf/elf_mod.c

    r9259d20 r3e828ea  
    6464#define DPRINTF(...)
    6565
    66 static const char *error_codes[] = {
    67         "no error",
    68         "invalid image",
    69         "address space error",
    70         "incompatible image",
    71         "unsupported image type",
    72         "irrecoverable error",
    73         "file io error"
    74 };
    75 
    76 static unsigned int elf_load_module(elf_ld_t *elf);
    77 static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
    78 static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
     66static errno_t elf_load_module(elf_ld_t *elf);
     67static errno_t segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
     68static errno_t load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
    7969
    8070/** Load ELF binary from a file.
     
    9080 *                  extracted from the binary.
    9181 *
    92  * @return EE_OK on success or EE_xx error code.
    93  *
    94  */
    95 int elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info)
     82 * @return EOK on success or an error code.
     83 *
     84 */
     85errno_t elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info)
    9686{
    9787        elf_ld_t elf;
     
    10393        }
    10494        if (rc != EOK) {
    105                 return EE_IO;
     95                return rc;
    10696        }
    10797
     
    110100        elf.flags = flags;
    111101
    112         int ret = elf_load_module(&elf);
     102        rc = elf_load_module(&elf);
    113103
    114104        vfs_put(ofile);
    115         return ret;
    116 }
    117 
    118 int elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info)
     105        return rc;
     106}
     107
     108errno_t elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info)
    119109{
    120110        int file;
    121111        errno_t rc = vfs_lookup(path, 0, &file);
    122112        if (rc == EOK) {
    123                 int ret = elf_load_file(file, flags, info);
     113                rc = elf_load_file(file, flags, info);
    124114                vfs_put(file);
    125                 return ret;
     115                return rc;
    126116        } else {
    127                 return EE_IO;
     117                return EIO;
    128118        }
    129119}
     
    136126 *
    137127 * @param elf           Pointer to loader state buffer.
    138  * @return EE_OK on success or EE_xx error code.
    139  */
    140 static unsigned int elf_load_module(elf_ld_t *elf)
     128 * @return EOK on success or an error code.
     129 */
     130static errno_t elf_load_module(elf_ld_t *elf)
    141131{
    142132        elf_header_t header_buf;
     
    144134        aoff64_t pos = 0;
    145135        size_t nr;
    146         int i, ret;
     136        int i;
    147137        errno_t rc;
    148138
     
    150140        if (rc != EOK || nr != sizeof(elf_header_t)) {
    151141                DPRINTF("Read error.\n");
    152                 return EE_IO;
     142                return EIO;
    153143        }
    154144
     
    159149            header->e_ident[EI_MAG3] != ELFMAG3) {
    160150                DPRINTF("Invalid header.\n");
    161                 return EE_INVALID;
     151                return EINVAL;
    162152        }
    163153
     
    169159            header->e_ident[EI_CLASS] != ELF_CLASS) {
    170160                DPRINTF("Incompatible data/version/class.\n");
    171                 return EE_INCOMPATIBLE;
     161                return EINVAL;
    172162        }
    173163
     
    175165                DPRINTF("e_phentsize: %u != %zu\n", header->e_phentsize,
    176166                    sizeof(elf_segment_header_t));
    177                 return EE_INCOMPATIBLE;
     167                return EINVAL;
    178168        }
    179169
     
    181171        if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
    182172                DPRINTF("Object type %d is not supported\n", header->e_type);
    183                 return EE_UNSUPPORTED;
     173                return ENOTSUP;
    184174        }
    185175
    186176        if (header->e_phoff == 0) {
    187177                DPRINTF("Program header table is not present!\n");
    188                 return EE_UNSUPPORTED;
     178                return ENOTSUP;
    189179        }
    190180
     
    203193        if (phdr_len > sizeof(phdr)) {
    204194                DPRINTF("more than %d program headers\n", phdr_cap);
    205                 return EE_UNSUPPORTED;
     195                return ENOTSUP;
    206196        }
    207197
     
    210200        if (rc != EOK || nr != phdr_len) {
    211201                DPRINTF("Read error.\n");
    212                 return EE_IO;
     202                return EIO;
    213203        }
    214204
     
    231221        if (base_offset != 0) {
    232222                DPRINTF("ELF headers not present in the text segment.\n");
    233                 return EE_INVALID;
     223                return EINVAL;
    234224        }
    235225
     
    240230                if (module_base != 0) {
    241231                        DPRINTF("Unexpected shared object format.\n");
    242                         return EE_INVALID;
     232                        return EINVAL;
    243233                }
    244234
     
    258248                if (area == AS_MAP_FAILED) {
    259249                        DPRINTF("Can't find suitable memory area.\n");
    260                         return EE_MEMORY;
     250                        return ENOMEM;
    261251                }
    262252
     
    270260                        continue;
    271261
    272                 ret = load_segment(elf, &phdr[i]);
    273                 if (ret != EE_OK)
    274                         return ret;
     262                rc = load_segment(elf, &phdr[i]);
     263                if (rc != EOK)
     264                        return rc;
    275265        }
    276266
     
    292282                        continue;
    293283
    294                 ret = segment_header(elf, &phdr[i]);
    295                 if (ret != EE_OK)
    296                         return ret;
     284                rc = segment_header(elf, &phdr[i]);
     285                if (rc != EOK)
     286                        return rc;
    297287        }
    298288
     
    302292        DPRINTF("Done.\n");
    303293
    304         return EE_OK;
    305 }
    306 
    307 /** Print error message according to error code.
    308  *
    309  * @param rc Return code returned by elf_load().
    310  *
    311  * @return NULL terminated description of error.
    312  */
    313 const char *elf_error(unsigned int rc)
    314 {
    315         assert(rc < sizeof(error_codes) / sizeof(char *));
    316 
    317         return error_codes[rc];
     294        return EOK;
    318295}
    319296
     
    338315 * @param entry Segment header.
    339316 *
    340  * @return EE_OK on success, error code otherwise.
    341  */
    342 static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
     317 * @return EOK on success, error code otherwise.
     318 */
     319static errno_t segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
    343320{
    344321        switch (entry->p_type) {
     
    358335                if (entry->p_filesz == 0) {
    359336                        DPRINTF("Zero-sized ELF interp string.\n");
    360                         return EE_INVALID;
     337                        return EINVAL;
    361338                }
    362339                if (elf->info->interp[entry->p_filesz - 1] != '\0') {
    363340                        DPRINTF("Unterminated ELF interp string.\n");
    364                         return EE_INVALID;
     341                        return EINVAL;
    365342                }
    366343                DPRINTF("interpreter: \"%s\"\n", elf->info->interp);
     
    389366        default:
    390367                DPRINTF("Segment p_type %d unknown.\n", entry->p_type);
    391                 return EE_UNSUPPORTED;
    392                 break;
    393         }
    394         return EE_OK;
     368                return ENOTSUP;
     369                break;
     370        }
     371        return EOK;
    395372}
    396373
     
    400377 * @param entry Program header entry describing segment to be loaded.
    401378 *
    402  * @return EE_OK on success, error code otherwise.
    403  */
    404 int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
     379 * @return EOK on success, error code otherwise.
     380 */
     381errno_t load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
    405382{
    406383        void *a;
     
    435412                            entry->p_offset % entry->p_align,
    436413                            seg_addr % entry->p_align, entry->p_align);
    437                         return EE_INVALID;
     414                        return EINVAL;
    438415                }
    439416        }
     
    466443                DPRINTF("memory mapping failed (%p, %zu)\n",
    467444                    (void *) (base + bias), mem_sz);
    468                 return EE_MEMORY;
     445                return ENOMEM;
    469446        }
    470447
     
    479456        if (rc != EOK || nr != entry->p_filesz) {
    480457                DPRINTF("read error\n");
    481                 return EE_IO;
     458                return EIO;
    482459        }
    483460
     
    487464         */
    488465        if ((elf->flags & ELDF_RW) != 0)
    489                 return EE_OK;
     466                return EOK;
    490467
    491468        DPRINTF("as_area_change_flags(%p, %x)\n",
     
    494471        if (rc != EOK) {
    495472                DPRINTF("Failed to set memory area flags.\n");
    496                 return EE_MEMORY;
     473                return ENOMEM;
    497474        }
    498475
     
    500477                /* Enforce SMC coherence for the segment */
    501478                if (smc_coherence(seg_ptr, entry->p_filesz))
    502                         return EE_MEMORY;
    503         }
    504 
    505         return EE_OK;
     479                        return ENOMEM;
     480        }
     481
     482        return EOK;
    506483}
    507484
  • uspace/lib/c/generic/private/stdio.h

    r9259d20 r3e828ea  
    4040#include <async.h>
    4141#include <stddef.h>
     42#include <offset.h>
    4243
    4344/** Maximum characters that can be pushed back by ungetc() */
     
    5455        int (*flush)(FILE *stream);
    5556} __stream_ops_t;
     57
     58enum __buffer_state {
     59        /** Buffer is empty */
     60        _bs_empty,
     61
     62        /** Buffer contains data to be written */
     63        _bs_write,
     64
     65        /** Buffer contains prefetched data for reading */
     66        _bs_read
     67};
    5668
    5769struct _IO_FILE {
     
    8799
    88100        /** Buffering type */
    89         enum _buffer_type btype;
     101        enum __buffer_type btype;
    90102
    91103        /** Buffer */
     
    96108
    97109        /** Buffer state */
    98         enum _buffer_state buf_state;
     110        enum __buffer_state buf_state;
    99111
    100112        /** Buffer I/O pointer */
  • uspace/lib/c/generic/rtld/module.c

    r9259d20 r3e828ea  
    6565
    6666        module = calloc(1, sizeof(module_t));
    67         if (module == NULL)
     67        if (module == NULL) {
     68                DPRINTF("malloc failed\n");
    6869                return ENOMEM;
     70        }
    6971
    7072        module->id = rtld_get_next_id(rtld);
     
    182184        char name_buf[NAME_BUF_SIZE];
    183185        module_t *m;
    184         int rc;
     186        errno_t rc;
    185187
    186188        m = calloc(1, sizeof(module_t));
    187189        if (m == NULL) {
    188                 printf("malloc failed\n");
    189                 exit(1);
     190                DPRINTF("malloc failed\n");
     191                goto error;
    190192        }
    191193
     
    197199
    198200        if (str_size(name) > NAME_BUF_SIZE - 2) {
    199                 printf("soname too long. increase NAME_BUF_SIZE\n");
    200                 exit(1);
     201                DPRINTF("soname too long. increase NAME_BUF_SIZE\n");
     202                goto error;
    201203        }
    202204
     
    208210
    209211        rc = elf_load_file_name(name_buf, RTLD_MODULE_LDF, &info);
    210         if (rc != EE_OK) {
    211                 printf("Failed to load '%s'\n", name_buf);
    212                 exit(1);
     212        if (rc != EOK) {
     213                DPRINTF("Failed to load '%s'\n", name_buf);
     214                goto error;
    213215        }
    214216
     
    218220
    219221        if (info.dynamic == NULL) {
    220                 printf("Error: '%s' is not a dynamically-linked object.\n",
     222                DPRINTF("Error: '%s' is not a dynamically-linked object.\n",
    221223                    name_buf);
    222                 exit(1);
     224                goto error;
    223225        }
    224226
     
    243245
    244246        return m;
     247
     248error:
     249        if (m)
     250                free(m);
     251
     252        return NULL;
    245253}
    246254
    247255/** Load all modules on which m (transitively) depends.
    248256 */
    249 void module_load_deps(module_t *m, mlflags_t flags)
     257errno_t module_load_deps(module_t *m, mlflags_t flags)
    250258{
    251259        elf_dyn_t *dp;
     
    274282                /* There are no dependencies, so we are done. */
    275283                m->deps = NULL;
    276                 return;
     284                return EOK;
    277285        }
    278286
    279287        m->deps = malloc(n * sizeof(module_t *));
    280288        if (!m->deps) {
    281                 printf("malloc failed\n");
    282                 exit(1);
     289                DPRINTF("malloc failed\n");
     290                return ENOMEM;
    283291        }
    284292
     
    294302                        if (!dm) {
    295303                                dm = module_load(m->rtld, dep_name, flags);
    296                                 module_load_deps(dm, flags);
     304                                if (!dm) {
     305                                        return EINVAL;
     306                                }
     307
     308                                errno_t rc = module_load_deps(dm, flags);
     309                                if (rc != EOK) {
     310                                        return rc;
     311                                }
    297312                        }
    298313
     
    302317                ++dp;
    303318        }
     319
     320        return EOK;
    304321}
    305322
  • uspace/lib/c/generic/rtld/rtld.c

    r9259d20 r3e828ea  
    125125
    126126        DPRINTF("Load all program dependencies\n");
    127         module_load_deps(prog, 0);
     127        errno_t rc = module_load_deps(prog, 0);
     128        if (rc != EOK) {
     129                return rc;
     130        }
    128131
    129132        /* Compute static TLS size */
  • uspace/lib/c/generic/str.c

    r9259d20 r3e828ea  
    14711471        *end = '\0';
    14721472        return start;
    1473 }
    1474 
    1475 /** Convert string to uint64_t (internal variant).
    1476  *
    1477  * @param nptr   Pointer to string.
    1478  * @param endptr Pointer to the first invalid character is stored here.
    1479  * @param base   Zero or number between 2 and 36 inclusive.
    1480  * @param neg    Indication of unary minus is stored here.
    1481  * @apram result Result of the conversion.
    1482  *
    1483  * @return EOK if conversion was successful.
    1484  *
    1485  */
    1486 static errno_t str_uint(const char *nptr, char **endptr, unsigned int base,
    1487     bool *neg, uint64_t *result)
    1488 {
    1489         assert(endptr != NULL);
    1490         assert(neg != NULL);
    1491         assert(result != NULL);
    1492 
    1493         *neg = false;
    1494         const char *str = nptr;
    1495 
    1496         /* Ignore leading whitespace */
    1497         while (isspace(*str))
    1498                 str++;
    1499 
    1500         if (*str == '-') {
    1501                 *neg = true;
    1502                 str++;
    1503         } else if (*str == '+')
    1504                 str++;
    1505 
    1506         if (base == 0) {
    1507                 /* Decode base if not specified */
    1508                 base = 10;
    1509 
    1510                 if (*str == '0') {
    1511                         base = 8;
    1512                         str++;
    1513 
    1514                         switch (*str) {
    1515                         case 'b':
    1516                         case 'B':
    1517                                 base = 2;
    1518                                 str++;
    1519                                 break;
    1520                         case 'o':
    1521                         case 'O':
    1522                                 base = 8;
    1523                                 str++;
    1524                                 break;
    1525                         case 'd':
    1526                         case 'D':
    1527                         case 't':
    1528                         case 'T':
    1529                                 base = 10;
    1530                                 str++;
    1531                                 break;
    1532                         case 'x':
    1533                         case 'X':
    1534                                 base = 16;
    1535                                 str++;
    1536                                 break;
    1537                         default:
    1538                                 str--;
    1539                         }
    1540                 }
    1541         } else {
    1542                 /* Check base range */
    1543                 if ((base < 2) || (base > 36)) {
    1544                         *endptr = (char *) str;
    1545                         return EINVAL;
    1546                 }
    1547         }
    1548 
    1549         *result = 0;
    1550         const char *startstr = str;
    1551 
    1552         while (*str != 0) {
    1553                 unsigned int digit;
    1554 
    1555                 if ((*str >= 'a') && (*str <= 'z'))
    1556                         digit = *str - 'a' + 10;
    1557                 else if ((*str >= 'A') && (*str <= 'Z'))
    1558                         digit = *str - 'A' + 10;
    1559                 else if ((*str >= '0') && (*str <= '9'))
    1560                         digit = *str - '0';
    1561                 else
    1562                         break;
    1563 
    1564                 if (digit >= base)
    1565                         break;
    1566 
    1567                 uint64_t prev = *result;
    1568                 *result = (*result) * base + digit;
    1569 
    1570                 if (*result < prev) {
    1571                         /* Overflow */
    1572                         *endptr = (char *) str;
    1573                         return EOVERFLOW;
    1574                 }
    1575 
    1576                 str++;
    1577         }
    1578 
    1579         if (str == startstr) {
    1580                 /*
    1581                  * No digits were decoded => first invalid character is
    1582                  * the first character of the string.
    1583                  */
    1584                 str = nptr;
    1585         }
    1586 
    1587         *endptr = (char *) str;
    1588 
    1589         if (str == nptr)
    1590                 return EINVAL;
    1591 
    1592         return EOK;
    1593 }
    1594 
    1595 /** Convert string to uint8_t.
    1596  *
    1597  * @param nptr   Pointer to string.
    1598  * @param endptr If not NULL, pointer to the first invalid character
    1599  *               is stored here.
    1600  * @param base   Zero or number between 2 and 36 inclusive.
    1601  * @param strict Do not allow any trailing characters.
    1602  * @param result Result of the conversion.
    1603  *
    1604  * @return EOK if conversion was successful.
    1605  *
    1606  */
    1607 errno_t str_uint8_t(const char *nptr, const char **endptr, unsigned int base,
    1608     bool strict, uint8_t *result)
    1609 {
    1610         assert(result != NULL);
    1611 
    1612         bool neg;
    1613         char *lendptr;
    1614         uint64_t res;
    1615         errno_t ret = str_uint(nptr, &lendptr, base, &neg, &res);
    1616 
    1617         if (endptr != NULL)
    1618                 *endptr = (char *) lendptr;
    1619 
    1620         if (ret != EOK)
    1621                 return ret;
    1622 
    1623         /* Do not allow negative values */
    1624         if (neg)
    1625                 return EINVAL;
    1626 
    1627         /*
    1628          * Check whether we are at the end of
    1629          * the string in strict mode
    1630          */
    1631         if ((strict) && (*lendptr != 0))
    1632                 return EINVAL;
    1633 
    1634         /* Check for overflow */
    1635         uint8_t _res = (uint8_t) res;
    1636         if (_res != res)
    1637                 return EOVERFLOW;
    1638 
    1639         *result = _res;
    1640 
    1641         return EOK;
    1642 }
    1643 
    1644 /** Convert string to uint16_t.
    1645  *
    1646  * @param nptr   Pointer to string.
    1647  * @param endptr If not NULL, pointer to the first invalid character
    1648  *               is stored here.
    1649  * @param base   Zero or number between 2 and 36 inclusive.
    1650  * @param strict Do not allow any trailing characters.
    1651  * @param result Result of the conversion.
    1652  *
    1653  * @return EOK if conversion was successful.
    1654  *
    1655  */
    1656 errno_t str_uint16_t(const char *nptr, const char **endptr, unsigned int base,
    1657     bool strict, uint16_t *result)
    1658 {
    1659         assert(result != NULL);
    1660 
    1661         bool neg;
    1662         char *lendptr;
    1663         uint64_t res;
    1664         errno_t ret = str_uint(nptr, &lendptr, base, &neg, &res);
    1665 
    1666         if (endptr != NULL)
    1667                 *endptr = (char *) lendptr;
    1668 
    1669         if (ret != EOK)
    1670                 return ret;
    1671 
    1672         /* Do not allow negative values */
    1673         if (neg)
    1674                 return EINVAL;
    1675 
    1676         /*
    1677          * Check whether we are at the end of
    1678          * the string in strict mode
    1679          */
    1680         if ((strict) && (*lendptr != 0))
    1681                 return EINVAL;
    1682 
    1683         /* Check for overflow */
    1684         uint16_t _res = (uint16_t) res;
    1685         if (_res != res)
    1686                 return EOVERFLOW;
    1687 
    1688         *result = _res;
    1689 
    1690         return EOK;
    1691 }
    1692 
    1693 /** Convert string to uint32_t.
    1694  *
    1695  * @param nptr   Pointer to string.
    1696  * @param endptr If not NULL, pointer to the first invalid character
    1697  *               is stored here.
    1698  * @param base   Zero or number between 2 and 36 inclusive.
    1699  * @param strict Do not allow any trailing characters.
    1700  * @param result Result of the conversion.
    1701  *
    1702  * @return EOK if conversion was successful.
    1703  *
    1704  */
    1705 errno_t str_uint32_t(const char *nptr, const char **endptr, unsigned int base,
    1706     bool strict, uint32_t *result)
    1707 {
    1708         assert(result != NULL);
    1709 
    1710         bool neg;
    1711         char *lendptr;
    1712         uint64_t res;
    1713         errno_t ret = str_uint(nptr, &lendptr, base, &neg, &res);
    1714 
    1715         if (endptr != NULL)
    1716                 *endptr = (char *) lendptr;
    1717 
    1718         if (ret != EOK)
    1719                 return ret;
    1720 
    1721         /* Do not allow negative values */
    1722         if (neg)
    1723                 return EINVAL;
    1724 
    1725         /*
    1726          * Check whether we are at the end of
    1727          * the string in strict mode
    1728          */
    1729         if ((strict) && (*lendptr != 0))
    1730                 return EINVAL;
    1731 
    1732         /* Check for overflow */
    1733         uint32_t _res = (uint32_t) res;
    1734         if (_res != res)
    1735                 return EOVERFLOW;
    1736 
    1737         *result = _res;
    1738 
    1739         return EOK;
    1740 }
    1741 
    1742 /** Convert string to uint64_t.
    1743  *
    1744  * @param nptr   Pointer to string.
    1745  * @param endptr If not NULL, pointer to the first invalid character
    1746  *               is stored here.
    1747  * @param base   Zero or number between 2 and 36 inclusive.
    1748  * @param strict Do not allow any trailing characters.
    1749  * @param result Result of the conversion.
    1750  *
    1751  * @return EOK if conversion was successful.
    1752  *
    1753  */
    1754 errno_t str_uint64_t(const char *nptr, const char **endptr, unsigned int base,
    1755     bool strict, uint64_t *result)
    1756 {
    1757         assert(result != NULL);
    1758 
    1759         bool neg;
    1760         char *lendptr;
    1761         errno_t ret = str_uint(nptr, &lendptr, base, &neg, result);
    1762 
    1763         if (endptr != NULL)
    1764                 *endptr = (char *) lendptr;
    1765 
    1766         if (ret != EOK)
    1767                 return ret;
    1768 
    1769         /* Do not allow negative values */
    1770         if (neg)
    1771                 return EINVAL;
    1772 
    1773         /*
    1774          * Check whether we are at the end of
    1775          * the string in strict mode
    1776          */
    1777         if ((strict) && (*lendptr != 0))
    1778                 return EINVAL;
    1779 
    1780         return EOK;
    1781 }
    1782 
    1783 /** Convert string to int64_t.
    1784  *
    1785  * @param nptr   Pointer to string.
    1786  * @param endptr If not NULL, pointer to the first invalid character
    1787  *               is stored here.
    1788  * @param base   Zero or number between 2 and 36 inclusive.
    1789  * @param strict Do not allow any trailing characters.
    1790  * @param result Result of the conversion.
    1791  *
    1792  * @return EOK if conversion was successful.
    1793  *
    1794  */
    1795 int str_int64_t(const char *nptr, const char **endptr, unsigned int base,
    1796     bool strict, int64_t *result)
    1797 {
    1798         assert(result != NULL);
    1799 
    1800         bool neg;
    1801         char *lendptr;
    1802         uint64_t unsigned_result;
    1803         int ret = str_uint(nptr, &lendptr, base, &neg, &unsigned_result);
    1804 
    1805         if (endptr != NULL)
    1806                 *endptr = (char *) lendptr;
    1807 
    1808         if (ret != EOK)
    1809                 return ret;
    1810 
    1811         /* Do not allow negative values */
    1812         if (neg) {
    1813                 if (unsigned_result == UINT64_MAX)
    1814                         return EINVAL;
    1815 
    1816                 *result = -(int64_t) unsigned_result;
    1817         } else
    1818                 *result = unsigned_result;
    1819 
    1820         /*
    1821          * Check whether we are at the end of
    1822          * the string in strict mode
    1823          */
    1824         if ((strict) && (*lendptr != 0))
    1825                 return EINVAL;
    1826 
    1827         return EOK;
    1828 }
    1829 
    1830 /** Convert string to size_t.
    1831  *
    1832  * @param nptr   Pointer to string.
    1833  * @param endptr If not NULL, pointer to the first invalid character
    1834  *               is stored here.
    1835  * @param base   Zero or number between 2 and 36 inclusive.
    1836  * @param strict Do not allow any trailing characters.
    1837  * @param result Result of the conversion.
    1838  *
    1839  * @return EOK if conversion was successful.
    1840  *
    1841  */
    1842 errno_t str_size_t(const char *nptr, const char **endptr, unsigned int base,
    1843     bool strict, size_t *result)
    1844 {
    1845         assert(result != NULL);
    1846 
    1847         bool neg;
    1848         char *lendptr;
    1849         uint64_t res;
    1850         errno_t ret = str_uint(nptr, &lendptr, base, &neg, &res);
    1851 
    1852         if (endptr != NULL)
    1853                 *endptr = (char *) lendptr;
    1854 
    1855         if (ret != EOK)
    1856                 return ret;
    1857 
    1858         /* Do not allow negative values */
    1859         if (neg)
    1860                 return EINVAL;
    1861 
    1862         /*
    1863          * Check whether we are at the end of
    1864          * the string in strict mode
    1865          */
    1866         if ((strict) && (*lendptr != 0))
    1867                 return EINVAL;
    1868 
    1869         /* Check for overflow */
    1870         size_t _res = (size_t) res;
    1871         if (_res != res)
    1872                 return EOVERFLOW;
    1873 
    1874         *result = _res;
    1875 
    1876         return EOK;
    18771473}
    18781474
  • uspace/lib/c/generic/strtol.c

    r9259d20 r3e828ea  
    4444#include <stdbool.h>
    4545#include <stdlib.h>
    46 
    47 // TODO: unit tests
     46#include <str.h>
     47
     48// FIXME: The original HelenOS functions return EOVERFLOW instead
     49//        of ERANGE. It's a pointless distinction from standard functions,
     50//        so we should change that. Beware the callers though.
     51
     52// TODO: more unit tests
    4853
    4954static inline int _digit_value(int c)
     
    6974}
    7075
     76static inline int _prefixbase(const char *restrict *nptrptr, bool nonstd)
     77{
     78        const char *nptr = *nptrptr;
     79
     80        if (nptr[0] != '0')
     81                return 10;
     82
     83        if (nptr[1] == 'x' || nptr[1] == 'X') {
     84                if (_digit_value(nptr[2]) < 16) {
     85                        *nptrptr += 2;
     86                        return 16;
     87                }
     88        }
     89
     90        if (nonstd) {
     91                switch (nptr[1]) {
     92                case 'b':
     93                case 'B':
     94                        if (_digit_value(nptr[2]) < 2) {
     95                                *nptrptr += 2;
     96                                return 2;
     97                        }
     98                        break;
     99                case 'o':
     100                case 'O':
     101                        if (_digit_value(nptr[2]) < 8) {
     102                                *nptrptr += 2;
     103                                return 8;
     104                        }
     105                        break;
     106                case 'd':
     107                case 'D':
     108                case 't':
     109                case 'T':
     110                        if (_digit_value(nptr[2]) < 10) {
     111                                *nptrptr += 2;
     112                                return 10;
     113                        }
     114                        break;
     115                }
     116        }
     117
     118        return 8;
     119}
     120
    71121static inline uintmax_t _strtoumax(
    72122    const char *restrict nptr, char **restrict endptr, int base,
    73     bool *restrict sgn)
     123    bool *restrict sgn, errno_t *err, bool nonstd)
    74124{
    75125        assert(nptr != NULL);
    76126        assert(sgn != NULL);
     127
     128        const char *first = nptr;
    77129
    78130        /* Skip leading whitespace. */
     
    96148        /* Figure out the base. */
    97149
    98         if (base == 0) {
    99                 if (*nptr == '0') {
    100                         if (tolower(nptr[1]) == 'x') {
    101                                 /* 0x... is hex. */
    102                                 base = 16;
    103                                 nptr += 2;
    104                         } else {
    105                                 /* 0... is octal. */
    106                                 base = 8;
    107                         }
    108                 } else {
    109                         /* Anything else is decimal by default. */
    110                         base = 10;
    111                 }
    112         } else if (base == 16) {
    113                 /* Allow hex number to be prefixed with "0x". */
    114                 if (nptr[0] == '0' && tolower(nptr[1]) == 'x') {
     150        if (base == 0)
     151                base = _prefixbase(&nptr, nonstd);
     152
     153        if (base == 16 && !nonstd) {
     154                /*
     155                 * Standard strto* functions allow hexadecimal prefix to be
     156                 * present when base is explicitly set to 16.
     157                 * Our nonstandard str_* functions don't allow it.
     158                 * I don't know if that is intended, just matching the original
     159                 * functionality here.
     160                 */
     161
     162                if (nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X') &&
     163                    _digit_value(nptr[2]) < base)
    115164                        nptr += 2;
    116                 }
    117         } else if (base < 0 || base == 1 || base > 36) {
    118                 errno = EINVAL;
     165        }
     166
     167        if (base < 2 || base > 36) {
     168                *err = EINVAL;
    119169                return 0;
    120170        }
    121171
    122         /* Read the value. */
     172        /* Must be at least one digit. */
     173
     174        if (_digit_value(*nptr) >= base) {
     175                /* No digits on input. */
     176                if (endptr != NULL)
     177                        *endptr = (char *) first;
     178                return 0;
     179        }
     180
     181        /* Read the value.  */
    123182
    124183        uintmax_t result = 0;
     
    127186
    128187        while (digit = _digit_value(*nptr), digit < base) {
    129 
    130188                if (result > max ||
    131189                    __builtin_add_overflow(result * base, digit, &result)) {
    132190
    133                         errno = ERANGE;
     191                        *err = nonstd ? EOVERFLOW : ERANGE;
    134192                        result = UINTMAX_MAX;
    135193                        break;
     
    145203                 * Move the pointer to the end of the number,
    146204                 * in case it isn't there already.
     205                 * This can happen when the number has legal formatting,
     206                 * but is out of range of the target type.
    147207                 */
    148208                while (_digit_value(*nptr) < base) {
     
    157217
    158218static inline intmax_t _strtosigned(const char *nptr, char **endptr, int base,
    159     intmax_t min, intmax_t max)
     219    intmax_t min, intmax_t max, errno_t *err, bool nonstd)
    160220{
    161221        bool sgn = false;
    162         uintmax_t number = _strtoumax(nptr, endptr, base, &sgn);
     222        uintmax_t number = _strtoumax(nptr, endptr, base, &sgn, err, nonstd);
    163223
    164224        if (number > (uintmax_t) max) {
     
    167227                }
    168228
    169                 errno = ERANGE;
     229                *err = nonstd ? EOVERFLOW : ERANGE;
    170230                return (sgn ? min : max);
    171231        }
     
    175235
    176236static inline uintmax_t _strtounsigned(const char *nptr, char **endptr, int base,
    177     uintmax_t max)
     237    uintmax_t max, errno_t *err, bool nonstd)
    178238{
    179239        bool sgn = false;
    180         uintmax_t number = _strtoumax(nptr, endptr, base, &sgn);
    181 
    182         if (sgn) {
    183                 if (number == 0) {
    184                         return 0;
    185                 } else {
    186                         errno = ERANGE;
    187                         return max;
    188                 }
     240        uintmax_t number = _strtoumax(nptr, endptr, base, &sgn, err, nonstd);
     241
     242        if (nonstd && sgn) {
     243                /* Do not allow negative values */
     244                *err = EINVAL;
     245                return 0;
    189246        }
    190247
    191248        if (number > max) {
    192                 errno = ERANGE;
     249                *err = nonstd ? EOVERFLOW : ERANGE;
    193250                return max;
    194251        }
    195252
    196         return number;
     253        return (sgn ? -number : number);
    197254}
    198255
     
    212269long strtol(const char *nptr, char **endptr, int base)
    213270{
    214         return _strtosigned(nptr, endptr, base, LONG_MIN, LONG_MAX);
     271        return _strtosigned(nptr, endptr, base, LONG_MIN, LONG_MAX, &errno, false);
    215272}
    216273
     
    230287unsigned long strtoul(const char *nptr, char **endptr, int base)
    231288{
    232         return _strtounsigned(nptr, endptr, base, ULONG_MAX);
     289        return _strtounsigned(nptr, endptr, base, ULONG_MAX, &errno, false);
    233290}
    234291
    235292long long strtoll(const char *nptr, char **endptr, int base)
    236293{
    237         return _strtosigned(nptr, endptr, base, LLONG_MIN, LLONG_MAX);
     294        return _strtosigned(nptr, endptr, base, LLONG_MIN, LLONG_MAX, &errno, false);
    238295}
    239296
    240297unsigned long long strtoull(const char *nptr, char **endptr, int base)
    241298{
    242         return _strtounsigned(nptr, endptr, base, ULLONG_MAX);
     299        return _strtounsigned(nptr, endptr, base, ULLONG_MAX, &errno, false);
    243300}
    244301
    245302intmax_t strtoimax(const char *nptr, char **endptr, int base)
    246303{
    247         return _strtosigned(nptr, endptr, base, INTMAX_MIN, INTMAX_MAX);
     304        return _strtosigned(nptr, endptr, base, INTMAX_MIN, INTMAX_MAX, &errno, false);
    248305}
    249306
    250307uintmax_t strtoumax(const char *nptr, char **endptr, int base)
    251308{
    252         return _strtounsigned(nptr, endptr, base, UINTMAX_MAX);
     309        return _strtounsigned(nptr, endptr, base, UINTMAX_MAX, &errno, false);
    253310}
    254311
     
    268325}
    269326
     327/** Convert string to uint8_t.
     328 *
     329 * @param nptr   Pointer to string.
     330 * @param endptr If not NULL, pointer to the first invalid character
     331 *               is stored here.
     332 * @param base   Zero or number between 2 and 36 inclusive.
     333 * @param strict Do not allow any trailing characters.
     334 * @param result Result of the conversion.
     335 *
     336 * @return EOK if conversion was successful.
     337 *
     338 */
     339errno_t str_uint8_t(const char *nptr, const char **endptr, unsigned int base,
     340    bool strict, uint8_t *result)
     341{
     342        assert(result != NULL);
     343
     344        errno_t rc = EOK;
     345        char *lendptr = (char *) nptr;
     346
     347        uintmax_t r = _strtounsigned(nptr, &lendptr, base, UINT8_MAX, &rc, true);
     348
     349        if (endptr)
     350                *endptr = lendptr;
     351
     352        if (rc != EOK)
     353                return rc;
     354
     355        if (strict && *lendptr != '\0')
     356                return EINVAL;
     357
     358        *result = r;
     359        return EOK;
     360}
     361
     362/** Convert string to uint16_t.
     363 *
     364 * @param nptr   Pointer to string.
     365 * @param endptr If not NULL, pointer to the first invalid character
     366 *               is stored here.
     367 * @param base   Zero or number between 2 and 36 inclusive.
     368 * @param strict Do not allow any trailing characters.
     369 * @param result Result of the conversion.
     370 *
     371 * @return EOK if conversion was successful.
     372 *
     373 */
     374errno_t str_uint16_t(const char *nptr, const char **endptr, unsigned int base,
     375    bool strict, uint16_t *result)
     376{
     377        assert(result != NULL);
     378
     379        errno_t rc = EOK;
     380        char *lendptr = (char *) nptr;
     381
     382        uintmax_t r = _strtounsigned(nptr, &lendptr, base, UINT16_MAX, &rc, true);
     383
     384        if (endptr)
     385                *endptr = lendptr;
     386
     387        if (rc != EOK)
     388                return rc;
     389
     390        if (strict && *lendptr != '\0')
     391                return EINVAL;
     392
     393        *result = r;
     394        return EOK;
     395}
     396
     397/** Convert string to uint32_t.
     398 *
     399 * @param nptr   Pointer to string.
     400 * @param endptr If not NULL, pointer to the first invalid character
     401 *               is stored here.
     402 * @param base   Zero or number between 2 and 36 inclusive.
     403 * @param strict Do not allow any trailing characters.
     404 * @param result Result of the conversion.
     405 *
     406 * @return EOK if conversion was successful.
     407 *
     408 */
     409errno_t str_uint32_t(const char *nptr, const char **endptr, unsigned int base,
     410    bool strict, uint32_t *result)
     411{
     412        assert(result != NULL);
     413
     414        errno_t rc = EOK;
     415        char *lendptr = (char *) nptr;
     416
     417        uintmax_t r = _strtounsigned(nptr, &lendptr, base, UINT32_MAX, &rc, true);
     418
     419        if (endptr)
     420                *endptr = lendptr;
     421
     422        if (rc != EOK)
     423                return rc;
     424
     425        if (strict && *lendptr != '\0')
     426                return EINVAL;
     427
     428        *result = r;
     429        return EOK;
     430}
     431
     432/** Convert string to uint64_t.
     433 *
     434 * @param nptr   Pointer to string.
     435 * @param endptr If not NULL, pointer to the first invalid character
     436 *               is stored here.
     437 * @param base   Zero or number between 2 and 36 inclusive.
     438 * @param strict Do not allow any trailing characters.
     439 * @param result Result of the conversion.
     440 *
     441 * @return EOK if conversion was successful.
     442 *
     443 */
     444errno_t str_uint64_t(const char *nptr, const char **endptr, unsigned int base,
     445    bool strict, uint64_t *result)
     446{
     447        assert(result != NULL);
     448
     449        errno_t rc = EOK;
     450        char *lendptr = (char *) nptr;
     451
     452        uintmax_t r = _strtounsigned(nptr, &lendptr, base, UINT64_MAX, &rc, true);
     453
     454        if (endptr)
     455                *endptr = lendptr;
     456
     457        if (rc != EOK)
     458                return rc;
     459
     460        if (strict && *lendptr != '\0')
     461                return EINVAL;
     462
     463        *result = r;
     464        return EOK;
     465}
     466
     467/** Convert string to int64_t.
     468 *
     469 * @param nptr   Pointer to string.
     470 * @param endptr If not NULL, pointer to the first invalid character
     471 *               is stored here.
     472 * @param base   Zero or number between 2 and 36 inclusive.
     473 * @param strict Do not allow any trailing characters.
     474 * @param result Result of the conversion.
     475 *
     476 * @return EOK if conversion was successful.
     477 *
     478 */
     479errno_t str_int64_t(const char *nptr, const char **endptr, unsigned int base,
     480    bool strict, int64_t *result)
     481{
     482        assert(result != NULL);
     483
     484        errno_t rc = EOK;
     485        char *lendptr = (char *) nptr;
     486
     487        intmax_t r = _strtosigned(nptr, &lendptr, base, INT64_MIN, INT64_MAX, &rc, true);
     488
     489        if (endptr)
     490                *endptr = lendptr;
     491
     492        if (rc != EOK)
     493                return rc;
     494
     495        if (strict && *lendptr != '\0')
     496                return EINVAL;
     497
     498        *result = r;
     499        return EOK;
     500}
     501
     502/** Convert string to size_t.
     503 *
     504 * @param nptr   Pointer to string.
     505 * @param endptr If not NULL, pointer to the first invalid character
     506 *               is stored here.
     507 * @param base   Zero or number between 2 and 36 inclusive.
     508 * @param strict Do not allow any trailing characters.
     509 * @param result Result of the conversion.
     510 *
     511 * @return EOK if conversion was successful.
     512 *
     513 */
     514errno_t str_size_t(const char *nptr, const char **endptr, unsigned int base,
     515    bool strict, size_t *result)
     516{
     517        assert(result != NULL);
     518
     519        errno_t rc = EOK;
     520        char *lendptr = (char *) nptr;
     521
     522        uintmax_t r = _strtounsigned(nptr, &lendptr, base, SIZE_MAX, &rc, true);
     523
     524        if (endptr)
     525                *endptr = lendptr;
     526
     527        if (rc != EOK)
     528                return rc;
     529
     530        if (strict && *lendptr != '\0')
     531                return EINVAL;
     532
     533        *result = r;
     534        return EOK;
     535}
     536
    270537/** @}
    271538 */
  • uspace/lib/c/generic/ubsan.c

    r9259d20 r3e828ea  
    3535};
    3636
     37struct type_mismatch_data_v1 {
     38        struct source_location loc;
     39        struct type_descriptor *type;
     40        unsigned char log_alignment;
     41        unsigned char type_check_kind;
     42};
     43
    3744struct overflow_data {
    3845        struct source_location loc;
     
    7380        struct source_location loc;
    7481        struct source_location attr_loc;
     82};
     83
     84struct pointer_overflow_data {
     85        struct source_location loc;
    7586};
    7687
     
    8192 */
    8293void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, unsigned long ptr);
     94void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data, unsigned long ptr);
    8395void __ubsan_handle_add_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
    8496void __ubsan_handle_sub_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
     
    99111void __ubsan_handle_nonnull_return(struct nonnull_return_data *data);
    100112void __ubsan_handle_builtin_unreachable(struct unreachable_data *data);
     113void __ubsan_handle_pointer_overflow(struct pointer_overflow_data *data,
     114    unsigned long base, unsigned long result);
    101115
    102116static void print_loc(const char *func, struct source_location *loc)
     
    121135}
    122136
     137void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
     138    unsigned long ptr)
     139{
     140        print_loc(__func__, &data->loc);
     141        PRINTF("Type: %s, alignment: %hhu, type_check_kind: %hhu\n",
     142            data->type->type_name, data->log_alignment, data->type_check_kind);
     143        ubsan_panic();
     144}
     145
    123146void __ubsan_handle_add_overflow(struct overflow_data *data,
    124147    unsigned long lhs,
     
    228251        ubsan_panic();
    229252}
     253
     254void __ubsan_handle_pointer_overflow(struct pointer_overflow_data *data,
     255    unsigned long base, unsigned long result)
     256{
     257        print_loc(__func__, &data->loc);
     258        ubsan_panic();
     259}
  • uspace/lib/c/include/adt/list.h

    r9259d20 r3e828ea  
    4242#include <stdint.h>
    4343#include <trace.h>
    44 
    45 /** Doubly linked list link. */
    46 typedef struct link {
    47         struct link *prev;  /**< Pointer to the previous item in the list. */
    48         struct link *next;  /**< Pointer to the next item in the list. */
    49 } link_t;
    50 
    51 /** Doubly linked list. */
    52 typedef struct list {
    53         link_t head;  /**< List head. Does not have any data. */
    54 } list_t;
    55 
    56 extern bool list_member(const link_t *, const list_t *);
    57 extern void list_splice(list_t *, link_t *);
    58 extern unsigned long list_count(const list_t *);
     44#include <_bits/decls.h>
     45
     46#ifndef __cplusplus
     47
     48/**
     49 * We don't define the macros in C++ to avoid polluting headers with
     50 * namespaceless names. We don't actually need them, so this is fine.
     51 * We still allow including the rest of the file (in `helenos` namespace)
     52 * so that we can expose publicly visible types that have list_t members.
     53 */
    5954
    6055/** Declare and initialize statically allocated list.
     
    138133        assert(!link_used(link))
    139134
     135#define list_pop(list, type, member) \
     136        ((type *) list_pop_internal(list, \
     137            (list_link_to_void(&(((type *) NULL)->member)) - NULL)))
     138
     139#endif  /* !__cplusplus */
     140
     141__HELENOS_DECLS_BEGIN;
     142
     143/** Doubly linked list link. */
     144typedef struct __adt_list_link {
     145        struct __adt_list_link *prev;  /**< Pointer to the previous item in the list. */
     146        struct __adt_list_link *next;  /**< Pointer to the next item in the list. */
     147} link_t;
     148
     149/** Doubly linked list. */
     150typedef struct {
     151        link_t head;  /**< List head. Does not have any data. */
     152} list_t;
     153
     154extern bool list_member(const link_t *, const list_t *);
     155extern void list_splice(list_t *, link_t *);
     156extern unsigned long list_count(const list_t *);
     157
    140158/** Returns true if the link is definitely part of a list. False if not sure. */
    141159static inline bool link_in_use(const link_t *link)
     
    425443}
    426444
    427 #define list_pop(list, type, member) \
    428         ((type *) list_pop_internal(list, \
    429             (list_link_to_void(&(((type *) NULL)->member)) - NULL)))
     445__HELENOS_DECLS_END;
    430446
    431447#endif
  • uspace/lib/c/include/assert.h

    r9259d20 r3e828ea  
    4141#define _LIBC_ASSERT_H_
    4242
     43#include <_bits/decls.h>
     44
    4345#ifndef __cplusplus
    4446#define static_assert _Static_assert
    4547#endif
     48
     49__C_DECLS_BEGIN;
    4650
    4751extern void __helenos_assert_abort(const char *, const char *, unsigned int)
     
    5054extern void __helenos_assert_quick_abort(const char *, const char *, unsigned int)
    5155    __attribute__((noreturn));
     56
     57__C_DECLS_END;
    5258
    5359#endif
  • uspace/lib/c/include/bsearch.h

    r9259d20 r3e828ea  
    3737
    3838#include <stddef.h>
     39#include <_bits/decls.h>
     40
     41__C_DECLS_BEGIN;
    3942
    4043extern void *bsearch(const void *, const void *, size_t, size_t,
    4144    int (*)(const void *, const void *));
     45
     46__C_DECLS_END;
    4247
    4348#endif
  • uspace/lib/c/include/ctype.h

    r9259d20 r3e828ea  
    3030#define _LIBC_CTYPE_H_
    3131
     32#include <_bits/decls.h>
     33
     34__C_DECLS_BEGIN;
    3235int islower(int);
    3336int isupper(int);
     
    4447int tolower(int);
    4548int toupper(int);
     49__C_DECLS_END;
    4650
    4751#endif
  • uspace/lib/c/include/dirent.h

    r9259d20 r3e828ea  
    3636#define _LIBC_DIRENT_H_
    3737
    38 #define NAME_MAX  256
     38#include <_bits/decls.h>
     39
     40__C_DECLS_BEGIN;
    3941
    4042struct dirent {
    41         char d_name[NAME_MAX + 1];
     43        char d_name[256];
    4244};
    4345
     
    4951extern int closedir(DIR *);
    5052
     53__C_DECLS_END;
     54
    5155#endif
    5256
  • uspace/lib/c/include/dlfcn.h

    r9259d20 r3e828ea  
    3737#define _LIBC_DLFCN_H_
    3838
     39#include <_bits/decls.h>
     40
     41__C_DECLS_BEGIN;
     42
    3943void *dlopen(const char *, int);
    4044void *dlsym(void *, const char *);
     45
     46__C_DECLS_END;
    4147
    4248#endif
  • uspace/lib/c/include/elf/elf_load.h

    r9259d20 r3e828ea  
    4545} elf_info_t;
    4646
    47 extern int elf_load(int, elf_info_t *);
     47extern errno_t elf_load(int, elf_info_t *);
    4848extern void elf_set_pcb(elf_info_t *, pcb_t *);
    4949
  • uspace/lib/c/include/elf/elf_mod.h

    r9259d20 r3e828ea  
    4242#include <stdint.h>
    4343#include <loader/pcb.h>
    44 
    45 /**
    46  * ELF error return codes
    47  */
    48 #define EE_OK                   0       /* No error */
    49 #define EE_INVALID              1       /* Invalid ELF image */
    50 #define EE_MEMORY               2       /* Cannot allocate address space */
    51 #define EE_INCOMPATIBLE         3       /* ELF image is not compatible with current architecture */
    52 #define EE_UNSUPPORTED          4       /* Non-supported ELF (e.g. dynamic ELFs) */
    53 #define EE_IRRECOVERABLE        5
    54 #define EE_IO                   6       /* Could not read file. */
    5544
    5645typedef enum {
     
    11099} elf_ld_t;
    111100
    112 extern const char *elf_error(unsigned int);
    113 extern int elf_load_file(int, eld_flags_t, elf_finfo_t *);
    114 extern int elf_load_file_name(const char *, eld_flags_t, elf_finfo_t *);
     101extern errno_t elf_load_file(int, eld_flags_t, elf_finfo_t *);
     102extern errno_t elf_load_file_name(const char *, eld_flags_t, elf_finfo_t *);
    115103
    116104#endif
  • uspace/lib/c/include/errno.h

    r9259d20 r3e828ea  
    3838#include <_bits/errno.h>
    3939#include <abi/errno.h>
     40#include <_bits/decls.h>
    4041
    41 #define errno  (*(__errno()))
     42__HELENOS_DECLS_BEGIN;
    4243
    4344extern errno_t *__errno(void) __attribute__((const));
     45
     46__HELENOS_DECLS_END;
     47
     48#ifdef __cplusplus
     49#define errno  (*(::helenos::__errno()))
     50#else
     51#define errno  (*(__errno()))
     52#endif
    4453
    4554#endif
  • uspace/lib/c/include/fibril.h

    r9259d20 r3e828ea  
    3636#define _LIBC_FIBRIL_H_
    3737
    38 #include <types/common.h>
    3938#include <time.h>
     39#include <_bits/errno.h>
    4040#include <_bits/__noreturn.h>
     41#include <_bits/decls.h>
     42
     43__HELENOS_DECLS_BEGIN;
    4144
    4245typedef struct fibril fibril_t;
     
    7174extern __noreturn void fibril_exit(long);
    7275
     76__HELENOS_DECLS_END;
     77
    7378#endif
    7479
  • uspace/lib/c/include/fibril_synch.h

    r9259d20 r3e828ea  
    4040#include <time.h>
    4141#include <stdbool.h>
    42 
    43 typedef struct {
    44         fibril_owner_info_t oi;  /**< Keep this the first thing. */
    45         int counter;
    46         list_t waiters;
    47 } fibril_mutex_t;
     42#include <_bits/decls.h>
     43
     44#ifndef __cplusplus
    4845
    4946#define FIBRIL_MUTEX_INITIALIZER(name) \
     
    5855#define FIBRIL_MUTEX_INITIALIZE(name) \
    5956        fibril_mutex_t name = FIBRIL_MUTEX_INITIALIZER(name)
    60 
    61 typedef struct {
    62         fibril_owner_info_t oi;  /**< Keep this the first thing. */
    63         unsigned int writers;
    64         unsigned int readers;
    65         list_t waiters;
    66 } fibril_rwlock_t;
    6757
    6858#define FIBRIL_RWLOCK_INITIALIZER(name) \
     
    7969        fibril_rwlock_t name = FIBRIL_RWLOCK_INITIALIZER(name)
    8070
    81 typedef struct {
    82         list_t waiters;
    83 } fibril_condvar_t;
    84 
    8571#define FIBRIL_CONDVAR_INITIALIZER(name) \
    8672        { \
     
    9076#define FIBRIL_CONDVAR_INITIALIZE(name) \
    9177        fibril_condvar_t name = FIBRIL_CONDVAR_INITIALIZER(name)
     78
     79#define FIBRIL_SEMAPHORE_INITIALIZER(name, cnt) \
     80        { \
     81                .count = (cnt), \
     82                .waiters = LIST_INITIALIZER((name).waiters), \
     83        }
     84
     85#define FIBRIL_SEMAPHORE_INITIALIZE(name, cnt) \
     86        fibril_semaphore_t name = FIBRIL_SEMAPHORE_INITIALIZER(name, cnt)
     87
     88#endif
     89
     90__HELENOS_DECLS_BEGIN;
     91
     92typedef struct {
     93        fibril_owner_info_t oi;  /**< Keep this the first thing. */
     94        int counter;
     95        list_t waiters;
     96} fibril_mutex_t;
     97
     98typedef struct {
     99        fibril_owner_info_t oi;  /**< Keep this the first thing. */
     100        unsigned int writers;
     101        unsigned int readers;
     102        list_t waiters;
     103} fibril_rwlock_t;
     104
     105typedef struct {
     106        list_t waiters;
     107} fibril_condvar_t;
    92108
    93109typedef void (*fibril_timer_fun_t)(void *);
     
    134150} fibril_semaphore_t;
    135151
    136 #define FIBRIL_SEMAPHORE_INITIALIZER(name, cnt) \
    137         { \
    138                 .count = (cnt), \
    139                 .waiters = LIST_INITIALIZER((name).waiters), \
    140         }
    141 
    142 #define FIBRIL_SEMAPHORE_INITIALIZE(name, cnt) \
    143         fibril_semaphore_t name = FIBRIL_SEMAPHORE_INITIALIZER(name, cnt)
    144 
    145152extern void __fibril_synch_init(void);
    146153extern void __fibril_synch_fini(void);
     
    190197extern void mpsc_close(mpsc_t *);
    191198
     199__HELENOS_DECLS_END;
     200
    192201#endif
    193202
  • uspace/lib/c/include/malloc.h

    r9259d20 r3e828ea  
    3737
    3838#include <stddef.h>
     39#include <_bits/decls.h>
     40
     41__C_DECLS_BEGIN;
    3942
    4043extern void *malloc(size_t size)
     
    4245extern void *calloc(size_t nmemb, size_t size)
    4346    __attribute__((malloc));
    44 extern void *memalign(size_t align, size_t size)
    45     __attribute__((malloc));
    4647extern void *realloc(void *addr, size_t size)
    4748    __attribute__((warn_unused_result));
    4849extern void free(void *addr);
     50
     51__C_DECLS_END;
     52
     53#ifdef _HELENOS_SOURCE
     54__HELENOS_DECLS_BEGIN;
     55
     56extern void *memalign(size_t align, size_t size)
     57    __attribute__((malloc));
    4958extern void *heap_check(void);
     59
     60__HELENOS_DECLS_END;
     61#endif
    5062
    5163#endif
  • uspace/lib/c/include/mem.h

    r9259d20 r3e828ea  
    3838
    3939#include <stddef.h>
     40#include <_bits/decls.h>
     41
     42__C_DECLS_BEGIN;
    4043
    4144extern void *memset(void *, int, size_t)
     
    5053    __attribute__((nonnull(1)));
    5154
     55__C_DECLS_END;
     56
    5257#endif
    5358
  • uspace/lib/c/include/offset.h

    r9259d20 r3e828ea  
    3636#define _LIBC_OFFSET_H_
    3737
     38#ifndef _HELENOS_SOURCE
     39#error This file should only be included from HelenOS sources
     40#endif
     41
    3842#include <stdint.h>
     43#include <_bits/decls.h>
     44#include <_bits/off64_t.h>
    3945
    4046/* off64_t */
     
    5258#define PRIXOFF64 PRIX64
    5359
    54 /** Relative offset */
    55 typedef int64_t off64_t;
     60__HELENOS_DECLS_BEGIN;
    5661
    5762/** Absolute offset */
    5863typedef uint64_t aoff64_t;
     64
     65__HELENOS_DECLS_END;
    5966
    6067#endif
  • uspace/lib/c/include/qsort.h

    r9259d20 r3e828ea  
    3737
    3838#include <stddef.h>
     39#include <_bits/decls.h>
    3940
     41__C_DECLS_BEGIN;
    4042extern void qsort(void *, size_t, size_t, int (*)(const void *,
    4143    const void *));
     44__C_DECLS_END;
     45
     46#ifdef _HELENOS_SOURCE
     47__HELENOS_DECLS_BEGIN;
    4248extern void qsort_r(void *, size_t, size_t, int (*)(const void *,
    4349    const void *, void *), void *);
     50__HELENOS_DECLS_END;
     51#endif
    4452
    4553#endif
  • uspace/lib/c/include/rtld/elf_dyn.h

    r9259d20 r3e828ea  
    3939#include <libarch/rtld/elf_dyn.h>
    4040
    41 #define ELF32_R_SYM(i) ((i) >> 8)
    42 #define ELF32_R_TYPE(i) ((unsigned char)(i))
    43 
    44 #define ELF64_R_SYM(i) ((i) >> 32)
    45 #define ELF64_R_TYPE(i) ((i) & 0xffffffffL)
    46 
    47 struct elf32_dyn {
    48         elf_sword d_tag;
    49         union {
    50                 elf_word d_val;
    51                 elf32_addr d_ptr;
    52         } d_un;
    53 };
    54 
    55 struct elf64_dyn {
    56         elf_sxword d_tag;
    57         union {
    58                 elf_xword d_val;
    59                 elf64_addr d_ptr;
    60         } d_un;
    61 };
    62 
    63 struct elf32_rel {
    64         elf32_addr r_offset;
    65         elf_word r_info;
    66 };
    67 
    68 struct elf32_rela {
    69         elf32_addr r_offset;
    70         elf_word r_info;
    71         elf_sword r_addend;
    72 };
    73 
    74 struct elf64_rel {
    75         elf64_addr r_offset;
    76         elf_xword r_info;
    77 };
    78 
    79 struct elf64_rela {
    80         elf64_addr r_offset;
    81         elf_xword r_info;
    82         elf_sxword r_addend;
    83 };
    84 
    85 #ifdef __32_BITS__
    86 typedef struct elf32_dyn elf_dyn_t;
    87 typedef struct elf32_rel elf_rel_t;
    88 typedef struct elf32_rela elf_rela_t;
    89 #endif
    90 
    91 #ifdef __64_BITS__
    92 typedef struct elf64_dyn elf_dyn_t;
    93 typedef struct elf64_rel elf_rel_t;
    94 typedef struct elf64_rela elf_rela_t;
    95 #endif
    96 
    97 /*
    98  * Dynamic array tags
    99  */
    100 #define DT_NULL         0
    101 #define DT_NEEDED       1
    102 #define DT_PLTRELSZ     2
    103 #define DT_PLTGOT       3
    104 #define DT_HASH         4
    105 #define DT_STRTAB       5
    106 #define DT_SYMTAB       6
    107 #define DT_RELA         7
    108 #define DT_RELASZ       8
    109 #define DT_RELAENT      9
    110 #define DT_STRSZ        10
    111 #define DT_SYMENT       11
    112 #define DT_INIT         12
    113 #define DT_FINI         13
    114 #define DT_SONAME       14
    115 #define DT_RPATH        15
    116 #define DT_SYMBOLIC     16
    117 #define DT_REL          17
    118 #define DT_RELSZ        18
    119 #define DT_RELENT       19
    120 #define DT_PLTREL       20
    121 #define DT_DEBUG        21
    122 #define DT_TEXTREL      22
    123 #define DT_JMPREL       23
    124 #define DT_BIND_NOW     24
    125 #define DT_LOPROC       0x70000000
    126 #define DT_HIPROC       0x7fffffff
    127 
    128 /*
    129  * Special section indexes
    130  */
    131 #define SHN_UNDEF       0
    132 #define SHN_LORESERVE   0xff00
    133 #define SHN_LOPROC      0xff00
    134 #define SHN_HIPROC      0xff1f
    135 #define SHN_ABS         0xfff1
    136 #define SHN_COMMON      0xfff2
    137 #define SHN_HIRESERVE   0xffff
    138 
    139 /*
    140  * Special symbol table index
    141  */
    142 #define STN_UNDEF       0
    143 
    14441#endif
    14542
  • uspace/lib/c/include/rtld/module.h

    r9259d20 r3e828ea  
    4545extern module_t *module_find(rtld_t *, const char *);
    4646extern module_t *module_load(rtld_t *, const char *, mlflags_t);
    47 extern void module_load_deps(module_t *, mlflags_t);
     47extern errno_t module_load_deps(module_t *, mlflags_t);
    4848extern module_t *module_by_id(rtld_t *, unsigned long);
    4949
  • uspace/lib/c/include/rtld/rtld_arch.h

    r9259d20 r3e828ea  
    4343void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size);
    4444void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size);
     45void *func_get_addr(elf_symbol_t *, module_t *);
    4546
    4647void program_run(void *entry, pcb_t *pcb);
  • uspace/lib/c/include/setjmp.h

    r9259d20 r3e828ea  
    3434#define _LIBC_SETJMP_H_
    3535
    36 #ifdef __cplusplus
    37 extern "C" {
    38 #endif
    39 
    4036#include <libarch/fibril_context.h>
    4137#include <_bits/__noreturn.h>
     38#include <_bits/decls.h>
     39
     40__C_DECLS_BEGIN;
    4241
    4342typedef __context_t jmp_buf[1];
     
    4645extern __noreturn void __context_restore(__context_t *, int);
    4746
    48 #define setjmp __context_save
    4947extern __noreturn void longjmp(jmp_buf, int);
    5048
    51 #ifdef __cplusplus
    52 }
    53 #endif
     49__C_DECLS_END;
     50
     51#define setjmp __context_save
    5452
    5553#endif
  • uspace/lib/c/include/stdio.h

    r9259d20 r3e828ea  
    3737#define _LIBC_STDIO_H_
    3838
    39 #ifdef __cplusplus
    40 extern "C" {
    41 #endif
    42 
    43 #include <offset.h>
    4439#include <stdarg.h>
    4540#include <io/verify.h>
     
    4843#include <_bits/wchar_t.h>
    4944#include <_bits/wint_t.h>
    50 
    51 /** Forward declaration */
    52 struct _IO_FILE;
    53 typedef struct _IO_FILE FILE;
    54 
    55 /** File position */
    56 typedef struct {
    57         off64_t pos;
    58 } fpos_t;
     45#include <_bits/decls.h>
    5946
    6047#ifndef _HELENOS_SOURCE
     
    7057
    7158/** Max number of files that is guaranteed to be able to open at the same time */
    72 #define FOPEN_MAX VFS_MAX_OPEN_FILES
     59#define FOPEN_MAX 16
    7360
    7461/** Recommended size of fixed-size array for holding file names. */
     
    9279/** Minimum number of unique temporary file names */
    9380#define TMP_MAX 1000000
     81
     82__C_DECLS_BEGIN;
     83
     84/** Forward declaration */
     85struct _IO_FILE;
     86typedef struct _IO_FILE FILE;
     87
     88/** File position */
     89typedef struct {
     90        long long pos;
     91} fpos_t;
    9492
    9593extern FILE *stdin;
     
    9896
    9997/* Character and string input functions */
    100 #define getc fgetc
    10198extern int fgetc(FILE *);
    10299extern char *fgets(char *, int, FILE *);
    103100extern char *gets(char *, size_t) __attribute__((deprecated));
    104101
     102static inline int getc(FILE *f)
     103{
     104        return fgetc(f);
     105}
     106
    105107extern int getchar(void);
    106108
    107109/* Character and string output functions */
    108 #define putc fputc
    109110extern int fputc(int, FILE *);
    110111extern int fputs(const char *, FILE *);
     112
     113static inline int putc(int i, FILE *f)
     114{
     115        return fputc(i, f);
     116}
    111117
    112118extern int putchar(int);
     
    180186extern char *tmpnam(char *s);
    181187
     188__C_DECLS_END;
     189
    182190#ifdef _HELENOS_SOURCE
    183191
     192#include <_bits/off64_t.h>
     193
     194__HELENOS_DECLS_BEGIN;
     195
    184196/* Nonstandard extensions. */
    185197
    186 enum _buffer_type {
     198enum __buffer_type {
    187199        /** No buffering */
    188200        _IONBF,
     
    193205};
    194206
    195 enum _buffer_state {
    196         /** Buffer is empty */
    197         _bs_empty,
    198 
    199         /** Buffer contains data to be written */
    200         _bs_write,
    201 
    202         /** Buffer contains prefetched data for reading */
    203         _bs_read
    204 };
    205 
    206207extern int vprintf_length(const char *, va_list);
    207208extern int printf_length(const char *, ...)
     
    210211extern int fileno(FILE *);
    211212
    212 #include <offset.h>
    213 
    214213extern int fseek64(FILE *, off64_t, int);
    215214extern off64_t ftell64(FILE *);
    216215
    217 #endif
    218 
    219 #ifdef __cplusplus
    220 }
     216__HELENOS_DECLS_END;
    221217#endif
    222218
  • uspace/lib/c/include/stdlib.h

    r9259d20 r3e828ea  
    3636#define _LIBC_STDLIB_H_
    3737
    38 #ifdef __cplusplus
    39 extern "C" {
    40 #endif
    41 
    4238#include <_bits/size_t.h>
    4339#include <_bits/wchar_t.h>
     40#include <_bits/decls.h>
    4441#include <bsearch.h>
    4542#include <malloc.h>
    4643#include <qsort.h>
     44
     45#define EXIT_SUCCESS 0
     46#define EXIT_FAILURE 1
     47
     48#define RAND_MAX  714025
     49
     50#define MB_CUR_MAX 4
     51
     52__C_DECLS_BEGIN;
    4753
    4854/** Type returned by the div function */
     
    6975        long long rem;
    7076} lldiv_t;
    71 
    72 #define EXIT_FAILURE 1
    73 #define EXIT_SUCCESS 0
    74 
    75 #define RAND_MAX  714025
    76 
    77 #define MB_CUR_MAX 4
    7877
    7978extern long double strtold(const char *, char **);
     
    109108extern lldiv_t lldiv(long long, long long);
    110109
    111 #ifdef __cplusplus
    112 }
    113 #endif
     110__C_DECLS_END;
    114111
    115112#endif
  • uspace/lib/c/include/str.h

    r9259d20 r3e828ea  
    3838#define _LIBC_STR_H_
    3939
    40 #ifdef __cplusplus
    41 extern "C" {
    42 #endif
    43 
    4440#include <errno.h>
    4541#include <stdbool.h>
     
    4844
    4945#include <mem.h>
     46#include <_bits/decls.h>
     47
     48#ifndef __cplusplus
    5049
    5150/* Common Unicode characters */
     
    6362 */
    6463#define SPASCII_STR_BUFSIZE(spa_size) ((spa_size) + 1)
     64
     65#endif
     66
     67__HELENOS_DECLS_BEGIN;
    6568
    6669extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
     
    134137extern errno_t str_size_t(const char *, const char **, unsigned int, bool,
    135138    size_t *);
    136 extern int str_int64_t(const char *, const char **, unsigned int, bool,
     139extern errno_t str_int64_t(const char *, const char **, unsigned int, bool,
    137140    int64_t *);
    138141
     
    147150extern unsigned long strtoul(const char *, char **, int);
    148151
    149 #ifdef __cplusplus
    150 }
    151 #endif
     152__HELENOS_DECLS_END;
    152153
    153154#endif
  • uspace/lib/c/include/string.h

    r9259d20 r3e828ea  
    4141#endif
    4242
     43#include <_bits/decls.h>
    4344#include <_bits/size_t.h>
    4445#include <_bits/NULL.h>
    4546#include <mem.h>
     47
     48__C_DECLS_BEGIN;
    4649
    4750extern char *strcpy(char *, const char *);
     
    7073#endif
    7174
     75__C_DECLS_END;
     76
    7277#endif
    7378
  • uspace/lib/c/include/time.h

    r9259d20 r3e828ea  
    3636#define _LIBC_TIME_H_
    3737
    38 #ifdef __cplusplus
    39 extern "C" {
    40 #endif
     38#include <_bits/decls.h>
    4139
    4240/* ISO/IEC 9899:2011 7.27.1 (2) */
     
    5149
    5250#include <_bits/size_t.h>
     51
     52__C_DECLS_BEGIN;
    5353
    5454/* ISO/IEC 9899:2011 7.27.1 (3), (4) */
     
    106106    const struct tm *__restrict__);
    107107
     108__C_DECLS_END;
     109
    108110#ifdef _HELENOS_SOURCE
    109111
     
    114116#include <stdbool.h>
    115117#include <_bits/errno.h>
     118
     119__HELENOS_DECLS_BEGIN;
    116120
    117121typedef long long sec_t;
     
    155159extern void udelay(sysarg_t);
    156160
     161__HELENOS_DECLS_END;
     162
    157163#endif /* _HELENOS_SOURCE */
    158 
    159 #ifdef __cplusplus
    160 }
    161 #endif
    162164
    163165#endif
  • uspace/lib/c/include/vfs/vfs.h

    r9259d20 r3e828ea  
    4444#include <async.h>
    4545#include <offset.h>
    46 
    47 #define VFS_MAX_OPEN_FILES  128
    4846
    4947enum vfs_change_state_type {
  • uspace/lib/c/test/stdio/scanf.c

    r9259d20 r3e828ea  
    4343
    4444#pragma GCC diagnostic ignored "-Wformat-zero-length"
     45#pragma GCC diagnostic ignored "-Wformat"
     46#pragma GCC diagnostic ignored "-Wformat-extra-args"
    4547
    4648PCUT_INIT;
  • uspace/lib/c/test/string.c

    r9259d20 r3e828ea  
    2828
    2929/* Prevent an error from being generated */
    30 #undef _HELENOS_SOURCE
     30#define _REALLY_WANT_STRING_H
    3131#include <string.h>
    32 #define _HELENOS_SOURCE
    3332#include <pcut/pcut.h>
    3433
  • uspace/lib/c/test/strtol.c

    r9259d20 r3e828ea  
    3838#include <stdlib.h>
    3939#include <str.h>
     40#include <limits.h>
    4041
    4142PCUT_INIT;
     
    217218        /* Correct result. */
    218219        PCUT_ASSERT_INT_EQUALS(EOVERFLOW, rc);
    219         PCUT_ASSERT_UINT_EQUALS(UINT64_MAX, result);
    220220#endif
    221221
     
    245245        /* Correct result. */
    246246        PCUT_ASSERT_INT_EQUALS(EOVERFLOW, rc);
    247         PCUT_ASSERT_UINT_EQUALS(UINT64_MAX, result);
    248247#endif
     248}
     249
     250PCUT_TEST(strtoul_negative_wraparound)
     251{
     252        long output;
     253        char *endp;
     254        char *endp_unchanged = (char *) "endp_unchanged unique pointer";
     255        int errno_unchanged = -1;
     256        const char *input;
     257        int base;
     258
     259        /*
     260         * N2176 7.22.1.4 The strtol, strtoll, strtoul, and strtoull functions
     261         *
     262         * "If the subject sequence begins with a minus sign, the value
     263         * resulting from the conversion is negated (in the return type)."
     264         */
     265
     266        endp = endp_unchanged;
     267        errno = errno_unchanged;
     268        output = strtoul(input = "-10", &endp, base = 0);
     269        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     270        PCUT_ASSERT_PTR_EQUALS(input + 3, endp);
     271        PCUT_ASSERT_UINT_EQUALS(-(10ul), output);
    249272}
    250273
     
    404427        endp = endp_unchanged;
    405428        errno = errno_unchanged;
     429        output = strtol(input = "    0xg", &endp, base = 0);
     430        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     431        PCUT_ASSERT_PTR_EQUALS(input + 5, endp);
     432        PCUT_ASSERT_INT_EQUALS(0, output);
     433
     434        endp = endp_unchanged;
     435        errno = errno_unchanged;
    406436        output = strtol(input = "    0x1", &endp, base = 0);
    407437        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     
    418448        endp = endp_unchanged;
    419449        errno = errno_unchanged;
     450        output = strtol(input = "    0xg", &endp, base = 16);
     451        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     452        PCUT_ASSERT_PTR_EQUALS(input + 5, endp);
     453        PCUT_ASSERT_INT_EQUALS(0, output);
     454
     455        endp = endp_unchanged;
     456        errno = errno_unchanged;
     457        output = strtol(input = "    g", &endp, base = 16);
     458        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     459        PCUT_ASSERT_PTR_EQUALS(input, endp);
     460        PCUT_ASSERT_INT_EQUALS(0, output);
     461
     462        endp = endp_unchanged;
     463        errno = errno_unchanged;
    420464        output = strtol(input = "    0x1", &endp, base = 16);
    421465        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
    422466        PCUT_ASSERT_PTR_EQUALS(input + 7, endp);
    423467        PCUT_ASSERT_INT_EQUALS(1, output);
     468
     469        endp = endp_unchanged;
     470        errno = errno_unchanged;
     471        output = strtol(input = "    +", &endp, base = 0);
     472        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     473        PCUT_ASSERT_PTR_EQUALS(input, endp);
     474        PCUT_ASSERT_INT_EQUALS(0, output);
     475
     476        endp = endp_unchanged;
     477        errno = errno_unchanged;
     478        output = strtol(input = "    -", &endp, base = 0);
     479        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     480        PCUT_ASSERT_PTR_EQUALS(input, endp);
     481        PCUT_ASSERT_INT_EQUALS(0, output);
     482
     483        endp = endp_unchanged;
     484        errno = errno_unchanged;
     485        output = strtol(input = "    +", &endp, base = 10);
     486        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     487        PCUT_ASSERT_PTR_EQUALS(input, endp);
     488        PCUT_ASSERT_INT_EQUALS(0, output);
     489
     490        endp = endp_unchanged;
     491        errno = errno_unchanged;
     492        output = strtol(input = "    -", &endp, base = 10);
     493        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     494        PCUT_ASSERT_PTR_EQUALS(input, endp);
     495        PCUT_ASSERT_INT_EQUALS(0, output);
     496
     497        endp = endp_unchanged;
     498        errno = errno_unchanged;
     499        output = strtol(input = "+", &endp, base = 0);
     500        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     501        PCUT_ASSERT_PTR_EQUALS(input, endp);
     502        PCUT_ASSERT_INT_EQUALS(0, output);
     503
     504        endp = endp_unchanged;
     505        errno = errno_unchanged;
     506        output = strtol(input = "-", &endp, base = 0);
     507        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     508        PCUT_ASSERT_PTR_EQUALS(input, endp);
     509        PCUT_ASSERT_INT_EQUALS(0, output);
     510
     511        endp = endp_unchanged;
     512        errno = errno_unchanged;
     513        output = strtol(input = "+", &endp, base = 10);
     514        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     515        PCUT_ASSERT_PTR_EQUALS(input, endp);
     516        PCUT_ASSERT_INT_EQUALS(0, output);
     517
     518        endp = endp_unchanged;
     519        errno = errno_unchanged;
     520        output = strtol(input = "-", &endp, base = 10);
     521        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     522        PCUT_ASSERT_PTR_EQUALS(input, endp);
     523        PCUT_ASSERT_INT_EQUALS(0, output);
    424524}
    425525
Note: See TracChangeset for help on using the changeset viewer.