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 /* Buffer used to store int-to-ASCII conversions. Will only be implemented if 17 * any of the related functions is implemented. The area is large enough to 18 * store "18446744073709551615" or "-9223372036854775808" and the final zero. 19 */ 20 static __attribute__((unused)) char itoa_buffer[21]; 21 22 /* 23 * As much as possible, please keep functions alphabetically sorted. 24 */ 25 26 static __attribute__((unused)) 27 long atol(const char *s) 28 { 29 unsigned long ret = 0; 30 unsigned long d; 31 int neg = 0; 32 33 if (*s == '-') { 34 neg = 1; 35 s++; 36 } 37 38 while (1) { 39 d = (*s++) - '0'; 40 if (d > 9) 41 break; 42 ret *= 10; 43 ret += d; 44 } 45 46 return neg ? -ret : ret; 47 } 48 49 static __attribute__((unused)) 50 int atoi(const char *s) 51 { 52 return atol(s); 53 } 54 55 /* Converts the unsigned long integer <in> to its hex representation into 56 * buffer <buffer>, which must be long enough to store the number and the 57 * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The 58 * buffer is filled from the first byte, and the number of characters emitted 59 * (not counting the trailing zero) is returned. The function is constructed 60 * in a way to optimize the code size and avoid any divide that could add a 61 * dependency on large external functions. 62 */ 63 static __attribute__((unused)) 64 int utoh_r(unsigned long in, char *buffer) 65 { 66 signed char pos = (~0UL > 0xfffffffful) ? 60 : 28; 67 int digits = 0; 68 int dig; 69 70 do { 71 dig = in >> pos; 72 in -= (uint64_t)dig << pos; 73 pos -= 4; 74 if (dig || digits || pos < 0) { 75 if (dig > 9) 76 dig += 'a' - '0' - 10; 77 buffer[digits++] = '0' + dig; 78 } 79 } while (pos >= 0); 80 81 buffer[digits] = 0; 82 return digits; 83 } 84 85 /* converts unsigned long <in> to an hex string using the static itoa_buffer 86 * and returns the pointer to that string. 87 */ 88 static inline __attribute__((unused)) 89 char *utoh(unsigned long in) 90 { 91 utoh_r(in, itoa_buffer); 92 return itoa_buffer; 93 } 94 95 /* Converts the unsigned long integer <in> to its string representation into 96 * buffer <buffer>, which must be long enough to store the number and the 97 * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for 98 * 4294967295 in 32-bit). The buffer is filled from the first byte, and the 99 * number of characters emitted (not counting the trailing zero) is returned. 100 * The function is constructed in a way to optimize the code size and avoid 101 * any divide that could add a dependency on large external functions. 102 */ 103 static __attribute__((unused)) 104 int utoa_r(unsigned long in, char *buffer) 105 { 106 unsigned long lim; 107 int digits = 0; 108 int pos = (~0UL > 0xfffffffful) ? 19 : 9; 109 int dig; 110 111 do { 112 for (dig = 0, lim = 1; dig < pos; dig++) 113 lim *= 10; 114 115 if (digits || in >= lim || !pos) { 116 for (dig = 0; in >= lim; dig++) 117 in -= lim; 118 buffer[digits++] = '0' + dig; 119 } 120 } while (pos--); 121 122 buffer[digits] = 0; 123 return digits; 124 } 125 126 /* Converts the signed long integer <in> to its string representation into 127 * buffer <buffer>, which must be long enough to store the number and the 128 * trailing zero (21 bytes for -9223372036854775808 in 64-bit, 12 for 129 * -2147483648 in 32-bit). The buffer is filled from the first byte, and the 130 * number of characters emitted (not counting the trailing zero) is returned. 131 */ 132 static __attribute__((unused)) 133 int itoa_r(long in, char *buffer) 134 { 135 char *ptr = buffer; 136 int len = 0; 137 138 if (in < 0) { 139 in = -in; 140 *(ptr++) = '-'; 141 len++; 142 } 143 len += utoa_r(in, ptr); 144 return len; 145 } 146 147 /* for historical compatibility, same as above but returns the pointer to the 148 * buffer. 149 */ 150 static inline __attribute__((unused)) 151 char *ltoa_r(long in, char *buffer) 152 { 153 itoa_r(in, buffer); 154 return buffer; 155 } 156 157 /* converts long integer <in> to a string using the static itoa_buffer and 158 * returns the pointer to that string. 159 */ 160 static inline __attribute__((unused)) 161 char *itoa(long in) 162 { 163 itoa_r(in, itoa_buffer); 164 return itoa_buffer; 165 } 166 167 /* converts long integer <in> to a string using the static itoa_buffer and 168 * returns the pointer to that string. Same as above, for compatibility. 169 */ 170 static inline __attribute__((unused)) 171 char *ltoa(long in) 172 { 173 itoa_r(in, itoa_buffer); 174 return itoa_buffer; 175 } 176 177 /* converts unsigned long integer <in> to a string using the static itoa_buffer 178 * and returns the pointer to that string. 179 */ 180 static inline __attribute__((unused)) 181 char *utoa(unsigned long in) 182 { 183 utoa_r(in, itoa_buffer); 184 return itoa_buffer; 185 } 186 187 /* Converts the unsigned 64-bit integer <in> to its hex representation into 188 * buffer <buffer>, which must be long enough to store the number and the 189 * trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from 190 * the first byte, and the number of characters emitted (not counting the 191 * trailing zero) is returned. The function is constructed in a way to optimize 192 * the code size and avoid any divide that could add a dependency on large 193 * external functions. 194 */ 195 static __attribute__((unused)) 196 int u64toh_r(uint64_t in, char *buffer) 197 { 198 signed char pos = 60; 199 int digits = 0; 200 int dig; 201 202 do { 203 if (sizeof(long) >= 8) { 204 dig = (in >> pos) & 0xF; 205 } else { 206 /* 32-bit platforms: avoid a 64-bit shift */ 207 uint32_t d = (pos >= 32) ? (in >> 32) : in; 208 dig = (d >> (pos & 31)) & 0xF; 209 } 210 if (dig > 9) 211 dig += 'a' - '0' - 10; 212 pos -= 4; 213 if (dig || digits || pos < 0) 214 buffer[digits++] = '0' + dig; 215 } while (pos >= 0); 216 217 buffer[digits] = 0; 218 return digits; 219 } 220 221 /* converts uint64_t <in> to an hex string using the static itoa_buffer and 222 * returns the pointer to that string. 223 */ 224 static inline __attribute__((unused)) 225 char *u64toh(uint64_t in) 226 { 227 u64toh_r(in, itoa_buffer); 228 return itoa_buffer; 229 } 230 231 /* Converts the unsigned 64-bit integer <in> to its string representation into 232 * buffer <buffer>, which must be long enough to store the number and the 233 * trailing zero (21 bytes for 18446744073709551615). The buffer is filled from 234 * the first byte, and the number of characters emitted (not counting the 235 * trailing zero) is returned. The function is constructed in a way to optimize 236 * the code size and avoid any divide that could add a dependency on large 237 * external functions. 238 */ 239 static __attribute__((unused)) 240 int u64toa_r(uint64_t in, char *buffer) 241 { 242 unsigned long long lim; 243 int digits = 0; 244 int pos = 19; /* start with the highest possible digit */ 245 int dig; 246 247 do { 248 for (dig = 0, lim = 1; dig < pos; dig++) 249 lim *= 10; 250 251 if (digits || in >= lim || !pos) { 252 for (dig = 0; in >= lim; dig++) 253 in -= lim; 254 buffer[digits++] = '0' + dig; 255 } 256 } while (pos--); 257 258 buffer[digits] = 0; 259 return digits; 260 } 261 262 /* Converts the signed 64-bit integer <in> to its string representation into 263 * buffer <buffer>, which must be long enough to store the number and the 264 * trailing zero (21 bytes for -9223372036854775808). The buffer is filled from 265 * the first byte, and the number of characters emitted (not counting the 266 * trailing zero) is returned. 267 */ 268 static __attribute__((unused)) 269 int i64toa_r(int64_t in, char *buffer) 270 { 271 char *ptr = buffer; 272 int len = 0; 273 274 if (in < 0) { 275 in = -in; 276 *(ptr++) = '-'; 277 len++; 278 } 279 len += u64toa_r(in, ptr); 280 return len; 281 } 282 283 /* converts int64_t <in> to a string using the static itoa_buffer and returns 284 * the pointer to that string. 285 */ 286 static inline __attribute__((unused)) 287 char *i64toa(int64_t in) 288 { 289 i64toa_r(in, itoa_buffer); 290 return itoa_buffer; 291 } 292 293 /* converts uint64_t <in> to a string using the static itoa_buffer and returns 294 * the pointer to that string. 295 */ 296 static inline __attribute__((unused)) 297 char *u64toa(uint64_t in) 298 { 299 u64toa_r(in, itoa_buffer); 300 return itoa_buffer; 301 } 302 303 static __attribute__((unused)) 304 int msleep(unsigned int msecs) 305 { 306 struct timeval my_timeval = { msecs / 1000, (msecs % 1000) * 1000 }; 307 308 if (sys_select(0, 0, 0, 0, &my_timeval) < 0) 309 return (my_timeval.tv_sec * 1000) + 310 (my_timeval.tv_usec / 1000) + 311 !!(my_timeval.tv_usec % 1000); 312 else 313 return 0; 314 } 315 316 /* This one is not marked static as it's needed by libgcc for divide by zero */ 317 __attribute__((weak,unused)) 318 int raise(int signal) 319 { 320 return kill(getpid(), signal); 321 } 322 323 static __attribute__((unused)) 324 unsigned int sleep(unsigned int seconds) 325 { 326 struct timeval my_timeval = { seconds, 0 }; 327 328 if (sys_select(0, 0, 0, 0, &my_timeval) < 0) 329 return my_timeval.tv_sec + !!my_timeval.tv_usec; 330 else 331 return 0; 332 } 333 334 static __attribute__((unused)) 335 int tcsetpgrp(int fd, pid_t pid) 336 { 337 return ioctl(fd, TIOCSPGRP, &pid); 338 } 339 340 #endif /* _NOLIBC_STDLIB_H */ 341