1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 2 /* 3 * stdlib function definitions for NOLIBC 4 * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu> 5 */ 6 7 #ifndef _NOLIBC_STDLIB_H 8 #define _NOLIBC_STDLIB_H 9 10 #include "std.h" 11 #include "arch.h" 12 #include "types.h" 13 #include "sys.h" 14 15 /* 16 * As much as possible, please keep functions alphabetically sorted. 17 */ 18 19 static __attribute__((unused)) 20 long atol(const char *s) 21 { 22 unsigned long ret = 0; 23 unsigned long d; 24 int neg = 0; 25 26 if (*s == '-') { 27 neg = 1; 28 s++; 29 } 30 31 while (1) { 32 d = (*s++) - '0'; 33 if (d > 9) 34 break; 35 ret *= 10; 36 ret += d; 37 } 38 39 return neg ? -ret : ret; 40 } 41 42 static __attribute__((unused)) 43 int atoi(const char *s) 44 { 45 return atol(s); 46 } 47 48 /* performs the opposite of atol() using a user-fed buffer. The buffer must be 49 * at least 21 bytes long (large enough for "-9223372036854775808"). 50 */ 51 static __attribute__((unused)) 52 const char *ltoa_r(long in, char *buffer) 53 { 54 char *pos = buffer + 21 - 1; 55 int neg = in < 0; 56 unsigned long n = neg ? -in : in; 57 58 *pos-- = '\0'; 59 do { 60 *pos-- = '0' + n % 10; 61 n /= 10; 62 if (pos < buffer) 63 return pos + 1; 64 } while (n); 65 66 if (neg) 67 *pos-- = '-'; 68 return pos + 1; 69 } 70 71 /* performs the opposite of atol() using a statically allocated buffer */ 72 static __attribute__((unused)) 73 const char *ltoa(long in) 74 { 75 /* large enough for -9223372036854775808 */ 76 static char buffer[21]; 77 return ltoa_r(in, buffer); 78 } 79 80 static __attribute__((unused)) 81 int msleep(unsigned int msecs) 82 { 83 struct timeval my_timeval = { msecs / 1000, (msecs % 1000) * 1000 }; 84 85 if (sys_select(0, 0, 0, 0, &my_timeval) < 0) 86 return (my_timeval.tv_sec * 1000) + 87 (my_timeval.tv_usec / 1000) + 88 !!(my_timeval.tv_usec % 1000); 89 else 90 return 0; 91 } 92 93 /* This one is not marked static as it's needed by libgcc for divide by zero */ 94 __attribute__((weak,unused)) 95 int raise(int signal) 96 { 97 return kill(getpid(), signal); 98 } 99 100 static __attribute__((unused)) 101 unsigned int sleep(unsigned int seconds) 102 { 103 struct timeval my_timeval = { seconds, 0 }; 104 105 if (sys_select(0, 0, 0, 0, &my_timeval) < 0) 106 return my_timeval.tv_sec + !!my_timeval.tv_usec; 107 else 108 return 0; 109 } 110 111 static __attribute__((unused)) 112 int tcsetpgrp(int fd, pid_t pid) 113 { 114 return ioctl(fd, TIOCSPGRP, &pid); 115 } 116 117 #endif /* _NOLIBC_STDLIB_H */ 118