summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/string.c148
-rw-r--r--lib/vsprintf.c13
2 files changed, 158 insertions, 3 deletions
diff --git a/lib/string.c b/lib/string.c
index e8659ad..99ffdf0 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -1,5 +1,144 @@
+#include <errno.h>
#include <string.h>
+static char *errors[] = {
+ [0] = "Success",
+ [EPERM] = "Operation not permitted",
+ [ENOENT] = "No such file or directory",
+ [ESRCH] = "No such process",
+ [EINTR] = "Interrupted system call",
+ [EIO] = "Input/output error",
+ [ENXIO] = "No such device or address",
+ [E2BIG] = "Argument list too long",
+ [ENOEXEC] = "Exec format error",
+ [EBADF] = "Bad file descriptor",
+ [ECHILD] = "No child processes",
+ [EAGAIN] = "Resource temporarily unavailable",
+ [EWOULDBLOCK] = "Resource temporarily unavailable",
+ [ENOMEM] = "Cannot allocate memory",
+ [EACCES] = "Permission denied",
+ [EFAULT] = "Bad address",
+ [ENOTBLK] = "Block device required",
+ [EBUSY] = "Device or resource busy",
+ [EEXIST] = "File exists",
+ [EXDEV] = "Invalid cross-device link",
+ [ENODEV] = "No such 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] = "Numerical result out of range",
+ [EDEADLK] = "Resource deadlock avoided",
+ [EDEADLOCK] = "Resource deadlock avoided",
+ [ENAMETOOLONG] = "File name too long",
+ [ENOLCK] = "No locks available",
+ [ENOSYS] = "Function not implemented",
+ [ENOTEMPTY] = "Directory not empty",
+ [ELOOP] = "Too many levels of symbolic links",
+ [ENOMSG] = "No message of desired type",
+ [EIDRM] = "Identifier removed",
+ [ECHRNG] = "Channel number out of range",
+ [EL2NSYNC] = "Level 2 not synchronized",
+ [EL3HLT] = "Level 3 halted",
+ [EL3RST] = "Level 3 reset",
+ [ELNRNG] = "Link number out of range",
+ [EUNATCH] = "Protocol driver not attached",
+ [ENOCSI] = "No CSI structure available",
+ [EL2HLT] = "Level 2 halted",
+ [EBADE] = "Invalid exchange",
+ [EBADR] = "Invalid request descriptor",
+ [EXFULL] = "Exchange full",
+ [ENOANO] = "No anode",
+ [EBADRQC] = "Invalid request code",
+ [EBADSLT] = "Invalid slot",
+ [EBFONT] = "Bad font file format",
+ [ENOSTR] = "Device not a stream",
+ [ENODATA] = "No data available",
+ [ETIME] = "Timer expired",
+ [ENOSR] = "Out of streams resources",
+ [ENONET] = "Machine is not on the network",
+ [ENOPKG] = "Package not installed",
+ [EREMOTE] = "Object is remote",
+ [ENOLINK] = "Link has been severed",
+ [EADV] = "Advertise error",
+ [ESRMNT] = "Srmount error",
+ [ECOMM] = "Communication error on send",
+ [EPROTO] = "Protocol error",
+ [EMULTIHOP] = "Multihop attempted",
+ [EDOTDOT] = "RFS specific error",
+ [EBADMSG] = "Bad message",
+ [EOVERFLOW] = "Value too large for defined data type",
+ [ENOTUNIQ] = "Name not unique on network",
+ [EBADFD] = "File descriptor in bad state",
+ [EREMCHG] = "Remote address changed",
+ [ELIBACC] = "Can not access a needed shared library",
+ [ELIBBAD] = "Accessing a corrupted shared library",
+ [ELIBSCN] = ".lib section in a.out corrupted",
+ [ELIBMAX] = "Attempting to link in too many shared libraries",
+ [ELIBEXEC] = "Cannot exec a shared library directly",
+ [EILSEQ] = "Invalid or incomplete multibyte or wide character",
+ [ERESTART] = "Interrupted system call should be restarted",
+ [ESTRPIPE] = "Streams pipe error",
+ [EUSERS] = "Too many users",
+ [ENOTSOCK] = "Socket operation on non-socket",
+ [EDESTADDRREQ] = "Destination address required",
+ [EMSGSIZE] = "Message too long",
+ [EPROTOTYPE] = "Protocol wrong type for socket",
+ [ENOPROTOOPT] = "Protocol not available",
+ [EPROTONOSUPPORT] = "Protocol not supported",
+ [ESOCKTNOSUPPORT] = "Socket type not supported",
+ [ENOTSUP] = "Operation not supported",
+ [EOPNOTSUPP] = "Operation not supported",
+ [EPFNOSUPPORT] = "Protocol family not supported",
+ [EAFNOSUPPORT] = "Address family not supported by protocol",
+ [EADDRINUSE] = "Address already in use",
+ [EADDRNOTAVAIL] = "Cannot 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] = "Transport endpoint is already connected",
+ [ENOTCONN] = "Transport endpoint is not connected",
+ [ESHUTDOWN] = "Cannot send after transport endpoint shutdown",
+ [ETOOMANYREFS] = "Too many references: cannot splice",
+ [ETIMEDOUT] = "Connection timed out",
+ [ECONNREFUSED] = "Connection refused",
+ [EHOSTDOWN] = "Host is down",
+ [EHOSTUNREACH] = "No route to host",
+ [EALREADY] = "Operation already in progress",
+ [EINPROGRESS] = "Operation now in progress",
+ [ESTALE] = "Stale file handle",
+ [EUCLEAN] = "Structure needs cleaning",
+ [ENOTNAM] = "Not a XENIX named type file",
+ [ENAVAIL] = "No XENIX semaphores available",
+ [EISNAM] = "Is a named type file",
+ [EREMOTEIO] = "Remote I/O error",
+ [EDQUOT] = "Disk quota exceeded",
+ [ENOMEDIUM] = "No medium found",
+ [EMEDIUMTYPE] = "Wrong medium type",
+ [ECANCELED] = "Operation canceled",
+ [ENOKEY] = "Required key not available",
+ [EKEYEXPIRED] = "Key has expired",
+ [EKEYREVOKED] = "Key has been revoked",
+ [EKEYREJECTED] = "Key was rejected by service",
+ [EOWNERDEAD] = "Owner died",
+ [ENOTRECOVERABLE] = "State not recoverable",
+ [ERFKILL] = "Operation not possible due to RF-kill",
+ [EHWPOISON] = "Memory page has hardware error",
+};
+
void *memchr(const void *s, int c, size_t n) {
unsigned char *p = (unsigned char*) s;
while(n--) {
@@ -171,3 +310,12 @@ size_t strxfrm(char *dest, const char *src, size_t n) {
if(n > n2) strcpy(dest, src);
return n2;
}
+
+char *strerror(int err) {
+ err = err < 0 ? -err : err;
+
+ if(err > sizeof(errors) / sizeof(char*))
+ return NULL;
+
+ return errors[err];
+}
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index a566b83..4188308 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -6,8 +6,9 @@ enum TYPE {
TYPE_INT = 1,
TYPE_UINT = 2,
TYPE_HEX = 3,
- TYPE_STRING = 4,
- TYPE_PERCENT = 5
+ TYPE_CHAR = 4,
+ TYPE_STRING = 5,
+ TYPE_PERCENT = 6
};
enum FLAGS {
@@ -91,7 +92,7 @@ int vsprintf(char *str, char *fmt, va_list ap) {
fwidth = 0;
fmt++;
- while(1) {
+ for(;;) {
switch(*fmt) {
case '#':
flags |= FL_ALT;
@@ -99,6 +100,9 @@ int vsprintf(char *str, char *fmt, va_list ap) {
case '%':
type = TYPE_PERCENT;
goto done;
+ case 'c':
+ type = TYPE_CHAR;
+ goto done;
case 's':
type = TYPE_STRING;
goto done;
@@ -137,6 +141,9 @@ done:
while(*s)
*str++ = *s++;
break;
+ case TYPE_CHAR:
+ *str++ = va_arg(ap, char);
+ break;
case TYPE_HEX:
x = va_arg(ap, int);
hex(&str, flags, fwidth, 4, x);