[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH v2] lib/nolibc: Provide strerror(), strerror_r()



Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
---
 lib/nolibc/exportsyms.uk    |   2 +
 lib/nolibc/include/string.h |   3 +
 lib/nolibc/string.c         | 328 ++++++++++++++++++++++++++++++++++++
 3 files changed, 333 insertions(+)

diff --git a/lib/nolibc/exportsyms.uk b/lib/nolibc/exportsyms.uk
index cae6e298..c542f3a6 100644
--- a/lib/nolibc/exportsyms.uk
+++ b/lib/nolibc/exportsyms.uk
@@ -69,6 +69,8 @@ strndup
 strdup
 strlcpy
 strlcat
+strerror_r
+strerror
 
 # time
 nanosleep
diff --git a/lib/nolibc/include/string.h b/lib/nolibc/include/string.h
index 4b04fd8d..c5f0caa9 100644
--- a/lib/nolibc/include/string.h
+++ b/lib/nolibc/include/string.h
@@ -68,6 +68,9 @@ char *strtok(char *restrict s, const char *restrict sep);
 char *strndup(const char *str, size_t len);
 char *strdup(const char *str);
 
+char *strerror_r(int errnum, char *buf, size_t buflen);
+char *strerror(int errnum);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/nolibc/string.c b/lib/nolibc/string.c
index 1060bb2d..d4d1db27 100644
--- a/lib/nolibc/string.c
+++ b/lib/nolibc/string.c
@@ -61,6 +61,8 @@
 #include <stdint.h>
 #include <string.h>
 #include <limits.h>
+#include <errno.h>
+#include <stdio.h>
 
 void *memcpy(void *dst, const void *src, size_t len)
 {
@@ -345,3 +347,329 @@ size_t strlcat(char *d, const char *s, size_t n)
                return l + strlen(s);
        return l + strlcpy(d+l, s, n-l);
 }
