2022-02-07 17:23:19 +01:00
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
/*
* stdlib function definitions for NOLIBC
* Copyright ( C ) 2017 - 2021 Willy Tarreau < w @ 1 wt . eu >
*/
# ifndef _NOLIBC_STDLIB_H
# define _NOLIBC_STDLIB_H
# include "std.h"
# include "arch.h"
# include "types.h"
# include "sys.h"
2022-02-07 17:23:27 +01:00
/* Buffer used to store int-to-ASCII conversions. Will only be implemented if
* any of the related functions is implemented . The area is large enough to
* store " 18446744073709551615 " or " -9223372036854775808 " and the final zero .
*/
static __attribute__ ( ( unused ) ) char itoa_buffer [ 21 ] ;
2022-02-07 17:23:19 +01:00
/*
* As much as possible , please keep functions alphabetically sorted .
*/
static __attribute__ ( ( unused ) )
long atol ( const char * s )
{
unsigned long ret = 0 ;
unsigned long d ;
int neg = 0 ;
if ( * s = = ' - ' ) {
neg = 1 ;
s + + ;
}
while ( 1 ) {
d = ( * s + + ) - ' 0 ' ;
if ( d > 9 )
break ;
ret * = 10 ;
ret + = d ;
}
return neg ? - ret : ret ;
}
static __attribute__ ( ( unused ) )
int atoi ( const char * s )
{
return atol ( s ) ;
}
2022-02-07 17:23:27 +01:00
/* Converts the unsigned long integer <in> to its string representation into
* buffer < buffer > , which must be long enough to store the number and the
* trailing zero ( 21 bytes for 18446744073709551615 in 64 - bit , 11 for
* 4294967295 in 32 - bit ) . The buffer is filled from the first byte , and the
* number of characters emitted ( not counting the trailing zero ) is returned .
* The function is constructed in a way to optimize the code size and avoid
* any divide that could add a dependency on large external functions .
2022-02-07 17:23:26 +01:00
*/
static __attribute__ ( ( unused ) )
2022-02-07 17:23:27 +01:00
int utoa_r ( unsigned long in , char * buffer )
2022-02-07 17:23:26 +01:00
{
2022-02-07 17:23:27 +01:00
unsigned long lim ;
int digits = 0 ;
int pos = ( ~ 0UL > 0xfffffffful ) ? 19 : 9 ;
int dig ;
2022-02-07 17:23:26 +01:00
do {
2022-02-07 17:23:27 +01:00
for ( dig = 0 , lim = 1 ; dig < pos ; dig + + )
lim * = 10 ;
if ( digits | | in > = lim | | ! pos ) {
for ( dig = 0 ; in > = lim ; dig + + )
in - = lim ;
buffer [ digits + + ] = ' 0 ' + dig ;
}
} while ( pos - - ) ;
buffer [ digits ] = 0 ;
return digits ;
2022-02-07 17:23:26 +01:00
}
2022-02-07 17:23:27 +01:00
/* Converts the signed long integer <in> to its string representation into
* buffer < buffer > , which must be long enough to store the number and the
* trailing zero ( 21 bytes for - 9223372036854775808 in 64 - bit , 12 for
* - 2147483648 in 32 - bit ) . The buffer is filled from the first byte , and the
* number of characters emitted ( not counting the trailing zero ) is returned .
*/
2022-02-07 17:23:26 +01:00
static __attribute__ ( ( unused ) )
2022-02-07 17:23:27 +01:00
int itoa_r ( long in , char * buffer )
{
char * ptr = buffer ;
int len = 0 ;
if ( in < 0 ) {
in = - in ;
* ( ptr + + ) = ' - ' ;
len + + ;
}
len + = utoa_r ( in , ptr ) ;
return len ;
}
/* for historical compatibility, same as above but returns the pointer to the
* buffer .
*/
static inline __attribute__ ( ( unused ) )
char * ltoa_r ( long in , char * buffer )
{
itoa_r ( in , buffer ) ;
return buffer ;
}
/* converts long integer <in> to a string using the static itoa_buffer and
* returns the pointer to that string .
*/
static inline __attribute__ ( ( unused ) )
char * itoa ( long in )
{
itoa_r ( in , itoa_buffer ) ;
return itoa_buffer ;
}
/* converts long integer <in> to a string using the static itoa_buffer and
* returns the pointer to that string . Same as above , for compatibility .
*/
static inline __attribute__ ( ( unused ) )
char * ltoa ( long in )
{
itoa_r ( in , itoa_buffer ) ;
return itoa_buffer ;
}
/* converts unsigned long integer <in> to a string using the static itoa_buffer
* and returns the pointer to that string .
*/
static inline __attribute__ ( ( unused ) )
char * utoa ( unsigned long in )
2022-02-07 17:23:26 +01:00
{
2022-02-07 17:23:27 +01:00
utoa_r ( in , itoa_buffer ) ;
return itoa_buffer ;
2022-02-07 17:23:26 +01:00
}
2022-02-07 17:23:28 +01:00
/* Converts the unsigned 64-bit integer <in> to its string representation into
* buffer < buffer > , which must be long enough to store the number and the
* trailing zero ( 21 bytes for 18446744073709551615 ) . The buffer is filled from
* the first byte , and the number of characters emitted ( not counting the
* trailing zero ) is returned . The function is constructed in a way to optimize
* the code size and avoid any divide that could add a dependency on large
* external functions .
*/
static __attribute__ ( ( unused ) )
int u64toa_r ( uint64_t in , char * buffer )
{
unsigned long long lim ;
int digits = 0 ;
int pos = 19 ; /* start with the highest possible digit */
int dig ;
do {
for ( dig = 0 , lim = 1 ; dig < pos ; dig + + )
lim * = 10 ;
if ( digits | | in > = lim | | ! pos ) {
for ( dig = 0 ; in > = lim ; dig + + )
in - = lim ;
buffer [ digits + + ] = ' 0 ' + dig ;
}
} while ( pos - - ) ;
buffer [ digits ] = 0 ;
return digits ;
}
/* Converts the signed 64-bit integer <in> to its string representation into
* buffer < buffer > , which must be long enough to store the number and the
* trailing zero ( 21 bytes for - 9223372036854775808 ) . The buffer is filled from
* the first byte , and the number of characters emitted ( not counting the
* trailing zero ) is returned .
*/
static __attribute__ ( ( unused ) )
int i64toa_r ( int64_t in , char * buffer )
{
char * ptr = buffer ;
int len = 0 ;
if ( in < 0 ) {
in = - in ;
* ( ptr + + ) = ' - ' ;
len + + ;
}
len + = u64toa_r ( in , ptr ) ;
return len ;
}
/* converts int64_t <in> to a string using the static itoa_buffer and returns
* the pointer to that string .
*/
static inline __attribute__ ( ( unused ) )
char * i64toa ( int64_t in )
{
i64toa_r ( in , itoa_buffer ) ;
return itoa_buffer ;
}
/* converts uint64_t <in> to a string using the static itoa_buffer and returns
* the pointer to that string .
*/
static inline __attribute__ ( ( unused ) )
char * u64toa ( uint64_t in )
{
u64toa_r ( in , itoa_buffer ) ;
return itoa_buffer ;
}
2022-02-07 17:23:19 +01:00
static __attribute__ ( ( unused ) )
int msleep ( unsigned int msecs )
{
struct timeval my_timeval = { msecs / 1000 , ( msecs % 1000 ) * 1000 } ;
if ( sys_select ( 0 , 0 , 0 , 0 , & my_timeval ) < 0 )
return ( my_timeval . tv_sec * 1000 ) +
( my_timeval . tv_usec / 1000 ) +
! ! ( my_timeval . tv_usec % 1000 ) ;
else
return 0 ;
}
/* This one is not marked static as it's needed by libgcc for divide by zero */
__attribute__ ( ( weak , unused ) )
int raise ( int signal )
{
return kill ( getpid ( ) , signal ) ;
}
static __attribute__ ( ( unused ) )
unsigned int sleep ( unsigned int seconds )
{
struct timeval my_timeval = { seconds , 0 } ;
if ( sys_select ( 0 , 0 , 0 , 0 , & my_timeval ) < 0 )
return my_timeval . tv_sec + ! ! my_timeval . tv_usec ;
else
return 0 ;
}
static __attribute__ ( ( unused ) )
int tcsetpgrp ( int fd , pid_t pid )
{
return ioctl ( fd , TIOCSPGRP , & pid ) ;
}
# endif /* _NOLIBC_STDLIB_H */