55 *
66 * string/strerror (errno names)
77 *
8- * Copyright 2018 Phoenix Systems
8+ * Copyright 2018, 2023 Phoenix Systems
99 * Author: Michal Miroslaw, Aleksander Kaminski
1010 *
1111 * This file is part of Phoenix-RTOS.
1818#include <stdio.h>
1919#include <string.h>
2020#include <errno.h>
21-
22-
23- typedef struct {
24- uint16_t errnum ;
25- uint16_t offset ;
26- } errinfo_t ;
27-
28-
29- static const char errnames [] = {
30- #include "errno.str.inc"
31- };
32-
33- static const errinfo_t errtab [] = {
34- #include "errno.tab.inc"
21+ #include <netdb.h>
22+
23+
24+ /* clang-format off */
25+ static const char * __errmsgtab [] = {
26+ /* EOK */ "Operation succeeded" ,
27+ /* EPERM */ "Operation not permitted" ,
28+ /* ENOENT */ "No such file or directory" ,
29+ /* ESRCH */ "No such process" ,
30+ /* EINTR */ "Interrupted system call" ,
31+ /* EIO */ "I/O error" ,
32+ /* ENXIO */ "No such device or address" ,
33+ /* E2BIG */ "Argument list too long" ,
34+ /* ENOEXEC */ "Executable format error" ,
35+ /* EBADF */ "Bad file number" ,
36+ /* ECHILD */ "No child processes" ,
37+ /* EAGAIN */ "Try again" ,
38+ /* ENOMEM */ "Out of memory" ,
39+ /* EACCES */ "Permission denied" ,
40+ /* EFAULT */ "Bad address" ,
41+ /* ENOTBLK */ "Block device required" ,
42+ /* EBUSY */ "Device or resource busy" ,
43+ /* EEXIST */ "File exists" ,
44+ /* EXDEV */ "Cross-device link" ,
45+ /* ENODEV */ "No such device" ,
46+ /* ENOTDIR */ "Not a directory" ,
47+ /* EISDIR */ "Is a directory" ,
48+ /* EINVAL */ "Invalid argument" ,
49+ /* ENFILE */ "File table overflow" ,
50+ /* EMFILE */ "Too many open files" ,
51+ /* ENOTTY */ "Not a typewriter" ,
52+ /* ETXTBSY */ "Text file busy" ,
53+ /* EFBIG */ "File too large" ,
54+ /* ENOSPC */ "No space left on device" ,
55+ /* ESPIPE */ "Illegal seek" ,
56+ /* EROFS */ "Read-only file system" ,
57+ /* EMLINK */ "Too many links" ,
58+ /* EPIPE */ "Broken pipe" ,
59+ /* EDOM */ "Argument out of domain" ,
60+ /* ERANGE */ "Result not representable" ,
61+ /* ENOSYS */ "Function not implemented" ,
62+ /* ENAMETOOLONG */ "Name too long" ,
63+ /* ETIME */ "Timer expired" ,
64+ /* EDEADLK */ "Resource deadlock avoided" ,
65+ /* ENOTEMPTY */ "Directory not empty" ,
66+ /* ELOOP */ "Too many levels of symbolic links" ,
67+ NULL ,
68+ /* ENOMSG */ "No message of the desired type" ,
69+ NULL ,
70+ NULL ,
71+ NULL ,
72+ NULL ,
73+ NULL ,
74+ NULL ,
75+ /* EUNATCH */ "Protocol driver not attached" ,
76+ NULL ,
77+ NULL ,
78+ NULL ,
79+ NULL ,
80+ NULL ,
81+ NULL ,
82+ NULL ,
83+ NULL ,
84+ NULL ,
85+ NULL ,
86+ NULL ,
87+ /* ENODATA */ "No message is available on the STREAM head read queue" ,
88+ NULL ,
89+ NULL ,
90+ /* ENONET */ "Machine is not on the network." ,
91+ NULL ,
92+ /* EBADFD */ "File descriptor in bad state" ,
93+ NULL ,
94+ NULL ,
95+ NULL ,
96+ NULL ,
97+ /* EPROTO */ "Protocol error" ,
98+ NULL ,
99+ NULL ,
100+ /* EBADMSG */ "Bad message" ,
101+ /* EOVERFLOW */ "Value too large to be stored in data type" ,
102+ NULL ,
103+ NULL ,
104+ NULL ,
105+ NULL ,
106+ NULL ,
107+ NULL ,
108+ NULL ,
109+ NULL ,
110+ /* EILSEQ */ "Invalid or incomplete multibyte or wide character" ,
111+ NULL ,
112+ NULL ,
113+ NULL ,
114+ /* ENOTSOCK */ "Not a socket" ,
115+ /* EDESTADDRREQ */ "Destination address required" ,
116+ /* EMSGSIZE */ "Message too long" ,
117+ /* EPROTOTYPE */ "Protocol wrong type for socket" ,
118+ /* ENOPROTOOPT */ "Protocol not available" ,
119+ /* EPROTONOSUPPORT */ "Protocol not supported" ,
120+ NULL ,
121+ /* EOPNOTSUPP */ "Operation not supported on socket" ,
122+ /* EPFNOSUPPORT */ "Protocol family not supported" ,
123+ /* EAFNOSUPPORT */ "Address family not supported" ,
124+ /* EADDRINUSE */ "Address already in use" ,
125+ /* EADDRNOTAVAIL */ "Address not available" ,
126+ /* ENETDOWN */ "Network is down" ,
127+ /* ENETUNREACH */ "Network unreachable" ,
128+ /* ENETRESET */ "Connection aborted by network" ,
129+ /* ECONNABORTED */ "Connection aborted" ,
130+ /* ECONNRESET */ "Connection reset" ,
131+ /* ENOBUFS */ "No buffer space available" ,
132+ /* EISCONN */ "Socket is connected" ,
133+ /* ENOTCONN */ "The socket is not connected" ,
134+ NULL ,
135+ NULL ,
136+ /* ETIMEDOUT */ "Connection timed out" ,
137+ /* ECONNREFUSED */ "Connection refused" ,
138+ /* EHOSTDOWN */ "Host is down" ,
139+ /* EHOSTUNREACH */ "Host is unreachable" ,
140+ /* EALREADY */ "Connection already in progress" ,
141+ /* EINPROGRESS */ "Operation in progress" ,
142+ /* ENOLCK */ "No locks available" ,
143+ /* EUCLEAN */ "Structure needs cleaning" ,
144+ NULL ,
145+ NULL ,
146+ NULL ,
147+ NULL ,
148+ NULL ,
149+ NULL ,
150+ NULL ,
151+ NULL ,
152+ NULL ,
153+ NULL ,
154+ NULL ,
155+ NULL ,
156+ NULL ,
157+ /* ENOTRECOVERABLE */ "State not recoverable"
35158};
36-
37- static const char gainames [] = {
38- #include "gaierr.str.inc"
39- };
40-
41- static const errinfo_t gaitab [] = {
42- #include "gaierr.tab.inc"
43- };
44-
45- // static assert: 16-bit offset
46- static const char assert_errnames_size [- (sizeof (errnames ) > 0xFFFF )] __attribute__((unused ));
47- static const char assert_gainames_size [- (sizeof (gainames ) > 0xFFFF )] __attribute__((unused ));
159+ /* clang-format on */
48160
49161
50- static int err_cmp ( const void * key , const void * elem )
162+ static inline const char * strerror_ ( int errnum , char * buff , size_t bufflen , int * err )
51163{
52- const errinfo_t * p = elem ;
53- long err = (long )key ;
164+ const char * str = NULL ;
54165
55- return err - (long )p -> errnum ;
56- }
57-
58-
59- static inline const char * strerror_ (const errinfo_t * tab , size_t tabsz , const char * names , int errnum , char * buff , size_t bufflen , int * err )
60- {
61- const errinfo_t * e ;
62-
63- if (errnum < 0 ) {
64- errnum = - errnum ;
166+ if ((errnum >= 0 ) && (errnum < (int )(sizeof (__errmsgtab ) / sizeof (* __errmsgtab )))) {
167+ str = __errmsgtab [errnum ];
65168 }
66169
67- e = bsearch ((void * )(long )errnum , tab , tabsz / sizeof (* tab ), sizeof (* tab ), err_cmp );
68- if (e == NULL ) {
170+ if (str == NULL ) {
69171 (void )snprintf (buff , bufflen , "Unknown error %d" , errnum );
70172 * err = EINVAL ;
71- return buff ;
173+ str = buff ;
72174 }
73175
74- return names + e -> offset ;
176+ return str ;
75177}
76178
77179
@@ -81,7 +183,7 @@ char *strerror(int errnum)
81183 const char * str ;
82184 int err = 0 ;
83185
84- str = strerror_ (errtab , sizeof ( errtab ), errnames , errnum , unknownMsg , sizeof (unknownMsg ), & err );
186+ str = strerror_ (errnum , unknownMsg , sizeof (unknownMsg ), & err );
85187 if (err != 0 ) {
86188 errno = err ;
87189 }
@@ -97,7 +199,7 @@ int strerror_r(int errnum, char *buf, size_t buflen)
97199 int ret = 0 ;
98200 size_t len ;
99201
100- str = strerror_ (errtab , sizeof ( errtab ), errnames , errnum , unknownMsg , sizeof (unknownMsg ), & ret );
202+ str = strerror_ (errnum , unknownMsg , sizeof (unknownMsg ), & ret );
101203 len = strlen (str );
102204 if (buflen > len ) {
103205 memcpy (buf , str , len + 1 );
@@ -113,13 +215,32 @@ int strerror_r(int errnum, char *buf, size_t buflen)
113215const char * gai_strerror (int errnum )
114216{
115217 static char unknownMsg [32 ];
116- const char * str ;
117- int err = 0 ;
118218
119- str = strerror_ (gaitab , sizeof (gaitab ), gainames , errnum , unknownMsg , sizeof (unknownMsg ), & err );
120- if (err != 0 ) {
121- errno = err ;
219+ switch (errnum ) {
220+ case EAI_AGAIN :
221+ return "Name could not be resolved at this time" ;
222+ case EAI_BADFLAGS :
223+ return "Flags parameter had an invalid value" ;
224+ case EAI_FAIL :
225+ return "Non-recoverable failure in name resolution" ;
226+ case EAI_FAMILY :
227+ return "Address family was not recognized" ;
228+ case EAI_MEMORY :
229+ return "Memory allocation failure" ;
230+ case EAI_NODATA :
231+ return "No address associated with hostname" ;
232+ case EAI_NONAME :
233+ return "Name does not resolve" ;
234+ case EAI_OVERFLOW :
235+ return "Argument buffer overflow" ;
236+ case EAI_SERVICE :
237+ return "Service was not recognized for socket type" ;
238+ case EAI_SOCKTYPE :
239+ return "Intended socket type was not recognized" ;
240+ case EAI_SYSTEM :
241+ return "System error returned in errno" ;
242+ default :
243+ (void )snprintf (unknownMsg , sizeof (unknownMsg ), "Unknown error %d" , errnum );
244+ return unknownMsg ;
122245 }
123-
124- return (char * )str ;
125246}
0 commit comments