diff --git a/photon/libc/include/stdio.h b/photon/libc/include/stdio.h index 905a9ae..31094e3 100644 --- a/photon/libc/include/stdio.h +++ b/photon/libc/include/stdio.h @@ -58,6 +58,8 @@ extern int vfprintf(FILE *fp, const char *restrict format, va_list arg); extern int vsprintf(char *buf, const char *restrict format, va_list arg); extern int vsnprintf(char *buf, size_t sz, const char *restrict format, va_list arg); +extern void perror(const char *s); + #if defined(__cplusplus) } #endif diff --git a/photon/libc/include/string.h b/photon/libc/include/string.h index c65a84d..4d5b745 100644 --- a/photon/libc/include/string.h +++ b/photon/libc/include/string.h @@ -30,6 +30,8 @@ extern char *strdup(const char *s); extern char *strtok(char *s, const char *delim); extern char *strtok_r(char *s, const char *delim, char **sp); +extern char *strerror(int errnum); + #if defined(__cplusplus) } /* extern "C" */ #endif diff --git a/photon/libc/stdio/perror.c b/photon/libc/stdio/perror.c new file mode 100644 index 0000000..a8ef33d --- /dev/null +++ b/photon/libc/stdio/perror.c @@ -0,0 +1,13 @@ +#include +#include +#include + +void perror(const char *s) +{ + if (s) { + fprintf(stderr, "%s: %s\n", s, strerror(errno)); + } else { + fputs(strerror(errno), stderr); + fputc('\n', stderr); + } +} diff --git a/photon/libc/string/strerror.c b/photon/libc/string/strerror.c new file mode 100644 index 0000000..9f511a3 --- /dev/null +++ b/photon/libc/string/strerror.c @@ -0,0 +1,152 @@ +#include +#include +#include + +static const char *sys_errlist[] = { + [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", + [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", + [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", + [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", +}; +static int n_sys_errlist = sizeof sys_errlist / sizeof sys_errlist[0]; + +static char g_msg_buf[128]; + +char *strerror(int errnum) +{ + if (errnum <= 0 || errnum >= n_sys_errlist) { + snprintf(g_msg_buf, sizeof g_msg_buf, "Unknown error: %d", errnum); + } else { + strncpy(g_msg_buf, sys_errlist[errnum], sizeof g_msg_buf - 1); + g_msg_buf[sizeof g_msg_buf - 1] = '\0'; + } + + return g_msg_buf; +} diff --git a/photon/libc/sys/horizon/sys/_errno.h b/photon/libc/sys/horizon/sys/_errno.h index eaf5fdd..877bb75 100644 --- a/photon/libc/sys/horizon/sys/_errno.h +++ b/photon/libc/sys/horizon/sys/_errno.h @@ -1,129 +1,136 @@ #ifndef SYS_HORIZON_SYS__ERRNO_H_ #define SYS_HORIZON_SYS__ERRNO_H_ -#define EPERM 1 /* Not super-user */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No children */ -#define EAGAIN 11 /* No more processes */ -#define ENOMEM 12 /* Not enough core */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Mount device busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* Too many open files in system */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math arg out of domain of func */ -#define ERANGE 34 /* Math result not representable */ -#define ENOMSG 35 /* No message of desired type */ -#define EIDRM 36 /* Identifier removed */ -#define ECHRNG 37 /* Channel number out of range */ -#define EL2NSYNC 38 /* Level 2 not synchronized */ -#define EL3HLT 39 /* Level 3 halted */ -#define EL3RST 40 /* Level 3 reset */ -#define ELNRNG 41 /* Link number out of range */ -#define EUNATCH 42 /* Protocol driver not attached */ -#define ENOCSI 43 /* No CSI structure available */ -#define EL2HLT 44 /* Level 2 halted */ -#define EDEADLK 45 /* Deadlock condition */ -#define ENOLCK 46 /* No record locks available */ -#define EBADE 50 /* Invalid exchange */ -#define EBADR 51 /* Invalid request descriptor */ -#define EXFULL 52 /* Exchange full */ -#define ENOANO 53 /* No anode */ -#define EBADRQC 54 /* Invalid request code */ -#define EBADSLT 55 /* Invalid slot */ -#define EDEADLOCK 56 /* File locking deadlock error */ -#define EBFONT 57 /* Bad font file fmt */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* No data (for no delay io) */ -#define ETIME 62 /* Timer expired */ -#define ENOSR 63 /* Out of streams resources */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* The object is remote */ -#define ENOLINK 67 /* The link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ -#define EMULTIHOP 74 /* Multihop attempted */ -#define ELBIN 75 /* Inode is remote (not really error) */ -#define EDOTDOT 76 /* Cross mount point (not really error) */ -#define EBADMSG 77 /* Trying to read unreadable message */ -#define EFTYPE 79 /* Inappropriate file type or format */ -#define ENOTUNIQ 80 /* Given log. name not unique */ -#define EBADFD 81 /* f.d. invalid for this operation */ -#define EREMCHG 82 /* Remote address changed */ -#define ELIBACC 83 /* Can't access a needed shared lib */ -#define ELIBBAD 84 /* Accessing a corrupted shared lib */ -#define ELIBSCN 85 /* .lib section in a.out corrupted */ -#define ELIBMAX 86 /* Attempting to link in too many libs */ -#define ELIBEXEC 87 /* Attempting to exec a shared library */ -#define ENOSYS 88 /* Function not implemented */ -#define ENMFILE 89 /* No more files */ -#define ENOTEMPTY 90 /* Directory not empty */ -#define ENAMETOOLONG 91 /* File or path name too long */ -#define ELOOP 92 /* Too many symbolic links */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EPFNOSUPPORT 96 /* Protocol family not supported */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */ -#define EPROTOTYPE 107 /* Protocol wrong type for socket */ -#define ENOTSOCK 108 /* Socket operation on non-socket */ -#define ENOPROTOOPT 109 /* Protocol not available */ -#define ESHUTDOWN 110 /* Can't send after socket shutdown */ -#define ECONNREFUSED 111 /* Connection refused */ -#define EADDRINUSE 112 /* Address already in use */ -#define ECONNABORTED 113 /* Connection aborted */ -#define ENETUNREACH 114 /* Network is unreachable */ -#define ENETDOWN 115 /* Network interface is not configured */ -#define ETIMEDOUT 116 /* Connection timed out */ -#define EHOSTDOWN 117 /* Host is down */ -#define EHOSTUNREACH 118 /* Host is unreachable */ -#define EINPROGRESS 119 /* Connection already in progress */ -#define EALREADY 120 /* Socket already connected */ -#define EDESTADDRREQ 121 /* Destination address required */ -#define EMSGSIZE 122 /* Message too long */ -#define EPROTONOSUPPORT 123 /* Unknown protocol */ -#define ESOCKTNOSUPPORT 124 /* Socket type not supported */ -#define EADDRNOTAVAIL 125 /* Address not available */ -#define ENETRESET 126 -#define EISCONN 127 /* Socket is already connected */ -#define ENOTCONN 128 /* Socket is not connected */ -#define ETOOMANYREFS 129 -#define EPROCLIM 130 -#define EUSERS 131 -#define EDQUOT 132 -#define ESTALE 133 -#define ENOTSUP 134 /* Not supported */ -#define ENOMEDIUM 135 /* No medium (in tape drive) */ -#define ENOSHARE 136 /* No such host or network path */ -#define ECASECLASH 137 /* Filename exists with different case */ -#define EILSEQ 138 -#define EOVERFLOW 139 /* Value too large for defined data type */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define __ELASTERROR 2000 /* Users can add values starting here */ +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* Input/output error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file descriptor */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Resource temporarily unavailable */ +#define ENOMEM 12 /* Cannot allocate memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Invalid cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate ioctl for device */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Numerical argument out of domain */ +#define ERANGE 34 /* Numerical result out of range */ +#define EDEADLK 35 /* Resource deadlock avoided */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many levels of symbolic links */ +#define ENOMSG 41 /* No message of desired type */ +#define EIDRM 42 /* Identifier removed */ +#define ECHRNG 43 /* Channel number out of range */ +#define EL2NSYNC 44 /* Level 2 not synchronized */ +#define EL3HLT 45 /* Level 3 halted */ +#define EL3RST 46 /* Level 3 reset */ +#define ELNRNG 47 /* Link number out of range */ +#define EUNATCH 48 /* Protocol driver not attached */ +#define ENOCSI 49 /* No CSI structure available */ +#define EL2HLT 50 /* Level 2 halted */ +#define EBADE 51 /* Invalid exchange */ +#define EBADR 52 /* Invalid request descriptor */ +#define EXFULL 53 /* Exchange full */ +#define ENOANO 54 /* No anode */ +#define EBADRQC 55 /* Invalid request code */ +#define EBADSLT 56 /* Invalid slot */ +#define EBFONT 57 /* Bad font file format */ +#define ENOSTR 58 /* Device not a stream */ +#define ENODATA 59 /* No data available */ +#define ETIME 60 /* Timer expired */ +#define ENOSR 61 /* Out of streams resources */ +#define ENONET 62 /* Machine is not on the network */ +#define ENOPKG 63 /* Package not installed */ +#define EREMOTE 64 /* Object is remote */ +#define ENOLINK 65 /* Link has been severed */ +#define EADV 66 /* Advertise error */ +#define ESRMNT 67 /* Srmount error */ +#define ECOMM 68 /* Communication error on send */ +#define EPROTO 69 /* Protocol error */ +#define EMULTIHOP 70 /* Multihop attempted */ +#define EDOTDOT 71 /* RFS specific error */ +#define EBADMSG 72 /* Bad message */ +#define EOVERFLOW 73 /* Value too large for defined data type */ +#define ENOTUNIQ 74 /* Name not unique on network */ +#define EBADFD 75 /* File descriptor in bad state */ +#define EREMCHG 76 /* Remote address changed */ +#define ELIBACC 77 /* Can not access a needed shared library */ +#define ELIBBAD 78 /* Accessing a corrupted shared library */ +#define ELIBSCN 79 /* .lib section in a.out corrupted */ +#define ELIBMAX 80 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 81 /* Cannot exec a shared library directly */ +#define EILSEQ 82 /* Invalid or incomplete multibyte or wide character */ +#define ERESTART 83 /* Interrupted system call should be restarted */ +#define ESTRPIPE 84 /* Streams pipe error */ +#define EUSERS 85 /* Too many users */ +#define ENOTSOCK 86 /* Socket operation on non-socket */ +#define EDESTADDRREQ 87 /* Destination address required */ +#define EMSGSIZE 88 /* Message too long */ +#define EPROTOTYPE 89 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 90 /* Protocol not available */ +#define EPROTONOSUPPORT 91 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 92 /* Socket type not supported */ +#define ENOTSUP 93 /* Operation not supported */ +#define EPFNOSUPPORT 94 /* Protocol family not supported */ +#define EAFNOSUPPORT 95 /* Address family not supported by protocol */ +#define EADDRINUSE 96 /* Address already in use */ +#define EADDRNOTAVAIL 97 /* Cannot assign requested address */ +#define ENETDOWN 98 /* Network is down */ +#define ENETUNREACH 99 /* Network is unreachable */ +#define ENETRESET 100 /* Network dropped connection on reset */ +#define ECONNABORTED 101 /* Software caused connection abort */ +#define ECONNRESET 102 /* Connection reset by peer */ +#define ENOBUFS 103 /* No buffer space available */ +#define EISCONN 104 /* Transport endpoint is already connected */ +#define ENOTCONN 105 /* Transport endpoint is not connected */ +#define ESHUTDOWN 106 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 107 /* Too many references: cannot splice */ +#define ETIMEDOUT 108 /* Connection timed out */ +#define ECONNREFUSED 109 /* Connection refused */ +#define EHOSTDOWN 110 /* Host is down */ +#define EHOSTUNREACH 111 /* No route to host */ +#define EALREADY 112 /* Operation already in progress */ +#define EINPROGRESS 113 /* Operation now in progress */ +#define ESTALE 114 /* Stale file handle */ +#define EUCLEAN 115 /* Structure needs cleaning */ +#define ENOTNAM 116 /* Not a XENIX named type file */ +#define ENAVAIL 117 /* No XENIX semaphores available */ +#define EISNAM 118 /* Is a named type file */ +#define EREMOTEIO 119 /* Remote I/O error */ +#define EDQUOT 120 /* Disk quota exceeded */ +#define ENOMEDIUM 121 /* No medium found */ +#define EMEDIUMTYPE 122 /* Wrong medium type */ +#define ECANCELED 123 /* Operation canceled */ +#define ENOKEY 124 /* Required key not available */ +#define EKEYEXPIRED 125 /* Key has expired */ +#define EKEYREVOKED 126 /* Key has been revoked */ +#define EKEYREJECTED 127 /* Key was rejected by service */ +#define EOWNERDEAD 128 /* Owner died */ +#define ENOTRECOVERABLE 129 /* State not recoverable */ +#define ERFKILL 130 /* Operation not possible due to RF-kill */ +#define EHWPOISON 131 /* Memory page has hardware error */ #endif