xref: /openbmc/linux/tools/include/nolibc/stdlib.h (revision 66c397c4d2e15871c50940c168b7d4a76aaa08a9)
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 string representation into
56  * buffer <buffer>, which must be long enough to store the number and the
57  * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for
58  * 4294967295 in 32-bit). The buffer is filled from the first byte, and the
59  * number of characters emitted (not counting the trailing zero) is returned.
60  * The function is constructed in a way to optimize the code size and avoid
61  * any divide that could add a dependency on large external functions.
62  */
63 static __attribute__((unused))
64 int utoa_r(unsigned long in, char *buffer)
65 {
66 	unsigned long lim;
67 	int digits = 0;
68 	int pos = (~0UL > 0xfffffffful) ? 19 : 9;
69 	int dig;
70 
71 	do {
72 		for (dig = 0, lim = 1; dig < pos; dig++)
73 			lim *= 10;
74 
75 		if (digits || in >= lim || !pos) {
76 			for (dig = 0; in >= lim; dig++)
77 				in -= lim;
78 			buffer[digits++] = '0' + dig;
79 		}
80 	} while (pos--);
81 
82 	buffer[digits] = 0;
83 	return digits;
84 }
85 
86 /* Converts the signed long integer <in> to its string representation into
87  * buffer <buffer>, which must be long enough to store the number and the
88  * trailing zero (21 bytes for -9223372036854775808 in 64-bit, 12 for
89  * -2147483648 in 32-bit). The buffer is filled from the first byte, and the
90  * number of characters emitted (not counting the trailing zero) is returned.
91  */
92 static __attribute__((unused))
93 int itoa_r(long in, char *buffer)
94 {
95 	char *ptr = buffer;
96 	int len = 0;
97 
98 	if (in < 0) {
99 		in = -in;
100 		*(ptr++) = '-';
101 		len++;
102 	}
103 	len += utoa_r(in, ptr);
104 	return len;
105 }
106 
107 /* for historical compatibility, same as above but returns the pointer to the
108  * buffer.
109  */
110 static inline __attribute__((unused))
111 char *ltoa_r(long in, char *buffer)
112 {
113 	itoa_r(in, buffer);
114 	return buffer;
115 }
116 
117 /* converts long integer <in> to a string using the static itoa_buffer and
118  * returns the pointer to that string.
119  */
120 static inline __attribute__((unused))
121 char *itoa(long in)
122 {
123 	itoa_r(in, itoa_buffer);
124 	return itoa_buffer;
125 }
126 
127 /* converts long integer <in> to a string using the static itoa_buffer and
128  * returns the pointer to that string. Same as above, for compatibility.
129  */
130 static inline __attribute__((unused))
131 char *ltoa(long in)
132 {
133 	itoa_r(in, itoa_buffer);
134 	return itoa_buffer;
135 }
136 
137 /* converts unsigned long integer <in> to a string using the static itoa_buffer
138  * and returns the pointer to that string.
139  */
140 static inline __attribute__((unused))
141 char *utoa(unsigned long in)
142 {
143 	utoa_r(in, itoa_buffer);
144 	return itoa_buffer;
145 }
146 
147 static __attribute__((unused))
148 int msleep(unsigned int msecs)
149 {
150 	struct timeval my_timeval = { msecs / 1000, (msecs % 1000) * 1000 };
151 
152 	if (sys_select(0, 0, 0, 0, &my_timeval) < 0)
153 		return (my_timeval.tv_sec * 1000) +
154 			(my_timeval.tv_usec / 1000) +
155 			!!(my_timeval.tv_usec % 1000);
156 	else
157 		return 0;
158 }
159 
160 /* This one is not marked static as it's needed by libgcc for divide by zero */
161 __attribute__((weak,unused))
162 int raise(int signal)
163 {
164 	return kill(getpid(), signal);
165 }
166 
167 static __attribute__((unused))
168 unsigned int sleep(unsigned int seconds)
169 {
170 	struct timeval my_timeval = { seconds, 0 };
171 
172 	if (sys_select(0, 0, 0, 0, &my_timeval) < 0)
173 		return my_timeval.tv_sec + !!my_timeval.tv_usec;
174 	else
175 		return 0;
176 }
177 
178 static __attribute__((unused))
179 int tcsetpgrp(int fd, pid_t pid)
180 {
181 	return ioctl(fd, TIOCSPGRP, &pid);
182 }
183 
184 #endif /* _NOLIBC_STDLIB_H */
185