+
+/* GNU-specific version of strerror_r */
+char *strerror_r(int errnum, char *buf, size_t buflen)
+{
+       const char *strerr;
+
+       switch (errnum) {
+       case EPERM:
+               strerr = "Operation not permitted";
+               break;
+       case ENOENT:
+               strerr = "No such file or directory";
+               break;
+       case ESRCH:
+               strerr = "No such process";
+               break;
+       case EINTR:
+               strerr = "Interrupted system call";
+               break;
+       case EIO:
+               strerr = "Input/output error";
+               break;
+       case ENXIO:
+               strerr = "Device not configured";
+               break;
+       case E2BIG:
+               strerr = "Argument list too long";
+               break;
+       case ENOEXEC:
+               strerr = "Exec format error";
+               break;
+       case EBADF:
+               strerr = "Bad file descriptor";
+               break;
+       case ECHILD:
+               strerr = "No child processes";
+               break;
+       case EDEADLK:
+               strerr = "Resource deadlock avoided";
+               break;
+       case ENOMEM:
+               strerr = "Cannot allocate memory";
+               break;
+       case EACCES:
+               strerr = "Permission denied";
+               break;
+       case EFAULT:
+               strerr = "Bad address";
+               break;
+       case ENOTBLK:
+               strerr = "Block device required";
+               break;
+       case EBUSY:
+               strerr = "Device busy";
+               break;
+       case EEXIST:
+               strerr = "File exists";
+               break;
+       case EXDEV:
+               strerr = "Cross-device link";
+               break;
+       case ENODEV:
+               strerr = "Operation not supported by device";
+               break;
+       case ENOTDIR:
+               strerr = "Not a directory";
+               break;
+       case EISDIR:
+               strerr = "Is a directory";
+               break;
+       case EINVAL:
+               strerr = "Invalid argument";
+               break;
+       case ENFILE:
+               strerr = "Too many open files in system";
+               break;
+       case EMFILE:
+               strerr = "Too many open files";
+               break;
+       case ENOTTY:
+               strerr = "Inappropriate ioctl for device";
+               break;
+       case ETXTBSY:
+               strerr = "Text file busy";
+               break;
+       case EFBIG:
+               strerr = "File too large";
+               break;
+       case ENOSPC:
+               strerr = "No space left on device";
+               break;
+       case ESPIPE:
+               strerr = "Illegal seek";
+               break;
+       case EROFS:
+               strerr = "Read-only file system";
+               break;
+       case EMLINK:
+               strerr = "Too many links";
+               break;
+       case EPIPE:
+               strerr = "Broken pipe";
+               break;
+       case EDOM:
+               strerr = "Numerical argument out of domain";
+               break;
+       case ERANGE:
+               strerr = "Result too large";
+               break;
+       case EAGAIN:
+               strerr = "Resource temporarily unavailable";
+               break;
+       case EINPROGRESS:
+               strerr = "Operation now in progress";
+               break;
+       case EALREADY:
+               strerr = "Operation already in progress";
+               break;
+       case ENOTSOCK:
+               strerr = "Socket operation on non-socket";
+               break;
+       case EDESTADDRREQ:
+               strerr = "Destination address required";
+               break;
+       case EMSGSIZE:
+               strerr = "Message too long";
+               break;
+       case EPROTOTYPE:
+               strerr = "Protocol wrong type for socket";
+               break;
+       case ENOPROTOOPT:
+               strerr = "Protocol not available";
+               break;
+       case EPROTONOSUPPORT:
+               strerr = "Protocol not supported";
+               break;
+       case ESOCKTNOSUPPORT:
+               strerr = "Socket type not supported";
+               break;
+       case EOPNOTSUPP:
+               strerr = "Operation not supported on socket";
+               break;
+       case EPFNOSUPPORT:
+               strerr = "Protocol family not supported";
+               break;
+       case EAFNOSUPPORT:
+               strerr = "Address family not supported by protocol family";
+               break;
+       case EADDRINUSE:
+               strerr = "Address already in use";
+               break;
+       case EADDRNOTAVAIL:
+               strerr = "Can't assign requested address";
+               break;
+       case ENETDOWN:
+               strerr = "Network is down";
+               break;
+       case ENETUNREACH:
+               strerr = "Network is unreachable";
+               break;
+       case ENETRESET:
+               strerr = "Network dropped connection on reset";
+               break;
+       case ECONNABORTED:
+               strerr = "Software caused connection abort";
+               break;
+       case ECONNRESET:
+               strerr = "Connection reset by peer";
+               break;
+       case ENOBUFS:
+               strerr = "No buffer space available";
+               break;
+       case EISCONN:
+               strerr = "Socket is already connected";
+               break;
+       case ENOTCONN:
+               strerr = "Socket is not connected";
+               break;
+       case ESHUTDOWN:
+               strerr = "Can't send after socket shutdown";
+               break;
+       case ETIMEDOUT:
+               strerr = "Operation timed out";
+               break;
+       case ECONNREFUSED:
+               strerr = "Connection refused";
+               break;
+       case ELOOP:
+               strerr = "Too many levels of symbolic links";
+               break;
+       case ENAMETOOLONG:
+               strerr = "File name too long";
+               break;
+       case EHOSTDOWN:
+               strerr = "Host is down";
+               break;
+       case EHOSTUNREACH:
+               strerr = "No route to host";
+               break;
+       case ENOTEMPTY:
+               strerr = "Directory not empty";
+               break;
+       case EPROCLIM:
+               strerr = "Too many processes";
+               break;
+       case EUSERS:
+               strerr = "Too many users";
+               break;
+       case EDQUOT:
+               strerr = "Disc quota exceeded";
+               break;
+       case ESTALE:
+               strerr = "Stale NFS file handle";
+               break;
+       case EBADRPC:
+               strerr = "RPC struct is bad";
+               break;
+       case ERPCMISMATCH:
+               strerr = "RPC version wrong";
+               break;
+       case EPROGUNAVAIL:
+               strerr = "RPC prog";
+               break;
+       case EPROGMISMATCH:
+               strerr = "Program version wrong";
+               break;
+       case EPROCUNAVAIL:
+               strerr = "Bad procedure for program";
+               break;
+       case ENOLCK:
+               strerr = "No locks available";
+               break;
+       case ENOSYS:
+               strerr = "Function not implemented";
+               break;
+       case EFTYPE:
+               strerr = "Inappropriate file type or format";
+               break;
+       case EAUTH:
+               strerr = "Authentication error";
+               break;
+       case ENEEDAUTH:
+               strerr = "Need authenticator";
+               break;
+       case EIDRM:
+               strerr = "Identifier removed";
+               break;
+       case ENOMSG:
+               strerr = "No message of desired type";
+               break;
+       case EOVERFLOW:
+               strerr = "Value too large to be stored in data type";
+               break;
+       case ECANCELED:
+               strerr = "Operation canceled";
+               break;
+       case EILSEQ:
+               strerr = "Illegal byte sequence";
+               break;
+       case ENOATTR:
+               strerr = "Attribute not found";
+               break;
+       case EDOOFUS:
+               strerr = "Programming error";
+               break;
+       case EBADMSG:
+               strerr = "Bad message";
+               break;
+       case EMULTIHOP:
+               strerr = "Multihop attempted";
+               break;
+       case ENOLINK:
+               strerr = "Link has been severed";
+               break;
+       case EPROTO:
+               strerr = "Protocol error";
+               break;
+       case ENOTCAPABLE:
+               strerr = "Capabilities insufficient";
+               break;
+       case ECAPMODE:
+               strerr = "Not permitted in capability mode";
+               break;
+       case ENOTRECOVERABLE:
+               strerr = "State not recoverable";
+               break;
+       case EOWNERDEAD:
+               strerr = "Previous owner died";
+               break;
+       case ENOTSUP:
+               strerr = "Not supported";
+               break;
+       default:
+               strerr = NULL;
+               errno = EINVAL; /* Unknown errnum requires errno to be set */
+               break;
+       }
+
+       if (!buflen)
+               return buf;
+
+       /*
+        * NOTE: If target buffer is too small, we are supposed to set
+        *       errno to ERANGE. We ignore this case for simplification.
+        */
+       if (strerr)
+               strncpy(buf, strerr, buflen);
+       else
+               snprintf(buf, buflen, "Unknown error %d", errnum);
+
+       /* ensure null termination */
+       buf[buflen - 1] = '\0';
+       return buf;
+}
+
+/* NOTE: strerror() is not thread-safe, nor reentrant-safe */
+char *strerror(int errnum)
+{
+       /* NOTE: Our longest message is currently 48 characters. With
+        *       64 characters we should have room for minor changes
+        *       in the future.
+        */
+       static char buf[64];
+
+       return strerror_r(errnum, buf, sizeof(buf));
+}
-- 
2.20.1


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.