From c65395be643cad64e11d1b0763d7ea048da3dc84 Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Sun, 8 Nov 2020 17:37:16 +0100 Subject: [PATCH] Implement strerror(3) and strerror_r(3) Error descriptions obtained from include/errno.h. --- libpsx/src/libc/error.c | 113 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 8 deletions(-) diff --git a/libpsx/src/libc/error.c b/libpsx/src/libc/error.c index 6863b2f..ab5fe5b 100644 --- a/libpsx/src/libc/error.c +++ b/libpsx/src/libc/error.c @@ -1,19 +1,116 @@ +#include #include #include -static char strerror_not_implemented[64]; +static const char *const str[] = +{ + [EPERM] = "Operation not permitted", + [ENOENT] = "No such file or directory", + [ESRCH] = "No such process", + [EINTR] = "Interrupted system call", + [EIO] = "Input/output error", + [ENXIO] = "Device not configured", + [E2BIG] = "Argument list too long", + [ENOEXEC] = "Exec format error", + [EBADF] = "Bad file descriptor", + [ECHILD] = "No child processes", + [EDEADLK] = "Resource deadlock avoided", + [ENOMEM] = "Cannot allocate memory", + [EACCES] = "Permission denied", + [EFAULT] = "Bad address", + [ENOTBLK] = "Block device required", + [EBUSY] = "Device busy", + [EEXIST] = "File exists", + [EXDEV] = "Cross-device link", + [ENODEV] = "Operation not supported by device", + [ENOTDIR] = "Not a directory", + [EISDIR] = "Is a directory", + [EINVAL] = "Invalid argument", + [ENFILE] = "Too many open files in system", + [EMFILE] = "Too many open files", + [ENOTTY] = "Inappropriate ioctl for device", + [ETXTBSY] = "Text file busy", + [EFBIG] = "File too large", + [ENOSPC] = "No space left on device", + [ESPIPE] = "Illegal seek", + [EROFS] = "Read-only file system", + [EMLINK] = "Too many links", + [EPIPE] = "Broken pipe", + [EDOM] = "Numerical argument out of domain", + [ERANGE] = "Result too large or too small", + [EAGAIN] = "Resource temporarily unavailable", + [EWOULDBLOCK] = "Operation would block", + [EINPROGRESS] = "Operation now in progress", + [EALREADY] = "Operation already in progress", + [ENOTSOCK] = "Socket operation on non-socket", + [EDESTADDRREQ] = "Destination address required", + [EMSGSIZE] = "Message too long", + [EPROTOTYPE] = "Protocol wrong type for socket", + [ENOPROTOOPT] = "Protocol option not available", + [EPROTONOSUPPORT] = "Protocol not supported", + [ESOCKTNOSUPPORT] = "Socket type not supported", + [EOPNOTSUPP] = "Operation not supported", + [EPFNOSUPPORT] = "Protocol family not supported", + [EAFNOSUPPORT] = "Address family not supported by protocol family", + [EADDRINUSE] = "Address already in use", + [EADDRNOTAVAIL] = "Can't assign requested address", + [ENETDOWN] = "Network is down", + [ENETUNREACH] = "Network is unreachable", + [ENETRESET] = "Network dropped connection on reset", + [ECONNABORTED] = "Software caused connection abort", + [ECONNRESET] = "Connection reset by peer", + [ENOBUFS] = "No buffer space available", + [EISCONN] = "Socket is already connected", + [ENOTCONN] = "Socket is not connected", + [ESHUTDOWN] = "Can't send after socket shutdown", + [ETOOMANYREFS] = "Too many references: can't splice", + [ETIMEDOUT] = "Operation timed out", + [ECONNREFUSED] = "Connection refused", + [ELOOP] = "Too many levels of symbolic links", + [ENAMETOOLONG] = "File name too long", + [EHOSTDOWN] = "Host is down", + [EHOSTUNREACH] = "No route to host", + [ENOTEMPTY] = "Directory not empty", + [EUSERS] = "Too many users", + [EDQUOT] = "Disc quota exceeded", + [ESTALE] = "Stale NFS file handle", + [EREMOTE] = "Too many levels of remote in path", + [ENOLCK] = "No locks available", + [ENOSYS] = "Function not implemented", + [EIDRM] = "Identifier removed", + [ENOMSG] = "No message of desired type", + [EOVERFLOW] = "Value too large to be stored in data type", + [EILSEQ] = "Illegal byte sequence", + [ENOTSUP] = "Not supported", + [ECANCELED] = "Operation canceled", + [EBADMSG] = "Bad or Corrupt message", + [ENODATA] = "No message available", + [ENOSR] = "No STREAM resources", + [ENOSTR] = "Not a STREAM", + [ETIME] = "STREAM ioctl timeout", + [EMULTIHOP] = "Multihop attempted", + [ENOLINK] = "Link has been severed", + [EPROTO] = "Protocol error" +}; char *strerror(int errnum) { - strerror_r(errnum, strerror_not_implemented, 64); - - return strerror_not_implemented; + static char deferr[sizeof "Unknown error -2147483648"]; + + if (errnum < sizeof str / sizeof *str) + return (char *)str[errnum]; + + snprintf(deferr, sizeof deferr, "Unknown error %d", errnum); + return deferr; } int strerror_r(int errnum, char *strerrbuf, size_t buflen) { - snprintf(strerrbuf, buflen, - "strerror(%d)", errnum); - - return 0; + if (errnum < sizeof str / sizeof *str) { + snprintf(strerrbuf, buflen, "%s", str[errnum]); + return strlen(str[errnum]); + } + + snprintf(strerrbuf, buflen, "Unknown error %d", errnum); + return -1; }