|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v2] lib/nolibc: Provide strerror(), strerror_r()
Hi Simon,
Patch looks good, thanks.
-- Felipe
Reviewed-by: Felipe Huici <felipe.huici@xxxxxxxxx>
============================================================
Dr. Felipe Huici
Chief Researcher, Systems and Machine Learning Group
NEC Laboratories Europe GmbH
Kurfuerstenanlage 36, D-69115 Heidelberg
Tel. +49
(0)6221 4342-241
Fax: +49
(0)6221 4342-155
e-mail:
felipe.huici@xxxxxxxxx
============================================================
Registered at Amtsgericht Mannheim, Germany, HRB728558
On 18.04.19, 09:58, "Simon Kuenzer" <simon.kuenzer@xxxxxxxxx> wrote:
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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |