From b7b49d58014a547cdcca0cf2dccea7110b248be5 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Wed, 7 Mar 2018 21:00:26 -0700 Subject: [PATCH] Implement strerror --- src/errno/src/lib.rs | 429 ++++++++++++++++++++++++++---------------- src/string/src/lib.rs | 18 +- 2 files changed, 283 insertions(+), 164 deletions(-) diff --git a/src/errno/src/lib.rs b/src/errno/src/lib.rs index a40975c9..5d0d6c00 100644 --- a/src/errno/src/lib.rs +++ b/src/errno/src/lib.rs @@ -4,164 +4,271 @@ extern crate platform; -#[repr(C)] -pub enum Errno { - // Argument list too long - E2BIG = 1, - // Permission denied - EACCES, - // Address in use - EADDRINUSE, - // Address not available - EADDRNOTAVAIL, - // Address family not supported - EAFNOSUPPORT, - // Resource unavailable, try again (may be the same value as [EWOULDBLOCK]) - EAGAIN, - // Connection already in progress - EALREADY, - // Bad file descriptor - EBADF, - // Bad message - EBADMSG, - // Device or resource busy - EBUSY, - // Operation canceled - ECANCELED, - // No child processes - ECHILD, - // Connection aborted - ECONNABORTED, - // Connection refused - ECONNREFUSED, - // Connection reset - ECONNRESET, - // Resource deadlock would occur - EDEADLK, - // Destination address required - EDESTADDRREQ, - // Mathematics argument out of domain of function - EDOM, - // Reserved - EDQUOT, - // File exists - EEXIST, - // Bad address - EFAULT, - // File too large - EFBIG, - // Host is unreachable - EHOSTUNREACH, - // Identifier removed - EIDRM, - // Illegal byte sequence - EILSEQ, - // Operation in progress - EINPROGRESS, - // Interrupted function - EINTR, - // Invalid argument - EINVAL, - // I/O error - EIO, - // Socket is connected - EISCONN, - // Is a directory - EISDIR, - // Too many levels of symbolic links - ELOOP, - // Too many open files - EMFILE, - // Too many links - EMLINK, - // Message too large - EMSGSIZE, - // Reserved - EMULTIHOP, - // Filename too long - ENAMETOOLONG, - // Network is down - ENETDOWN, - // Connection aborted by network - ENETRESET, - // Network unreachable - ENETUNREACH, - // Too many files open in system - ENFILE, - // No buffer space available - ENOBUFS, - // No message is available on the STREAM head read queue - ENODATA, - // No such device - ENODEV, - // No such file or directory - ENOENT, - // Executable file format error - ENOEXEC, - // No locks available - ENOLCK, - // Reserved - ENOLINK, - // Not enough space - ENOMEM, - // No message of the desired type - ENOMSG, - // Protocol not available - ENOPROTOOPT, - // No space left on device - ENOSPC, - // No STREAM resources - ENOSR, - // Not a STREAM - ENOSTR, - // Function not supported - ENOSYS, - // The socket is not connected - ENOTCONN, - // Not a directory - ENOTDIR, - // Directory not empty - ENOTEMPTY, - // Not a socket - ENOTSOCK, - // Not supported - ENOTSUP, - // Inappropriate I/O control operation - ENOTTY, - // No such device or address - ENXIO, - // Operation not supported on socket - EOPNOTSUPP, - // Value too large to be stored in data type - EOVERFLOW, - // Operation not permitted - EPERM, - // Broken pipe - EPIPE, - // Protocol error - EPROTO, - // Protocol not supported - EPROTONOSUPPORT, - // Protocol wrong type for socket - EPROTOTYPE, - // Result too large - ERANGE, - // Read-only file system - EROFS, - // Invalid seek - ESPIPE, - // No such process - ESRCH, - // Reserved - ESTALE, - // Stream ioctl() timeout - ETIME, - // Connection timed out - ETIMEDOUT, - // Text file busy - ETXTBSY, - // Operation would block (may be the same value as [EAGAIN]) - EWOULDBLOCK, - // Cross-device link - EXDEV, -} +use platform::types::*; + +pub const EPERM: c_int = 1; /* Operation not permitted */ +pub const ENOENT: c_int = 2; /* No such file or directory */ +pub const ESRCH: c_int = 3; /* No such process */ +pub const EINTR: c_int = 4; /* Interrupted system call */ +pub const EIO: c_int = 5; /* I/O error */ +pub const ENXIO: c_int = 6; /* No such device or address */ +pub const E2BIG: c_int = 7; /* Argument list too long */ +pub const ENOEXEC: c_int = 8; /* Exec format error */ +pub const EBADF: c_int = 9; /* Bad file number */ +pub const ECHILD: c_int = 10; /* No child processes */ +pub const EAGAIN: c_int = 11; /* Try again */ +pub const ENOMEM: c_int = 12; /* Out of memory */ +pub const EACCES: c_int = 13; /* Permission denied */ +pub const EFAULT: c_int = 14; /* Bad address */ +pub const ENOTBLK: c_int = 15; /* Block device required */ +pub const EBUSY: c_int = 16; /* Device or resource busy */ +pub const EEXIST: c_int = 17; /* File exists */ +pub const EXDEV: c_int = 18; /* Cross-device link */ +pub const ENODEV: c_int = 19; /* No such device */ +pub const ENOTDIR: c_int = 20; /* Not a directory */ +pub const EISDIR: c_int = 21; /* Is a directory */ +pub const EINVAL: c_int = 22; /* Invalid argument */ +pub const ENFILE: c_int = 23; /* File table overflow */ +pub const EMFILE: c_int = 24; /* Too many open files */ +pub const ENOTTY: c_int = 25; /* Not a typewriter */ +pub const ETXTBSY: c_int = 26; /* Text file busy */ +pub const EFBIG: c_int = 27; /* File too large */ +pub const ENOSPC: c_int = 28; /* No space left on device */ +pub const ESPIPE: c_int = 29; /* Illegal seek */ +pub const EROFS: c_int = 30; /* Read-only file system */ +pub const EMLINK: c_int = 31; /* Too many links */ +pub const EPIPE: c_int = 32; /* Broken pipe */ +pub const EDOM: c_int = 33; /* Math argument out of domain of func */ +pub const ERANGE: c_int = 34; /* Math result not representable */ +pub const EDEADLK: c_int = 35; /* Resource deadlock would occur */ +pub const ENAMETOOLONG: c_int = 36; /* File name too long */ +pub const ENOLCK: c_int = 37; /* No record locks available */ +pub const ENOSYS: c_int = 38; /* Function not implemented */ +pub const ENOTEMPTY: c_int = 39; /* Directory not empty */ +pub const ELOOP: c_int = 40; /* Too many symbolic links encountered */ +pub const EWOULDBLOCK: c_int = 41; /* Operation would block */ +pub const ENOMSG: c_int = 42; /* No message of desired type */ +pub const EIDRM: c_int = 43; /* Identifier removed */ +pub const ECHRNG: c_int = 44; /* Channel number out of range */ +pub const EL2NSYNC: c_int = 45; /* Level 2 not synchronized */ +pub const EL3HLT: c_int = 46; /* Level 3 halted */ +pub const EL3RST: c_int = 47; /* Level 3 reset */ +pub const ELNRNG: c_int = 48; /* Link number out of range */ +pub const EUNATCH: c_int = 49; /* Protocol driver not attached */ +pub const ENOCSI: c_int = 50; /* No CSI structure available */ +pub const EL2HLT: c_int = 51; /* Level 2 halted */ +pub const EBADE: c_int = 52; /* Invalid exchange */ +pub const EBADR: c_int = 53; /* Invalid request descriptor */ +pub const EXFULL: c_int = 54; /* Exchange full */ +pub const ENOANO: c_int = 55; /* No anode */ +pub const EBADRQC: c_int = 56; /* Invalid request code */ +pub const EBADSLT: c_int = 57; /* Invalid slot */ +pub const EDEADLOCK: c_int = 58; /* Resource deadlock would occur */ +pub const EBFONT: c_int = 59; /* Bad font file format */ +pub const ENOSTR: c_int = 60; /* Device not a stream */ +pub const ENODATA: c_int = 61; /* No data available */ +pub const ETIME: c_int = 62; /* Timer expired */ +pub const ENOSR: c_int = 63; /* Out of streams resources */ +pub const ENONET: c_int = 64; /* Machine is not on the network */ +pub const ENOPKG: c_int = 65; /* Package not installed */ +pub const EREMOTE: c_int = 66; /* Object is remote */ +pub const ENOLINK: c_int = 67; /* Link has been severed */ +pub const EADV: c_int = 68; /* Advertise error */ +pub const ESRMNT: c_int = 69; /* Srmount error */ +pub const ECOMM: c_int = 70; /* Communication error on send */ +pub const EPROTO: c_int = 71; /* Protocol error */ +pub const EMULTIHOP: c_int = 72; /* Multihop attempted */ +pub const EDOTDOT: c_int = 73; /* RFS specific error */ +pub const EBADMSG: c_int = 74; /* Not a data message */ +pub const EOVERFLOW: c_int = 75; /* Value too large for defined data type */ +pub const ENOTUNIQ: c_int = 76; /* Name not unique on network */ +pub const EBADFD: c_int = 77; /* File descriptor in bad state */ +pub const EREMCHG: c_int = 78; /* Remote address changed */ +pub const ELIBACC: c_int = 79; /* Can not access a needed shared library */ +pub const ELIBBAD: c_int = 80; /* Accessing a corrupted shared library */ +pub const ELIBSCN: c_int = 81; /* .lib section in a.out corrupted */ +pub const ELIBMAX: c_int = 82; /* Attempting to link in too many shared libraries */ +pub const ELIBEXEC: c_int = 83; /* Cannot exec a shared library directly */ +pub const EILSEQ: c_int = 84; /* Illegal byte sequence */ +pub const ERESTART: c_int = 85; /* Interrupted system call should be restarted */ +pub const ESTRPIPE: c_int = 86; /* Streams pipe error */ +pub const EUSERS: c_int = 87; /* Too many users */ +pub const ENOTSOCK: c_int = 88; /* Socket operation on non-socket */ +pub const EDESTADDRREQ: c_int = 89; /* Destination address required */ +pub const EMSGSIZE: c_int = 90; /* Message too long */ +pub const EPROTOTYPE: c_int = 91; /* Protocol wrong type for socket */ +pub const ENOPROTOOPT: c_int = 92; /* Protocol not available */ +pub const EPROTONOSUPPORT: c_int = 93; /* Protocol not supported */ +pub const ESOCKTNOSUPPORT: c_int = 94; /* Socket type not supported */ +pub const EOPNOTSUPP: c_int = 95; /* Operation not supported on transport endpoint */ +pub const EPFNOSUPPORT: c_int = 96; /* Protocol family not supported */ +pub const EAFNOSUPPORT: c_int = 97; /* Address family not supported by protocol */ +pub const EADDRINUSE: c_int = 98; /* Address already in use */ +pub const EADDRNOTAVAIL: c_int = 99; /* Cannot assign requested address */ +pub const ENETDOWN: c_int = 100; /* Network is down */ +pub const ENETUNREACH: c_int = 101; /* Network is unreachable */ +pub const ENETRESET: c_int = 102; /* Network dropped connection because of reset */ +pub const ECONNABORTED: c_int = 103; /* Software caused connection abort */ +pub const ECONNRESET: c_int = 104; /* Connection reset by peer */ +pub const ENOBUFS: c_int = 105; /* No buffer space available */ +pub const EISCONN: c_int = 106; /* Transport endpoint is already connected */ +pub const ENOTCONN: c_int = 107; /* Transport endpoint is not connected */ +pub const ESHUTDOWN: c_int = 108; /* Cannot send after transport endpoint shutdown */ +pub const ETOOMANYREFS: c_int = 109; /* Too many references: cannot splice */ +pub const ETIMEDOUT: c_int = 110; /* Connection timed out */ +pub const ECONNREFUSED: c_int = 111; /* Connection refused */ +pub const EHOSTDOWN: c_int = 112; /* Host is down */ +pub const EHOSTUNREACH: c_int = 113; /* No route to host */ +pub const EALREADY: c_int = 114; /* Operation already in progress */ +pub const EINPROGRESS: c_int = 115; /* Operation now in progress */ +pub const ESTALE: c_int = 116; /* Stale NFS file handle */ +pub const EUCLEAN: c_int = 117; /* Structure needs cleaning */ +pub const ENOTNAM: c_int = 118; /* Not a XENIX named type file */ +pub const ENAVAIL: c_int = 119; /* No XENIX semaphores available */ +pub const EISNAM: c_int = 120; /* Is a named type file */ +pub const EREMOTEIO: c_int = 121; /* Remote I/O error */ +pub const EDQUOT: c_int = 122; /* Quota exceeded */ +pub const ENOMEDIUM: c_int = 123; /* No medium found */ +pub const EMEDIUMTYPE: c_int = 124; /* Wrong medium type */ +pub const ECANCELED: c_int = 125; /* Operation Canceled */ +pub const ENOKEY: c_int = 126; /* Required key not available */ +pub const EKEYEXPIRED: c_int = 127; /* Key has expired */ +pub const EKEYREVOKED: c_int = 128; /* Key has been revoked */ +pub const EKEYREJECTED: c_int = 129; /* Key was rejected by service */ +pub const EOWNERDEAD: c_int = 130; /* Owner died */ +pub const ENOTRECOVERABLE: c_int = 131; /* State not recoverable */ + +pub static STR_ERROR: [&'static str; 132] = [ + "Success", + "Operation not permitted", + "No such file or directory", + "No such process", + "Interrupted system call", + "I/O error", + "No such device or address", + "Argument list too long", + "Exec format error", + "Bad file number", + "No child processes", + "Try again", + "Out of memory", + "Permission denied", + "Bad address", + "Block device required", + "Device or resource busy", + "File exists", + "Cross-device link", + "No such device", + "Not a directory", + "Is a directory", + "Invalid argument", + "File table overflow", + "Too many open files", + "Not a typewriter", + "Text file busy", + "File too large", + "No space left on device", + "Illegal seek", + "Read-only file system", + "Too many links", + "Broken pipe", + "Math argument out of domain of func", + "Math result not representable", + "Resource deadlock would occur", + "File name too long", + "No record locks available", + "Function not implemented", + "Directory not empty", + "Too many symbolic links encountered", + "Operation would block", + "No message of desired type", + "Identifier removed", + "Channel number out of range", + "Level 2 not synchronized", + "Level 3 halted", + "Level 3 reset", + "Link number out of range", + "Protocol driver not attached", + "No CSI structure available", + "Level 2 halted", + "Invalid exchange", + "Invalid request descriptor", + "Exchange full", + "No anode", + "Invalid request code", + "Invalid slot", + "Resource deadlock would occur", + "Bad font file format", + "Device not a stream", + "No data available", + "Timer expired", + "Out of streams resources", + "Machine is not on the network", + "Package not installed", + "Object is remote", + "Link has been severed", + "Advertise error", + "Srmount error", + "Communication error on send", + "Protocol error", + "Multihop attempted", + "RFS specific error", + "Not a data message", + "Value too large for defined data type", + "Name not unique on network", + "File descriptor in bad state", + "Remote address changed", + "Can not access a needed shared library", + "Accessing a corrupted shared library", + ".lib section in a.out corrupted", + "Attempting to link in too many shared libraries", + "Cannot exec a shared library directly", + "Illegal byte sequence", + "Interrupted system call should be restarted", + "Streams pipe error", + "Too many users", + "Socket operation on non-socket", + "Destination address required", + "Message too long", + "Protocol wrong type for socket", + "Protocol not available", + "Protocol not supported", + "Socket type not supported", + "Operation not supported on transport endpoint", + "Protocol family not supported", + "Address family not supported by protocol", + "Address already in use", + "Cannot assign requested address", + "Network is down", + "Network is unreachable", + "Network dropped connection because of reset", + "Software caused connection abort", + "Connection reset by peer", + "No buffer space available", + "Transport endpoint is already connected", + "Transport endpoint is not connected", + "Cannot send after transport endpoint shutdown", + "Too many references: cannot splice", + "Connection timed out", + "Connection refused", + "Host is down", + "No route to host", + "Operation already in progress", + "Operation now in progress", + "Stale NFS file handle", + "Structure needs cleaning", + "Not a XENIX named type file", + "No XENIX semaphores available", + "Is a named type file", + "Remote I/O error", + "Quota exceeded", + "No medium found", + "Wrong medium type", + "Operation Canceled", + "Required key not available", + "Key has expired", + "Key has been revoked", + "Key was rejected by service", + "Owner died", + "State not recoverable" +]; diff --git a/src/string/src/lib.rs b/src/string/src/lib.rs index f8a6f425..8252dbf6 100644 --- a/src/string/src/lib.rs +++ b/src/string/src/lib.rs @@ -99,7 +99,7 @@ pub unsafe extern "C" fn strndup(s1: *const c_char, size: usize) -> *mut c_char // the "+ 1" is to account for the NUL byte let buffer = stdlib::malloc(len + 1) as *mut c_char; if buffer.is_null() { - platform::errno = Errno::ENOMEM as c_int; + platform::errno = ENOMEM as c_int; } else { //memcpy(buffer, s1, len) for i in 0..len as isize { @@ -112,8 +112,20 @@ pub unsafe extern "C" fn strndup(s1: *const c_char, size: usize) -> *mut c_char } #[no_mangle] -pub extern "C" fn strerror(errnum: c_int) -> *mut c_char { - unimplemented!(); +pub unsafe extern "C" fn strerror(errnum: c_int) -> *mut c_char { + use core::fmt::Write; + + static mut strerror_buf: [u8; 256] = [0; 256]; + + let mut w = platform::StringWriter(strerror_buf.as_mut_ptr(), strerror_buf.len()); + + if errnum >= 0 && errnum < STR_ERROR.len() as c_int { + w.write_str(STR_ERROR[errnum as usize]); + } else { + w.write_fmt(format_args!("Unknown error {}", errnum)); + } + + strerror_buf.as_mut_ptr() as *mut c_char } #[no_mangle] -- GitLab