#include #include 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--) { if(*p != (unsigned char) c) { p++; } else { return p; } } return 0; } int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *p1 = (const unsigned char*) s1; const unsigned char *p2 = (const unsigned char*) s2; while(n--) { if(*p1 != *p2) { return *p1 - *p2; } else { p1++, p2++; } } return 0; } void *memcpy(void *dest, const void *src, size_t n) { char *dp = (char*) dest; const char *sp = (const char*) src; while(n--) *dp++ = *sp++; return dest; } void *memmove(void *dest, const void *src, size_t n) { unsigned char tmp[n]; memcpy(tmp, src, n); memcpy(dest, tmp, n); return dest; } void *memset(void *s, int c, size_t n) { unsigned char *p = (unsigned char*) s; while(n--) *p++ = (unsigned char) c; return s; } size_t strlen(const char *str) { const char *s; for(s = str; *s; ++s) {} return (s - str); } char *strcat(char *dest, const char *src) { size_t dest_len = strlen(dest); size_t i; for(i = 0; src[i] != '\0'; i++) { dest[dest_len + i] = src[i]; } dest[dest_len + i] = '\0'; return dest; } char *strncat(char *dest, const char *src, size_t n) { size_t dest_len = strlen(dest); size_t i; for(i = 0; i < n && src[i] != '\0'; i++) { dest[dest_len + i] = src[i]; } dest[dest_len + i] = '\0'; return dest; } char *strchr(const char *s, int c) { while(*s != (char) c) { if(!*s++) return 0; } return (char*) s; } char *strrchr(char *s, int c) { char *ret = 0; do { if(*s == (char) c) ret = s; } while(*s++); return ret; } int strcmp(const char *s1, const char *s2) { while(*s1 && (*s1 == *s2)) s1++, s2++; return *(const unsigned char*) s1 - *(const unsigned char*) s2; } int strncmp(const char *s1, const char *s2, size_t n) { while(n--) { if(*s1++ != *s2++) { return *(unsigned char*) (s1 - 1) - *(unsigned char*) (s2 - 1); } } return 0; } char *strcpy(char *dest, const char *src) { char *ret = dest; while(*dest++ = *src++); return ret; } char *strncpy(char *dest, const char *src, size_t n) { char *ret = dest; do { if(!n--) return ret; } while (*dest++ = *src++); while(n--) *dest++ = 0; return ret; } size_t strcspn(const char *s1, const char *s2) { size_t ret = 0; while(*s1) { if(strchr(s2, *s1)) { return ret; } else { s1++, ret++; } } return ret; } size_t strspn(const char *s1, const char *s2) { size_t ret = 0; while(*s1 && strchr(s2, *s1++)) ret++; return ret; } char *strpbrk(const char *s1, const char *s2) { while(*s1) { if(strchr(s2, *s1++)) return (char*) --s1; } return 0; } char *strstr(const char *s1, const char *s2) { size_t n = strlen(s2); while(*s1) { if(!memcmp(s1++, s2, n)) { return (char*) (s1 - 1); } } return 0; } char *strtok(char *str, const char *delim) { static char *p = 0; if(str) { p = str; } else if(!p) { return 0; } str = p + strspn(p, delim); p = str + strcspn(str, delim); if(p == str) return p = 0; p = *p ? *p = 0, p + 1 : 0; return str; } size_t strxfrm(char *dest, const char *src, size_t n) { size_t n2 = strlen(src); 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]; }