1 /*
2  * Copyright (c) 2019 Antmicro Ltd
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <logging/log.h>
8 LOG_MODULE_REGISTER(lib_extensions, LOG_LEVEL_DBG);
9 
10 #include <zephyr.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 
15 #include "libc_extensions.h"
16 
17 #define FN_MISSING() LOG_DBG("[IMPLEMENTATION MISSING : %s]\n", __func__)
18 
iscntrl(int c)19 int iscntrl(int c)
20 {
21 	/* All the characters placed before the space on the ASCII table
22 	 * and the 0x7F character (DEL) are control characters.
23 	 */
24 	return (int)(c < ' ' || c == 0x7F);
25 }
26 
strftime(char * dst,size_t dst_size,const char * fmt,const struct tm * tm)27 size_t strftime(char *dst, size_t dst_size,
28 		const char *fmt,
29 		const struct tm *tm)
30 {
31 	FN_MISSING();
32 
33 	return 0;
34 }
35 
difftime(time_t end,time_t beg)36 double difftime(time_t end, time_t beg)
37 {
38 	return end - beg;
39 }
40 
41 struct __strerr_wrap {
42 	int err;
43 	const char *errstr;
44 };
45 
46 /* Implementation suggested by @rakons in #16527 */
47 #define STRERR_DEFINE(e)	{e, #e}
48 
49 static const struct __strerr_wrap error_strings[] = {
50 	STRERR_DEFINE(EILSEQ),
51 	STRERR_DEFINE(EDOM),
52 	STRERR_DEFINE(ERANGE),
53 	STRERR_DEFINE(ENOTTY),
54 	STRERR_DEFINE(EACCES),
55 	STRERR_DEFINE(EPERM),
56 	STRERR_DEFINE(ENOENT),
57 	STRERR_DEFINE(ESRCH),
58 	STRERR_DEFINE(EEXIST),
59 	STRERR_DEFINE(ENOSPC),
60 	STRERR_DEFINE(ENOMEM),
61 	STRERR_DEFINE(EBUSY),
62 	STRERR_DEFINE(EINTR),
63 	STRERR_DEFINE(EAGAIN),
64 	STRERR_DEFINE(ESPIPE),
65 	STRERR_DEFINE(EXDEV),
66 	STRERR_DEFINE(EROFS),
67 	STRERR_DEFINE(ENOTEMPTY),
68 	STRERR_DEFINE(ECONNRESET),
69 	STRERR_DEFINE(ETIMEDOUT),
70 	STRERR_DEFINE(ECONNREFUSED),
71 	STRERR_DEFINE(EHOSTDOWN),
72 	STRERR_DEFINE(EHOSTUNREACH),
73 	STRERR_DEFINE(EADDRINUSE),
74 	STRERR_DEFINE(EPIPE),
75 	STRERR_DEFINE(EIO),
76 	STRERR_DEFINE(ENXIO),
77 	STRERR_DEFINE(ENOTBLK),
78 	STRERR_DEFINE(ENODEV),
79 	STRERR_DEFINE(ENOTDIR),
80 	STRERR_DEFINE(EISDIR),
81 	STRERR_DEFINE(ETXTBSY),
82 	STRERR_DEFINE(ENOEXEC),
83 	STRERR_DEFINE(EINVAL),
84 	STRERR_DEFINE(E2BIG),
85 	STRERR_DEFINE(ELOOP),
86 	STRERR_DEFINE(ENAMETOOLONG),
87 	STRERR_DEFINE(ENFILE),
88 	STRERR_DEFINE(EMFILE),
89 	STRERR_DEFINE(EBADF),
90 	STRERR_DEFINE(ECHILD),
91 	STRERR_DEFINE(EFAULT),
92 	STRERR_DEFINE(EFBIG),
93 	STRERR_DEFINE(EMLINK),
94 	STRERR_DEFINE(ENOLCK),
95 	STRERR_DEFINE(EDEADLK),
96 	STRERR_DEFINE(ECANCELED),
97 	STRERR_DEFINE(ENOSYS),
98 	STRERR_DEFINE(ENOMSG),
99 	STRERR_DEFINE(ENOSTR),
100 	STRERR_DEFINE(ENODATA),
101 	STRERR_DEFINE(ETIME),
102 	STRERR_DEFINE(ENOSR),
103 	STRERR_DEFINE(EPROTO),
104 	STRERR_DEFINE(EBADMSG),
105 	STRERR_DEFINE(ENOTSOCK),
106 	STRERR_DEFINE(EDESTADDRREQ),
107 	STRERR_DEFINE(EMSGSIZE),
108 	STRERR_DEFINE(EPROTOTYPE),
109 	STRERR_DEFINE(ENOPROTOOPT),
110 	STRERR_DEFINE(EPROTONOSUPPORT),
111 	STRERR_DEFINE(ESOCKTNOSUPPORT),
112 	STRERR_DEFINE(ENOTSUP),
113 	STRERR_DEFINE(EPFNOSUPPORT),
114 	STRERR_DEFINE(EAFNOSUPPORT),
115 	STRERR_DEFINE(EADDRNOTAVAIL),
116 	STRERR_DEFINE(ENETDOWN),
117 	STRERR_DEFINE(ENETUNREACH),
118 	STRERR_DEFINE(ENETRESET),
119 	STRERR_DEFINE(ECONNABORTED),
120 	STRERR_DEFINE(ENOBUFS),
121 	STRERR_DEFINE(EISCONN),
122 	STRERR_DEFINE(ENOTCONN),
123 	STRERR_DEFINE(ESHUTDOWN),
124 	STRERR_DEFINE(EALREADY),
125 	STRERR_DEFINE(EINPROGRESS),
126 };
127 
128 static char *strerr_unknown = "UNKNOWN";
129 
strerror(int err)130 char *strerror(int err)
131 {
132 	int i;
133 
134 	for (i = 0; i < ARRAY_SIZE(error_strings); ++i) {
135 		if (error_strings[i].err == err) {
136 			return (char *)error_strings[i].errstr;
137 		}
138 	}
139 
140 	return strerr_unknown;
141 }
142 
sscanf(const char * s,const char * format,...)143 int sscanf(const char *s, const char *format, ...)
144 {
145 	FN_MISSING();
146 
147 	return 0;
148 }
149 
atof(const char * str)150 double atof(const char *str)
151 {
152 	/* XXX good enough for civetweb uses */
153 	return (double)atoi(str);
154 }
155 
strtoll(const char * str,char ** endptr,int base)156 long long strtoll(const char *str, char **endptr, int base)
157 {
158 	/* XXX good enough for civetweb uses */
159 	return (long long)strtol(str, endptr, base);
160 }
161 
162 /*
163  * Most of the wrappers below are copies of the wrappers in net/sockets.h,
164  * but they are available only if CONFIG_NET_SOCKETS_POSIX_NAMES is enabled
165  * which is impossible here.
166  */
167 
getsockname(int sock,struct sockaddr * addr,socklen_t * addrlen)168 int getsockname(int sock, struct sockaddr *addr,
169 		socklen_t *addrlen)
170 {
171 	return zsock_getsockname(sock, addr, addrlen);
172 }
173 
poll(struct zsock_pollfd * fds,int nfds,int timeout)174 int poll(struct zsock_pollfd *fds, int nfds, int timeout)
175 {
176 	return zsock_poll(fds, nfds, timeout);
177 }
178 
getnameinfo(const struct sockaddr * addr,socklen_t addrlen,char * host,socklen_t hostlen,char * serv,socklen_t servlen,int flags)179 int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,
180 		char *host, socklen_t hostlen,
181 		char *serv, socklen_t servlen, int flags)
182 {
183 	return zsock_getnameinfo(addr, addrlen, host, hostlen,
184 				 serv, servlen, flags);
185 }
186 
send(int sock,const void * buf,size_t len,int flags)187 ssize_t send(int sock, const void *buf, size_t len, int flags)
188 {
189 	return zsock_send(sock, buf, len, flags);
190 }
191 
recv(int sock,void * buf,size_t max_len,int flags)192 ssize_t recv(int sock, void *buf, size_t max_len, int flags)
193 {
194 	return zsock_recv(sock, buf, max_len, flags);
195 }
196 
socket(int family,int type,int proto)197 int socket(int family, int type, int proto)
198 {
199 	return zsock_socket(family, type, proto);
200 }
201 
getaddrinfo(const char * host,const char * service,const struct zsock_addrinfo * hints,struct zsock_addrinfo ** res)202 int getaddrinfo(const char *host, const char *service,
203 		const struct zsock_addrinfo *hints,
204 		struct zsock_addrinfo **res)
205 {
206 	return zsock_getaddrinfo(host, service, hints, res);
207 }
208 
freeaddrinfo(struct zsock_addrinfo * ai)209 void freeaddrinfo(struct zsock_addrinfo *ai)
210 {
211 	zsock_freeaddrinfo(ai);
212 }
213 
connect(int sock,const struct sockaddr * addr,socklen_t addrlen)214 int connect(int sock, const struct sockaddr *addr,
215 	    socklen_t addrlen)
216 {
217 	return zsock_connect(sock, addr, addrlen);
218 }
219 
getsockopt(int sock,int level,int optname,void * optval,socklen_t * optlen)220 int getsockopt(int sock, int level, int optname,
221 	       void *optval, socklen_t *optlen)
222 {
223 	return zsock_getsockopt(sock, level, optname, optval, optlen);
224 }
225 
setsockopt(int sock,int level,int optname,const void * optval,socklen_t optlen)226 int setsockopt(int sock, int level, int optname,
227 	       const void *optval, socklen_t optlen)
228 {
229 	return zsock_setsockopt(sock, level, optname, optval, optlen);
230 }
231 
listen(int sock,int backlog)232 int listen(int sock, int backlog)
233 {
234 	return zsock_listen(sock, backlog);
235 }
236 
bind(int sock,const struct sockaddr * addr,socklen_t addrlen)237 int bind(int sock, const struct sockaddr *addr, socklen_t addrlen)
238 {
239 	return zsock_bind(sock, addr, addrlen);
240 }
241 
accept(int sock,struct sockaddr * addr,socklen_t * addrlen)242 int accept(int sock, struct sockaddr *addr, socklen_t *addrlen)
243 {
244 	return zsock_accept(sock, addr, addrlen);
245 }
246