瀏覽代碼

Begin converting `os.Errno` to be a `nil`-able type as a transition period

gingerBill 1 年之前
父節點
當前提交
e60951a902

+ 1 - 1
core/crypto/rand_windows.odin

@@ -10,7 +10,7 @@ HAS_RAND_BYTES :: true
 _rand_bytes :: proc(dst: []byte) {
 	ret := (os.Errno)(win32.BCryptGenRandom(nil, raw_data(dst), u32(len(dst)), win32.BCRYPT_USE_SYSTEM_PREFERRED_RNG))
 	if ret != os.ERROR_NONE {
-		switch ret {
+		#partial switch ret {
 		case os.ERROR_INVALID_HANDLE:
 			// The handle to the first parameter is invalid.
 			// This should not happen here, since we explicitly pass nil to it

+ 6 - 0
core/os/os.odin

@@ -13,6 +13,12 @@ SEEK_SET :: 0
 SEEK_CUR :: 1
 SEEK_END :: 2
 
+Platform_Error :: _Platform_Error
+Error :: Platform_Error
+Errno :: Error // alias
+
+ERROR_NONE :: Errno(0)
+
 write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
 	return write(fd, transmute([]byte)str)
 }

+ 4 - 4
core/os/os2/errors.odin

@@ -3,7 +3,7 @@ package os2
 import "core:io"
 import "base:runtime"
 
-General_Error :: enum u32 {
+General_Platform_Error :: enum u32 {
 	None,
 
 	Permission_Denied,
@@ -29,7 +29,7 @@ General_Error :: enum u32 {
 	Unsupported,
 }
 
-Platform_Error :: enum i32 {None=0}
+Platform_Platform_Error :: enum i32 {None=0}
 
 Error :: union #shared_nil {
 	General_Error,
@@ -43,7 +43,7 @@ ERROR_NONE :: Error{}
 
 
 
-is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool) {
+is_platform_Platform_Error :: proc(ferr: Error) -> (err: i32, ok: bool) {
 	v := ferr.(Platform_Error) or_else {}
 	return i32(v), i32(v) != 0
 }
@@ -104,7 +104,7 @@ error_string :: proc(ferr: Error) -> string {
 	return "unknown error"
 }
 
-print_error :: proc(f: ^File, ferr: Error, msg: string) {
+print_Platform_Error :: proc(f: ^File, ferr: Error, msg: string) {
 	TEMP_ALLOCATOR_GUARD()
 	err_str := error_string(ferr)
 

+ 1 - 1
core/os/os2/errors_linux.odin

@@ -142,7 +142,7 @@ _errno_strings : [linux.Errno]string = {
 }
 
 
-_get_platform_error :: proc(errno: linux.Errno) -> Error {
+_get_platform_Platform_Error :: proc(errno: linux.Errno) -> Error {
 	#partial switch errno {
 	case .NONE:
 		return nil

+ 1 - 1
core/os/os2/errors_windows.odin

@@ -20,7 +20,7 @@ _error_string :: proc(errno: i32) -> string {
 	return "<unknown platform error>"
 }
 
-_get_platform_error :: proc() -> Error {
+_get_platform_Platform_Error :: proc() -> Error {
 	err := win32.GetLastError()
 	if err == 0 {
 		return nil

+ 1 - 1
core/os/os2/file_stream.odin

@@ -15,7 +15,7 @@ to_reader :: to_stream
 
 
 @(private)
-error_to_io_error :: proc(ferr: Error) -> io.Error {
+error_to_io_Platform_Error :: proc(ferr: Error) -> io.Error {
 	if ferr == nil {
 		return .None
 	}

+ 1 - 1
core/os/os2/process.odin

@@ -370,7 +370,7 @@ Process_State :: struct {
 	timeout (if specified) has reached zero. If the timeout is `TIMEOUT_INFINITE`,
 	no timeout restriction is imposed and the procedure can block indefinately.
 
-	If the timeout has expired, the `General_Error.Timeout` is returned as
+	If the timeout has expired, the `GeneralPlatform_Error.Timeout` is returned as
 	the error.
 
 	If an error is returned for any other reason, other than timeout, the

+ 7 - 7
core/os/os2/process_windows.odin

@@ -101,7 +101,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 	if selection >= {.PPid, .Priority} {
 		entry, entry_err := _process_entry_by_pid(info.pid)
 		if entry_err != nil {
-			err = General_Error.Not_Exist
+			err = GeneralPlatform_Error.Not_Exist
 			return
 		}
 		if .PPid in selection {
@@ -147,7 +147,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 		}
 		if process_info.PebBaseAddress == nil {
 			// Not sure what the error is
-			err = General_Error.Unsupported
+			err = GeneralPlatform_Error.Unsupported
 			return
 		}
 		process_peb: win32.PEB
@@ -210,7 +210,7 @@ _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields
 	if selection >= {.PPid, .Priority} { // snap process
 		entry, entry_err := _process_entry_by_pid(info.pid)
 		if entry_err != nil {
-			err = General_Error.Not_Exist
+			err = GeneralPlatform_Error.Not_Exist
 			return
 		}
 		if .PPid in selection {
@@ -239,7 +239,7 @@ _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields
 		}
 		if process_info.PebBaseAddress == nil {
 			// Not sure what the error is
-			err = General_Error.Unsupported
+			err = GeneralPlatform_Error.Unsupported
 			return
 		}
 
@@ -301,7 +301,7 @@ _current_process_info :: proc(selection: Process_Info_Fields, allocator: runtime
 	if selection >= {.PPid, .Priority} { // snap process
 		entry, entry_err := _process_entry_by_pid(info.pid)
 		if entry_err != nil {
-			err = General_Error.Not_Exist
+			err = GeneralPlatform_Error.Not_Exist
 			return
 		}
 		if .PPid in selection {
@@ -459,7 +459,7 @@ _process_wait :: proc(process: Process, timeout: time.Duration) -> (process_stat
 		}
 		return
 	case win32.WAIT_TIMEOUT:
-		err = General_Error.Timeout
+		err = GeneralPlatform_Error.Timeout
 		return
 	case:
 		err = _get_platform_error()
@@ -508,7 +508,7 @@ _process_entry_by_pid :: proc(pid: int) -> (entry: win32.PROCESSENTRY32W, err: E
 		}
 		status = win32.Process32NextW(snap, &entry)
 	}
-	err = General_Error.Not_Exist
+	err = GeneralPlatform_Error.Not_Exist
 	return
 }
 

+ 252 - 141
core/os/os_darwin.odin

@@ -10,146 +10,257 @@ import "core:c"
 
 Handle    :: distinct i32
 File_Time :: distinct u64
-Errno     :: distinct int
 
 INVALID_HANDLE :: ~Handle(0)
 
-ERROR_NONE: Errno : 0
-EPERM:		Errno : 1		/* Operation not permitted */
-ENOENT:		Errno : 2		/* No such file or directory */
-ESRCH:		Errno : 3		/* No such process */
-EINTR:		Errno : 4		/* Interrupted system call */
-EIO:		Errno : 5		/* Input/output error */
-ENXIO:		Errno : 6		/* Device not configured */
-E2BIG:		Errno : 7		/* Argument list too long */
-ENOEXEC:	Errno : 8		/* Exec format error */
-EBADF:		Errno : 9		/* Bad file descriptor */
-ECHILD:		Errno : 10		/* No child processes */
-EDEADLK:	Errno : 11		/* Resource deadlock avoided */
-ENOMEM:		Errno : 12		/* Cannot allocate memory */
-EACCES:		Errno : 13		/* Permission denied */
-EFAULT:		Errno : 14		/* Bad address */
-ENOTBLK:	Errno : 15		/* Block device required */
-EBUSY:		Errno : 16		/* Device / Resource busy */
-EEXIST:		Errno : 17		/* File exists */
-EXDEV:		Errno : 18		/* Cross-device link */
-ENODEV:		Errno : 19		/* Operation not supported by device */
-ENOTDIR:	Errno : 20		/* Not a directory */
-EISDIR:		Errno : 21		/* Is a directory */
-EINVAL:		Errno : 22		/* Invalid argument */
-ENFILE:		Errno : 23		/* Too many open files in system */
-EMFILE:		Errno : 24		/* Too many open files */
-ENOTTY:		Errno : 25		/* Inappropriate ioctl for device */
-ETXTBSY:	Errno : 26		/* Text file busy */
-EFBIG:		Errno : 27		/* File too large */
-ENOSPC:		Errno : 28		/* No space left on device */
-ESPIPE:		Errno : 29		/* Illegal seek */
-EROFS:		Errno : 30		/* Read-only file system */
-EMLINK:		Errno : 31		/* Too many links */
-EPIPE:		Errno : 32		/* Broken pipe */
-
-/* math software */
-EDOM:		Errno : 33		/* Numerical argument out of domain */
-ERANGE:		Errno : 34		/* Result too large */
-
-/* non-blocking and interrupt i/o */
-EAGAIN:			Errno : 35		/* Resource temporarily unavailable */
-EWOULDBLOCK: 	Errno : EAGAIN		/* Operation would block */
-EINPROGRESS: 	Errno : 36		/* Operation now in progress */
-EALREADY:		Errno : 37		/* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-ENOTSOCK:			Errno : 38		/* Socket operation on non-socket */
-EDESTADDRREQ:		Errno : 39		/* Destination address required */
-EMSGSIZE:			Errno : 40		/* Message too long */
-EPROTOTYPE:			Errno : 41		/* Protocol wrong type for socket */
-ENOPROTOOPT:		Errno : 42		/* Protocol not available */
-EPROTONOSUPPORT:	Errno : 43		/* Protocol not supported */
-ESOCKTNOSUPPORT:	Errno : 44		/* Socket type not supported */
-ENOTSUP:			Errno : 45		/* Operation not supported */
-EOPNOTSUPP::		ENOTSUP
-EPFNOSUPPORT:		Errno : 46		/* Protocol family not supported */
-EAFNOSUPPORT:		Errno : 47		/* Address family not supported by protocol family */
-EADDRINUSE:			Errno : 48		/* Address already in use */
-EADDRNOTAVAIL:		Errno : 49		/* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-ENETDOWN:		Errno : 50		/* Network is down */
-ENETUNREACH:	Errno : 51		/* Network is unreachable */
-ENETRESET:		Errno : 52		/* Network dropped connection on reset */
-ECONNABORTED:	Errno : 53		/* Software caused connection abort */
-ECONNRESET:		Errno : 54		/* Connection reset by peer */
-ENOBUFS:		Errno : 55		/* No buffer space available */
-EISCONN:		Errno : 56		/* Socket is already connected */
-ENOTCONN:		Errno : 57		/* Socket is not connected */
-ESHUTDOWN:		Errno : 58		/* Can't send after socket shutdown */
-ETOOMANYREFS:	Errno : 59		/* Too many references: can't splice */
-ETIMEDOUT:		Errno : 60		/* Operation timed out */
-ECONNREFUSED:	Errno : 61		/* Connection refused */
-
-ELOOP:			Errno : 62		/* Too many levels of symbolic links */
-ENAMETOOLONG:	Errno : 63		/* File name too long */
-
-/* should be rearranged */
-EHOSTDOWN:		Errno : 64		/* Host is down */
-EHOSTUNREACH:	Errno : 65		/* No route to host */
-ENOTEMPTY:		Errno : 66		/* Directory not empty */
-
-/* quotas & mush */
-EPROCLIM:		Errno : 67		/* Too many processes */
-EUSERS:			Errno : 68		/* Too many users */
-EDQUOT:			Errno : 69		/* Disc quota exceeded */
-
-/* Network File System */
-ESTALE:			Errno : 70		/* Stale NFS file handle */
-EREMOTE:		Errno : 71		/* Too many levels of remote in path */
-EBADRPC:		Errno : 72		/* RPC struct is bad */
-ERPCMISMATCH:	Errno : 73		/* RPC version wrong */
-EPROGUNAVAIL:	Errno : 74		/* RPC prog. not avail */
-EPROGMISMATCH:	Errno : 75		/* Program version wrong */
-EPROCUNAVAIL:	Errno : 76		/* Bad procedure for program */
-
-ENOLCK:	Errno : 77		/* No locks available */
-ENOSYS:	Errno : 78		/* Function not implemented */
-
-EFTYPE:	Errno : 79		/* Inappropriate file type or format */
-EAUTH:	Errno : 80		/* Authentication error */
-ENEEDAUTH:	Errno : 81		/* Need authenticator */
-
-/* Intelligent device errors */
-EPWROFF:	Errno : 82	/* Device power is off */
-EDEVERR:	Errno : 83	/* Device error, e.g. paper out */
-EOVERFLOW:	Errno : 84		/* Value too large to be stored in data type */
-
-/* Program loading errors */
-EBADEXEC:	Errno : 85	/* Bad executable */
-EBADARCH:	Errno : 86	/* Bad CPU type in executable */
-ESHLIBVERS:	Errno : 87	/* Shared library version mismatch */
-EBADMACHO:	Errno : 88	/* Malformed Macho file */
-
-ECANCELED:	Errno : 89		/* Operation canceled */
-
-EIDRM:		Errno : 90		/* Identifier removed */
-ENOMSG:		Errno : 91		/* No message of desired type */
-EILSEQ:		Errno : 92		/* Illegal byte sequence */
-ENOATTR:	Errno : 93		/* Attribute not found */
-
-EBADMSG:	Errno : 94		/* Bad message */
-EMULTIHOP:	Errno : 95		/* Reserved */
-ENODATA:	Errno : 96		/* No message available on STREAM */
-ENOLINK:	Errno : 97		/* Reserved */
-ENOSR:		Errno : 98		/* No STREAM resources */
-ENOSTR:		Errno : 99		/* Not a STREAM */
-EPROTO:		Errno : 100		/* Protocol error */
-ETIME:		Errno : 101		/* STREAM ioctl timeout */
-
-ENOPOLICY:	Errno : 103		/* No such policy registered */
-
-ENOTRECOVERABLE:	Errno : 104		/* State not recoverable */
-EOWNERDEAD:			Errno : 105		/* Previous owner died */
-
-EQFULL:	Errno : 106		/* Interface output queue is full */
-ELAST:	Errno : 106		/* Must be equal largest errno */
+_Platform_Error :: enum i32  {
+	NONE       = 0,
+	EPERM      = 1,       /* Operation not permitted */
+	ENOENT     = 2,       /* No such file or directory */
+	ESRCH      = 3,       /* No such process */
+	EINTR      = 4,       /* Interrupted system call */
+	EIO        = 5,       /* Input/output error */
+	ENXIO      = 6,       /* Device not configured */
+	E2BIG      = 7,       /* Argument list too long */
+	ENOEXEC    = 8,       /* Exec format error */
+	EBADF      = 9,       /* Bad file descriptor */
+	ECHILD     = 10,      /* No child processes */
+	EDEADLK    = 11,      /* Resource deadlock avoided */
+	ENOMEM     = 12,      /* Cannot allocate memory */
+	EACCES     = 13,      /* Permission denied */
+	EFAULT     = 14,      /* Bad address */
+	ENOTBLK    = 15,      /* Block device required */
+	EBUSY      = 16,      /* Device / Resource busy */
+	EEXIST     = 17,      /* File exists */
+	EXDEV      = 18,      /* Cross-device link */
+	ENODEV     = 19,      /* Operation not supported by device */
+	ENOTDIR    = 20,      /* Not a directory */
+	EISDIR     = 21,      /* Is a directory */
+	EINVAL     = 22,      /* Invalid argument */
+	ENFILE     = 23,      /* Too many open files in system */
+	EMFILE     = 24,      /* Too many open files */
+	ENOTTY     = 25,      /* Inappropriate ioctl for device */
+	ETXTBSY    = 26,      /* Text file busy */
+	EFBIG      = 27,      /* File too large */
+	ENOSPC     = 28,      /* No space left on device */
+	ESPIPE     = 29,      /* Illegal seek */
+	EROFS      = 30,      /* Read-only file system */
+	EMLINK     = 31,      /* Too many links */
+	EPIPE      = 32,      /* Broken pipe */
+
+	/* math software */
+	EDOM   = 33,          /* Numerical argument out of domain */
+	ERANGE = 34,          /* Result too large */
+
+	/* non-blocking and interrupt i/o */
+	EAGAIN      = 35,         /* Resource temporarily unavailable */
+	EWOULDBLOCK = EAGAIN, /* Operation would block */
+	EINPROGRESS = 36,         /* Operation now in progress */
+	EALREADY    = 37,         /* Operation already in progress */
+
+	/* ipc/network software -- argument errors */
+	ENOTSOCK       = 38,    /* Socket operation on non-socket */
+	EDESTADDRREQ   = 39,    /* Destination address required */
+	EMSGSIZE       = 40,    /* Message too long */
+	EPROTOTYPE     = 41,    /* Protocol wrong type for socket */
+	ENOPROTOOPT    = 42,    /* Protocol not available */
+	EPROTONOSUPPOR = 43,    /* Protocol not supported */
+	ESOCKTNOSUPPOR = 44,    /* Socket type not supported */
+	ENOTSUP        = 45,    /* Operation not supported */
+	EOPNOTSUPP     = ENOTSUP,
+	EPFNOSUPPORT   = 46,    /* Protocol family not supported */
+	EAFNOSUPPORT   = 47,    /* Address family not supported by protocol family */
+	EADDRINUSE     = 48,    /* Address already in use */
+	EADDRNOTAVAIL  = 49,    /* Can't assign requested address */
+
+	/* ipc/network software -- operational errors */
+	ENETDOWN       = 50,    /* Network is down */
+	ENETUNREAC     = 51,    /* Network is unreachable */
+	ENETRESET      = 52,    /* Network dropped connection on reset */
+	ECONNABORTE    = 53,    /* Software caused connection abort */
+	ECONNRESET     = 54,    /* Connection reset by peer */
+	ENOBUFS        = 55,    /* No buffer space available */
+	EISCONN        = 56,    /* Socket is already connected */
+	ENOTCONN       = 57,    /* Socket is not connected */
+	ESHUTDOWN      = 58,    /* Can't send after socket shutdown */
+	ETOOMANYREF    = 59,    /* Too many references: can't splice */
+	ETIMEDOUT      = 60,    /* Operation timed out */
+	ECONNREFUSE    = 61,    /* Connection refused */
+
+	ELOOP          = 62,    /* Too many levels of symbolic links */
+	ENAMETOOLON    = 63,    /* File name too long */
+
+	/* should be rearranged */
+	EHOSTDOWN      = 64,    /* Host is down */
+	EHOSTUNREAC    = 65,    /* No route to host */
+	ENOTEMPTY      = 66,    /* Directory not empty */
+
+	/* quotas & mush */
+	EPROCLIM       = 67,    /* Too many processes */
+	EUSERS         = 68,    /* Too many users */
+	EDQUOT         = 69,    /* Disc quota exceeded */
+
+	/* Network File System */
+	ESTALE         = 70,    /* Stale NFS file handle */
+	EREMOTE        = 71,    /* Too many levels of remote in path */
+	EBADRPC        = 72,    /* RPC struct is bad */
+	ERPCMISMATC    = 73,    /* RPC version wrong */
+	EPROGUNAVAI    = 74,    /* RPC prog. not avail */
+	EPROGMISMATC   = 75,    /* Program version wrong */
+	EPROCUNAVAI    = 76,    /* Bad procedure for program */
+
+	ENOLC          = 77,    /* No locks available */
+	ENOSY          = 78,    /* Function not implemented */
+
+	EFTYP          = 79,    /* Inappropriate file type or format */
+	EAUT           = 80,    /* Authentication error */
+	ENEEDAUT       = 81,    /* Need authenticator */
+
+	/* Intelligent device errors */
+	EPWROF         = 82,    /* Device power is off */
+	EDEVER         = 83,    /* Device error, e.g. paper out */
+	EOVERFLO       = 84,    /* Value too large to be stored in data type */
+
+	/* Program loading errors */
+	EBADEXE        = 85,    /* Bad executable */
+	EBADARC        = 86,    /* Bad CPU type in executable */
+	ESHLIBVER      = 87,    /* Shared library version mismatch */
+	EBADMACH       = 88,    /* Malformed Macho file */
+
+	ECANCELE       = 89,    /* Operation canceled */
+
+	EIDRM          = 90,    /* Identifier removed */
+	ENOMSG         = 91,    /* No message of desired type */
+	EILSEQ         = 92,    /* Illegal byte sequence */
+	ENOATT         = 93,    /* Attribute not found */
+
+	EBADMS         = 94,    /* Bad message */
+	EMULTIHO       = 95,    /* Reserved */
+	ENODAT         = 96,    /* No message available on STREAM */
+	ENOLIN         = 97,    /* Reserved */
+	ENOSR          = 98,    /* No STREAM resources */
+	ENOSTR         = 99,    /* Not a STREAM */
+	EPROTO         = 100,  /* Protocol error */
+	ETIME          = 101,  /* STREAM ioctl timeout */
+
+	ENOPOLIC       = 103,  /* No such policy registered */
+
+	ENOTRECOVERABL = 104,  /* State not recoverable */
+	EOWNERDEAD     = 105,  /* Previous owner died */
+
+	EQFUL          = 106,  /* Interface output queue is full */
+	ELAS           = 106,  /* Must be equal largest errno */
+}
+
+
+EPERM          :: Platform_Error.EPERM
+ENOENT         :: Platform_Error.ENOENT
+ESRCH          :: Platform_Error.ESRCH
+EINTR          :: Platform_Error.EINTR
+EIO            :: Platform_Error.EIO
+ENXIO          :: Platform_Error.ENXIO
+E2BIG          :: Platform_Error.E2BIG
+ENOEXEC        :: Platform_Error.ENOEXEC
+EBADF          :: Platform_Error.EBADF
+ECHILD         :: Platform_Error.ECHILD
+EDEADLK        :: Platform_Error.EDEADLK
+ENOMEM         :: Platform_Error.ENOMEM
+EACCES         :: Platform_Error.EACCES
+EFAULT         :: Platform_Error.EFAULT
+ENOTBLK        :: Platform_Error.ENOTBLK
+EBUSY          :: Platform_Error.EBUSY
+EEXIST         :: Platform_Error.EEXIST
+EXDEV          :: Platform_Error.EXDEV
+ENODEV         :: Platform_Error.ENODEV
+ENOTDIR        :: Platform_Error.ENOTDIR
+EISDIR         :: Platform_Error.EISDIR
+EINVAL         :: Platform_Error.EINVAL
+ENFILE         :: Platform_Error.ENFILE
+EMFILE         :: Platform_Error.EMFILE
+ENOTTY         :: Platform_Error.ENOTTY
+ETXTBSY        :: Platform_Error.ETXTBSY
+EFBIG          :: Platform_Error.EFBIG
+ENOSPC         :: Platform_Error.ENOSPC
+ESPIPE         :: Platform_Error.ESPIPE
+EROFS          :: Platform_Error.EROFS
+EMLINK         :: Platform_Error.EMLINK
+EPIPE          :: Platform_Error.EPIPE
+EDOM           :: Platform_Error.EDOM
+ERANGE         :: Platform_Error.ERANGE
+EAGAIN         :: Platform_Error.EAGAIN
+EWOULDBLOCK    :: Platform_Error.EWOULDBLOCK
+EINPROGRESS    :: Platform_Error.EINPROGRESS
+EALREADY       :: Platform_Error.EALREADY
+ENOTSOCK       :: Platform_Error.ENOTSOCK
+EDESTADDRREQ   :: Platform_Error.EDESTADDRREQ
+EMSGSIZE       :: Platform_Error.EMSGSIZE
+EPROTOTYPE     :: Platform_Error.EPROTOTYPE
+ENOPROTOOPT    :: Platform_Error.ENOPROTOOPT
+EPROTONOSUPPOR :: Platform_Error.EPROTONOSUPPOR
+ESOCKTNOSUPPOR :: Platform_Error.ESOCKTNOSUPPOR
+ENOTSUP        :: Platform_Error.ENOTSUP
+EOPNOTSUPP     :: Platform_Error.EOPNOTSUPP
+EPFNOSUPPORT   :: Platform_Error.EPFNOSUPPORT
+EAFNOSUPPORT   :: Platform_Error.EAFNOSUPPORT
+EADDRINUSE     :: Platform_Error.EADDRINUSE
+EADDRNOTAVAIL  :: Platform_Error.EADDRNOTAVAIL
+ENETDOWN       :: Platform_Error.ENETDOWN
+ENETUNREAC     :: Platform_Error.ENETUNREAC
+ENETRESET      :: Platform_Error.ENETRESET
+ECONNABORTE    :: Platform_Error.ECONNABORTE
+ECONNRESET     :: Platform_Error.ECONNRESET
+ENOBUFS        :: Platform_Error.ENOBUFS
+EISCONN        :: Platform_Error.EISCONN
+ENOTCONN       :: Platform_Error.ENOTCONN
+ESHUTDOWN      :: Platform_Error.ESHUTDOWN
+ETOOMANYREF    :: Platform_Error.ETOOMANYREF
+ETIMEDOUT      :: Platform_Error.ETIMEDOUT
+ECONNREFUSE    :: Platform_Error.ECONNREFUSE
+ELOOP          :: Platform_Error.ELOOP
+ENAMETOOLON    :: Platform_Error.ENAMETOOLON
+EHOSTDOWN      :: Platform_Error.EHOSTDOWN
+EHOSTUNREAC    :: Platform_Error.EHOSTUNREAC
+ENOTEMPTY      :: Platform_Error.ENOTEMPTY
+EPROCLIM       :: Platform_Error.EPROCLIM
+EUSERS         :: Platform_Error.EUSERS
+EDQUOT         :: Platform_Error.EDQUOT
+ESTALE         :: Platform_Error.ESTALE
+EREMOTE        :: Platform_Error.EREMOTE
+EBADRPC        :: Platform_Error.EBADRPC
+ERPCMISMATC    :: Platform_Error.ERPCMISMATC
+EPROGUNAVAI    :: Platform_Error.EPROGUNAVAI
+EPROGMISMATC   :: Platform_Error.EPROGMISMATC
+EPROCUNAVAI    :: Platform_Error.EPROCUNAVAI
+ENOLC          :: Platform_Error.ENOLC
+ENOSY          :: Platform_Error.ENOSY
+EFTYP          :: Platform_Error.EFTYP
+EAUT           :: Platform_Error.EAUT
+ENEEDAUT       :: Platform_Error.ENEEDAUT
+EPWROF         :: Platform_Error.EPWROF
+EDEVER         :: Platform_Error.EDEVER
+EOVERFLO       :: Platform_Error.EOVERFLO
+EBADEXE        :: Platform_Error.EBADEXE
+EBADARC        :: Platform_Error.EBADARC
+ESHLIBVER      :: Platform_Error.ESHLIBVER
+EBADMACH       :: Platform_Error.EBADMACH
+ECANCELE       :: Platform_Error.ECANCELE
+EIDRM          :: Platform_Error.EIDRM
+ENOMSG         :: Platform_Error.ENOMSG
+EILSEQ         :: Platform_Error.EILSEQ
+ENOATT         :: Platform_Error.ENOATT
+EBADMS         :: Platform_Error.EBADMS
+EMULTIHO       :: Platform_Error.EMULTIHO
+ENODAT         :: Platform_Error.ENODAT
+ENOLIN         :: Platform_Error.ENOLIN
+ENOSR          :: Platform_Error.ENOSR
+ENOSTR         :: Platform_Error.ENOSTR
+EPROTO         :: Platform_Error.EPROTO
+ETIME          :: Platform_Error.ETIME
+ENOPOLIC       :: Platform_Error.ENOPOLIC
+ENOTRECOVERABL :: Platform_Error.ENOTRECOVERABL
+EOWNERDEAD     :: Platform_Error.EOWNERDEAD
+EQFUL          :: Platform_Error.EQFUL
+ELAS           :: Platform_Error.ELAS
 
 O_RDONLY   :: 0x0000
 O_WRONLY   :: 0x0001
@@ -524,12 +635,12 @@ foreign dl {
 	@(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---
 }
 
-get_last_error :: proc "contextless" () -> int {
-	return int(__error()^)
+get_last_error :: proc "contextless" () -> Error {
+	return Error(__error()^)
 }
 
 get_last_error_string :: proc() -> string {
-	return cast(string)_darwin_string_error(cast(c.int)get_last_error())
+	return string(_darwin_string_error(__error()^))
 }
 
 
@@ -548,7 +659,7 @@ open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (Handle, Errno
 	cstr := strings.clone_to_cstring(path, context.temp_allocator)
 	handle := _unix_open(cstr, i32(flags), u16(mode))
 	if handle == -1 {
-		return INVALID_HANDLE, cast(Errno)get_last_error()
+		return INVALID_HANDLE, get_last_error()
 	}
 
 	/*

+ 18 - 18
core/os/os_essence.odin

@@ -2,54 +2,54 @@ package os
 
 import "core:sys/es"
 
-Handle :: distinct int;
-Errno :: distinct int;
+Handle :: distinct int
+_Platform_Error :: enum i32 {NONE}
 
-ERROR_NONE :: (Errno) (es.SUCCESS);
+ERROR_NONE :: Errno(es.SUCCESS)
 
-O_RDONLY :: 0x1;
-O_WRONLY :: 0x2;
-O_CREATE :: 0x4;
-O_TRUNC  :: 0x8;
+O_RDONLY :: 0x1
+O_WRONLY :: 0x2
+O_CREATE :: 0x4
+O_TRUNC  :: 0x8
 
-stderr : Handle = 0; 
+stderr : Handle = 0
 
 current_thread_id :: proc "contextless" () -> int {
-	return (int) (es.ThreadGetID(es.CURRENT_THREAD));
+	return (int) (es.ThreadGetID(es.CURRENT_THREAD))
 }
 
 heap_alloc :: proc(size: int, zero_memory := true) -> rawptr {
-	return es.HeapAllocate(size, zero_memory);
+	return es.HeapAllocate(size, zero_memory)
 }
 
 heap_free :: proc(ptr: rawptr) {
-	es.HeapFree(ptr);
+	es.HeapFree(ptr)
 }
 
 heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
-	return es.HeapReallocate(ptr, new_size, false);
+	return es.HeapReallocate(ptr, new_size, false)
 }
 
 open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) {
-	return (Handle) (0), (Errno) (1);
+	return (Handle) (0), (Errno) (1)
 }
 
 close :: proc(fd: Handle) -> Errno {
-	return (Errno) (1);
+	return (Errno) (1)
 }
 
 file_size :: proc(fd: Handle) -> (i64, Errno) {
-	return (i64) (0), (Errno) (1);
+	return (i64) (0), (Errno) (1)
 }
 
 read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
-	return (int) (0), (Errno) (1);
+	return (int) (0), (Errno) (1)
 }
 
 write :: proc(fd: Handle, data: []u8) -> (int, Errno) {
-	return (int) (0), (Errno) (1);
+	return (int) (0), (Errno) (1)
 }
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
-	return (i64) (0), (Errno) (1);
+	return (i64) (0), (Errno) (1)
 }

+ 193 - 98
core/os/os_freebsd.odin

@@ -9,105 +9,200 @@ import "core:c"
 
 Handle :: distinct i32
 File_Time :: distinct u64
-Errno :: distinct i32
 
 INVALID_HANDLE :: ~Handle(0)
 
-ERROR_NONE:      Errno : 0
-EPERM:           Errno : 1
-ENOENT:          Errno : 2
-ESRCH:           Errno : 3
-EINTR:           Errno : 4
-EIO:             Errno : 5
-ENXIO:           Errno : 6
-E2BIG:           Errno : 7
-ENOEXEC:         Errno : 8
-EBADF:           Errno : 9
-ECHILD:          Errno : 10
-EBEADLK:         Errno : 11
-ENOMEM:          Errno : 12
-EACCESS:         Errno : 13
-EFAULT:          Errno : 14
-ENOTBLK:         Errno : 15
-EBUSY:           Errno : 16
-EEXIST:          Errno : 17
-EXDEV:           Errno : 18
-ENODEV:          Errno : 19
-ENOTDIR:         Errno : 20
-EISDIR:          Errno : 21
-EINVAL:          Errno : 22
-ENFILE:          Errno : 23
-EMFILE:          Errno : 24
-ENOTTY:          Errno : 25
-ETXTBSY:         Errno : 26
-EFBIG:           Errno : 27
-ENOSPC:          Errno : 28
-ESPIPE:          Errno : 29
-EROFS:           Errno : 30
-EMLINK:          Errno : 31
-EPIPE:           Errno : 32
-EDOM:            Errno : 33
-ERANGE:          Errno : 34 /* Result too large */
-EAGAIN:          Errno : 35
-EINPROGRESS:     Errno : 36
-EALREADY:        Errno : 37
-ENOTSOCK:        Errno : 38
-EDESTADDRREQ:    Errno : 39
-EMSGSIZE:        Errno : 40
-EPROTOTYPE:      Errno : 41
-ENOPROTOOPT:     Errno : 42
-EPROTONOSUPPORT: Errno : 43
-ESOCKTNOSUPPORT: Errno : 44
-EOPNOTSUPP:      Errno : 45
-EPFNOSUPPORT:    Errno : 46
-EAFNOSUPPORT:    Errno : 47
-EADDRINUSE:      Errno : 48
-EADDRNOTAVAIL:   Errno : 49
-ENETDOWN:        Errno : 50
-ENETUNREACH:     Errno : 51
-ENETRESET:       Errno : 52
-ECONNABORTED:    Errno : 53
-ECONNRESET:      Errno : 54
-ENOBUFS:         Errno : 55
-EISCONN:         Errno : 56
-ENOTCONN:        Errno : 57
-ESHUTDOWN:       Errno : 58
-ETIMEDOUT:       Errno : 60
-ECONNREFUSED:    Errno : 61
-ELOOP:           Errno : 62
-ENAMETOOLING:    Errno : 63
-EHOSTDOWN:       Errno : 64
-EHOSTUNREACH:    Errno : 65
-ENOTEMPTY:       Errno : 66
-EPROCLIM:        Errno : 67
-EUSERS:          Errno : 68
-EDQUOT:          Errno : 69
-ESTALE:          Errno : 70
-EBADRPC:         Errno : 72
-ERPCMISMATCH:    Errno : 73
-EPROGUNAVAIL:    Errno : 74
-EPROGMISMATCH:   Errno : 75
-EPROCUNAVAIL:    Errno : 76
-ENOLCK:          Errno : 77
-ENOSYS:          Errno : 78
-EFTYPE:          Errno : 79
-EAUTH:           Errno : 80
-ENEEDAUTH:       Errno : 81
-EIDRM:           Errno : 82
-ENOMSG:          Errno : 83
-EOVERFLOW:       Errno : 84
-ECANCELED:       Errno : 85
-EILSEQ:          Errno : 86
-ENOATTR:         Errno : 87
-EDOOFUS:         Errno : 88
-EBADMSG:         Errno : 89
-EMULTIHOP:       Errno : 90
-ENOLINK:         Errno : 91
-EPROTO:          Errno : 92
-ENOTCAPABLE:     Errno : 93
-ECAPMODE:        Errno : 94
-ENOTRECOVERABLE: Errno : 95
-EOWNERDEAD:      Errno : 96
+_Platform_Error :: enum i32 {
+	NONE            = 0,
+	EPERM           = 1,
+	ENOENT          = 2,
+	ESRCH           = 3,
+	EINTR           = 4,
+	EIO             = 5,
+	ENXIO           = 6,
+	E2BIG           = 7,
+	ENOEXEC         = 8,
+	EBADF           = 9,
+	ECHILD          = 10,
+	EBEADLK         = 11,
+	ENOMEM          = 12,
+	EACCESS         = 13,
+	EFAULT          = 14,
+	ENOTBLK         = 15,
+	EBUSY           = 16,
+	EEXIST          = 17,
+	EXDEV           = 18,
+	ENODEV          = 19,
+	ENOTDIR         = 20,
+	EISDIR          = 21,
+	EINVAL          = 22,
+	ENFILE          = 23,
+	EMFILE          = 24,
+	ENOTTY          = 25,
+	ETXTBSY         = 26,
+	EFBIG           = 27,
+	ENOSPC          = 28,
+	ESPIPE          = 29,
+	EROFS           = 30,
+	EMLINK          = 31,
+	EPIPE           = 32,
+	EDOM            = 33,
+	ERANGE          = 34, /* Result too large */
+	EAGAIN          = 35,
+	EINPROGRESS     = 36,
+	EALREADY        = 37,
+	ENOTSOCK        = 38,
+	EDESTADDRREQ    = 39,
+	EMSGSIZE        = 40,
+	EPROTOTYPE      = 41,
+	ENOPROTOOPT     = 42,
+	EPROTONOSUPPORT = 43,
+	ESOCKTNOSUPPORT = 44,
+	EOPNOTSUPP      = 45,
+	EPFNOSUPPORT    = 46,
+	EAFNOSUPPORT    = 47,
+	EADDRINUSE      = 48,
+	EADDRNOTAVAIL   = 49,
+	ENETDOWN        = 50,
+	ENETUNREACH     = 51,
+	ENETRESET       = 52,
+	ECONNABORTED    = 53,
+	ECONNRESET      = 54,
+	ENOBUFS         = 55,
+	EISCONN         = 56,
+	ENOTCONN        = 57,
+	ESHUTDOWN       = 58,
+	ETIMEDOUT       = 60,
+	ECONNREFUSED    = 61,
+	ELOOP           = 62,
+	ENAMETOOLING    = 63,
+	EHOSTDOWN       = 64,
+	EHOSTUNREACH    = 65,
+	ENOTEMPTY       = 66,
+	EPROCLIM        = 67,
+	EUSERS          = 68,
+	EDQUOT          = 69,
+	ESTALE          = 70,
+	EBADRPC         = 72,
+	ERPCMISMATCH    = 73,
+	EPROGUNAVAIL    = 74,
+	EPROGMISMATCH   = 75,
+	EPROCUNAVAIL    = 76,
+	ENOLCK          = 77,
+	ENOSYS          = 78,
+	EFTYPE          = 79,
+	EAUTH           = 80,
+	ENEEDAUTH       = 81,
+	EIDRM           = 82,
+	ENOMSG          = 83,
+	EOVERFLOW       = 84,
+	ECANCELED       = 85,
+	EILSEQ          = 86,
+	ENOATTR         = 87,
+	EDOOFUS         = 88,
+	EBADMSG         = 89,
+	EMULTIHOP       = 90,
+	ENOLINK         = 91,
+	EPROTO          = 92,
+	ENOTCAPABLE     = 93,
+	ECAPMODE        = 94,
+	ENOTRECOVERABLE = 95,
+	EOWNERDEAD      = 96,
+}
+EPERM           :: Platform_Error.EPERM
+ENOENT          :: Platform_Error.ENOENT
+ESRCH           :: Platform_Error.ESRCH
+EINTR           :: Platform_Error.EINTR
+EIO             :: Platform_Error.EIO
+ENXIO           :: Platform_Error.ENXIO
+E2BIG           :: Platform_Error.E2BIG
+ENOEXEC         :: Platform_Error.ENOEXEC
+EBADF           :: Platform_Error.EBADF
+ECHILD          :: Platform_Error.ECHILD
+EBEADLK         :: Platform_Error.EBEADLK
+ENOMEM          :: Platform_Error.ENOMEM
+EACCESS         :: Platform_Error.EACCESS
+EFAULT          :: Platform_Error.EFAULT
+ENOTBLK         :: Platform_Error.ENOTBLK
+EBUSY           :: Platform_Error.EBUSY
+EEXIST          :: Platform_Error.EEXIST
+EXDEV           :: Platform_Error.EXDEV
+ENODEV          :: Platform_Error.ENODEV
+ENOTDIR         :: Platform_Error.ENOTDIR
+EISDIR          :: Platform_Error.EISDIR
+EINVAL          :: Platform_Error.EINVAL
+ENFILE          :: Platform_Error.ENFILE
+EMFILE          :: Platform_Error.EMFILE
+ENOTTY          :: Platform_Error.ENOTTY
+ETXTBSY         :: Platform_Error.ETXTBSY
+EFBIG           :: Platform_Error.EFBIG
+ENOSPC          :: Platform_Error.ENOSPC
+ESPIPE          :: Platform_Error.ESPIPE
+EROFS           :: Platform_Error.EROFS
+EMLINK          :: Platform_Error.EMLINK
+EPIPE           :: Platform_Error.EPIPE
+EDOM            :: Platform_Error.EDOM
+ERANGE          :: Platform_Error.ERANGE
+EAGAIN          :: Platform_Error.EAGAIN
+EINPROGRESS     :: Platform_Error.EINPROGRESS
+EALREADY        :: Platform_Error.EALREADY
+ENOTSOCK        :: Platform_Error.ENOTSOCK
+EDESTADDRREQ    :: Platform_Error.EDESTADDRREQ
+EMSGSIZE        :: Platform_Error.EMSGSIZE
+EPROTOTYPE      :: Platform_Error.EPROTOTYPE
+ENOPROTOOPT     :: Platform_Error.ENOPROTOOPT
+EPROTONOSUPPORT :: Platform_Error.EPROTONOSUPPORT
+ESOCKTNOSUPPORT :: Platform_Error.ESOCKTNOSUPPORT
+EOPNOTSUPP      :: Platform_Error.EOPNOTSUPP
+EPFNOSUPPORT    :: Platform_Error.EPFNOSUPPORT
+EAFNOSUPPORT    :: Platform_Error.EAFNOSUPPORT
+EADDRINUSE      :: Platform_Error.EADDRINUSE
+EADDRNOTAVAIL   :: Platform_Error.EADDRNOTAVAIL
+ENETDOWN        :: Platform_Error.ENETDOWN
+ENETUNREACH     :: Platform_Error.ENETUNREACH
+ENETRESET       :: Platform_Error.ENETRESET
+ECONNABORTED    :: Platform_Error.ECONNABORTED
+ECONNRESET      :: Platform_Error.ECONNRESET
+ENOBUFS         :: Platform_Error.ENOBUFS
+EISCONN         :: Platform_Error.EISCONN
+ENOTCONN        :: Platform_Error.ENOTCONN
+ESHUTDOWN       :: Platform_Error.ESHUTDOWN
+ETIMEDOUT       :: Platform_Error.ETIMEDOUT
+ECONNREFUSED    :: Platform_Error.ECONNREFUSED
+ELOOP           :: Platform_Error.ELOOP
+ENAMETOOLING    :: Platform_Error.ENAMETOOLING
+EHOSTDOWN       :: Platform_Error.EHOSTDOWN
+EHOSTUNREACH    :: Platform_Error.EHOSTUNREACH
+ENOTEMPTY       :: Platform_Error.ENOTEMPTY
+EPROCLIM        :: Platform_Error.EPROCLIM
+EUSERS          :: Platform_Error.EUSERS
+EDQUOT          :: Platform_Error.EDQUOT
+ESTALE          :: Platform_Error.ESTALE
+EBADRPC         :: Platform_Error.EBADRPC
+ERPCMISMATCH    :: Platform_Error.ERPCMISMATCH
+EPROGUNAVAIL    :: Platform_Error.EPROGUNAVAIL
+EPROGMISMATCH   :: Platform_Error.EPROGMISMATCH
+EPROCUNAVAIL    :: Platform_Error.EPROCUNAVAIL
+ENOLCK          :: Platform_Error.ENOLCK
+ENOSYS          :: Platform_Error.ENOSYS
+EFTYPE          :: Platform_Error.EFTYPE
+EAUTH           :: Platform_Error.EAUTH
+ENEEDAUTH       :: Platform_Error.ENEEDAUTH
+EIDRM           :: Platform_Error.EIDRM
+ENOMSG          :: Platform_Error.ENOMSG
+EOVERFLOW       :: Platform_Error.EOVERFLOW
+ECANCELED       :: Platform_Error.ECANCELED
+EILSEQ          :: Platform_Error.EILSEQ
+ENOATTR         :: Platform_Error.ENOATTR
+EDOOFUS         :: Platform_Error.EDOOFUS
+EBADMSG         :: Platform_Error.EBADMSG
+EMULTIHOP       :: Platform_Error.EMULTIHOP
+ENOLINK         :: Platform_Error.ENOLINK
+EPROTO          :: Platform_Error.EPROTO
+ENOTCAPABLE     :: Platform_Error.ENOTCAPABLE
+ECAPMODE        :: Platform_Error.ECAPMODE
+ENOTRECOVERABLE :: Platform_Error.ENOTRECOVERABLE
+EOWNERDEAD      :: Platform_Error.EOWNERDEAD
 
 O_RDONLY   :: 0x00000
 O_WRONLY   :: 0x00001
@@ -324,8 +419,8 @@ is_path_separator :: proc(r: rune) -> bool {
 	return r == '/'
 }
 
-get_last_error :: proc "contextless" () -> int {
-	return int(__errno_location()^)
+get_last_error :: proc "contextless" () -> Error {
+	return Error(__errno_location()^)
 }
 
 open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) {

+ 6 - 8
core/os/os_haiku.odin

@@ -10,16 +10,14 @@ import "core:sys/haiku"
 Handle    :: i32
 Pid       :: i32
 File_Time :: i64
-Errno     :: i32
+_Platform_Error :: haiku.Errno
 
 MAX_PATH :: haiku.PATH_MAX
 
-ENOSYS :: int(haiku.Errno.POSIX_ERROR_BASE) + 9
+ENOSYS :: _Platform_Error(i32(haiku.Errno.POSIX_ERROR_BASE) + 9)
 
 INVALID_HANDLE :: ~Handle(0)
 
-ERROR_NONE: Errno: 0
-
 stdin:  Handle = 0
 stdout: Handle = 1
 stderr: Handle = 2
@@ -183,8 +181,8 @@ is_path_separator :: proc(r: rune) -> bool {
 	return r == '/'
 }
 
-get_last_error :: proc "contextless" () -> int {
-	return int(__error()^)
+get_last_error :: proc "contextless" () -> Error {
+	return Error(__error()^)
 }
 
 fork :: proc() -> (Pid, Errno) {
@@ -391,8 +389,8 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {
 	}
 	defer _unix_free(path_ptr)
 
-	path_cstr := transmute(cstring)path_ptr
-	path = strings.clone( string(path_cstr) )
+	path_cstr := cstring(path_ptr)
+	path = strings.clone(string(path_cstr))
 
 	return path, ERROR_NONE
 }

+ 62 - 30
core/os/os_js.odin

@@ -161,7 +161,40 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
 
 Handle    :: distinct uintptr
 File_Time :: distinct u64
-Errno     :: distinct int
+
+_Platform_Error :: enum i32 {
+	NONE = 0,
+	FILE_NOT_FOUND      = 2,
+	PATH_NOT_FOUND      = 3,
+	ACCESS_DENIED       = 5,
+	INVALID_HANDLE      = 6,
+	NOT_ENOUGH_MEMORY   = 8,
+	NO_MORE_FILES       = 18,
+	HANDLE_EOF          = 38,
+	NETNAME_DELETED     = 64,
+	FILE_EXISTS         = 80,
+	INVALID_PARAMETER   = 87,
+	BROKEN_PIPE         = 109,
+	BUFFER_OVERFLOW     = 111,
+	INSUFFICIENT_BUFFER = 122,
+	MOD_NOT_FOUND       = 126,
+	PROC_NOT_FOUND      = 127,
+	DIR_NOT_EMPTY       = 145,
+	ALREADY_EXISTS      = 183,
+	ENVVAR_NOT_FOUND    = 203,
+	MORE_DATA           = 234,
+	OPERATION_ABORTED   = 995,
+	IO_PENDING          = 997,
+	NOT_FOUND           = 1168,
+	PRIVILEGE_NOT_HELD  = 1314,
+	WSAEACCES             = 10013,
+	WSAECONNRESET         = 10054,
+
+	// Windows reserves errors >= 1<<29 for application use
+	FILE_IS_PIPE    = 1<<29 + 0,
+	FILE_IS_NOT_DIR = 1<<29 + 1,
+	NEGATIVE_OFFSET = 1<<29 + 2,
+}
 
 
 INVALID_HANDLE :: ~Handle(0)
@@ -182,37 +215,36 @@ O_ASYNC    :: 0x02000
 O_CLOEXEC  :: 0x80000
 
 
-ERROR_NONE:                   Errno : 0
-ERROR_FILE_NOT_FOUND:         Errno : 2
-ERROR_PATH_NOT_FOUND:         Errno : 3
-ERROR_ACCESS_DENIED:          Errno : 5
-ERROR_INVALID_HANDLE:         Errno : 6
-ERROR_NOT_ENOUGH_MEMORY:      Errno : 8
-ERROR_NO_MORE_FILES:          Errno : 18
-ERROR_HANDLE_EOF:             Errno : 38
-ERROR_NETNAME_DELETED:        Errno : 64
-ERROR_FILE_EXISTS:            Errno : 80
-ERROR_INVALID_PARAMETER:      Errno : 87
-ERROR_BROKEN_PIPE:            Errno : 109
-ERROR_BUFFER_OVERFLOW:        Errno : 111
-ERROR_INSUFFICIENT_BUFFER:    Errno : 122
-ERROR_MOD_NOT_FOUND:          Errno : 126
-ERROR_PROC_NOT_FOUND:         Errno : 127
-ERROR_DIR_NOT_EMPTY:          Errno : 145
-ERROR_ALREADY_EXISTS:         Errno : 183
-ERROR_ENVVAR_NOT_FOUND:       Errno : 203
-ERROR_MORE_DATA:              Errno : 234
-ERROR_OPERATION_ABORTED:      Errno : 995
-ERROR_IO_PENDING:             Errno : 997
-ERROR_NOT_FOUND:              Errno : 1168
-ERROR_PRIVILEGE_NOT_HELD:     Errno : 1314
-WSAEACCES:                    Errno : 10013
-WSAECONNRESET:                Errno : 10054
+ERROR_FILE_NOT_FOUND      :: Platform_Error.FILE_NOT_FOUND
+ERROR_PATH_NOT_FOUND      :: Platform_Error.PATH_NOT_FOUND
+ERROR_ACCESS_DENIED       :: Platform_Error.ACCESS_DENIED
+ERROR_INVALID_HANDLE      :: Platform_Error.INVALID_HANDLE
+ERROR_NOT_ENOUGH_MEMORY   :: Platform_Error.NOT_ENOUGH_MEMORY
+ERROR_NO_MORE_FILES       :: Platform_Error.NO_MORE_FILES
+ERROR_HANDLE_EOF          :: Platform_Error.HANDLE_EOF
+ERROR_NETNAME_DELETED     :: Platform_Error.NETNAME_DELETED
+ERROR_FILE_EXISTS         :: Platform_Error.FILE_EXISTS
+ERROR_INVALID_PARAMETER   :: Platform_Error.INVALID_PARAMETER
+ERROR_BROKEN_PIPE         :: Platform_Error.BROKEN_PIPE
+ERROR_BUFFER_OVERFLOW     :: Platform_Error.BUFFER_OVERFLOW
+ERROR_INSUFFICIENT_BUFFER :: Platform_Error.INSUFFICIENT_BUFFER
+ERROR_MOD_NOT_FOUND       :: Platform_Error.MOD_NOT_FOUND
+ERROR_PROC_NOT_FOUND      :: Platform_Error.PROC_NOT_FOUND
+ERROR_DIR_NOT_EMPTY       :: Platform_Error.DIR_NOT_EMPTY
+ERROR_ALREADY_EXISTS      :: Platform_Error.ALREADY_EXISTS
+ERROR_ENVVAR_NOT_FOUND    :: Platform_Error.ENVVAR_NOT_FOUND
+ERROR_MORE_DATA           :: Platform_Error.MORE_DATA
+ERROR_OPERATION_ABORTED   :: Platform_Error.OPERATION_ABORTED
+ERROR_IO_PENDING          :: Platform_Error.IO_PENDING
+ERROR_NOT_FOUND           :: Platform_Error.NOT_FOUND
+ERROR_PRIVILEGE_NOT_HELD  :: Platform_Error.PRIVILEGE_NOT_HELD
+WSAEACCES                 :: Platform_Error.WSAEACCES
+WSAECONNRESET             :: Platform_Error.WSAECONNRESET
 
 // Windows reserves errors >= 1<<29 for application use
-ERROR_FILE_IS_PIPE:           Errno : 1<<29 + 0
-ERROR_FILE_IS_NOT_DIR:        Errno : 1<<29 + 1
-ERROR_NEGATIVE_OFFSET:        Errno : 1<<29 + 2
+ERROR_FILE_IS_PIPE        :: Platform_Error.FILE_IS_PIPE
+ERROR_FILE_IS_NOT_DIR     :: Platform_Error.FILE_IS_NOT_DIR
+ERROR_NEGATIVE_OFFSET     :: Platform_Error.NEGATIVE_OFFSET
 
 // "Argv" arguments converted to Odin strings
 args := _alloc_command_line_arguments()

+ 132 - 132
core/os/os_linux.odin

@@ -20,148 +20,148 @@ import "base:intrinsics"
 // all that about compatibility. But we don't want to push experimental changes
 // and have people's code break while it's still work in progress.
 import unix "core:sys/unix"
+import linux "core:sys/linux"
 
 Handle    :: distinct i32
 Pid       :: distinct i32
 File_Time :: distinct u64
-Errno     :: distinct i32
 Socket    :: distinct int
 
 INVALID_HANDLE :: ~Handle(0)
 
-ERROR_NONE:     Errno : 0
-EPERM:          Errno : 1
-ENOENT:         Errno : 2
-ESRCH:          Errno : 3
-EINTR:          Errno : 4
-EIO:            Errno : 5
-ENXIO:          Errno : 6
-EBADF:          Errno : 9
-EAGAIN:         Errno : 11
-ENOMEM:         Errno : 12
-EACCES:         Errno : 13
-EFAULT:         Errno : 14
-EEXIST:         Errno : 17
-ENODEV:         Errno : 19
-ENOTDIR:        Errno : 20
-EISDIR:         Errno : 21
-EINVAL:         Errno : 22
-ENFILE:         Errno : 23
-EMFILE:         Errno : 24
-ETXTBSY:        Errno : 26
-EFBIG:          Errno : 27
-ENOSPC:         Errno : 28
-ESPIPE:         Errno : 29
-EROFS:          Errno : 30
-EPIPE:          Errno : 32
-
-ERANGE:         Errno : 34 /* Result too large */
-EDEADLK:        Errno : 35 /* Resource deadlock would occur */
-ENAMETOOLONG:   Errno : 36 /* File name too long */
-ENOLCK:         Errno : 37 /* No record locks available */
-
-ENOSYS:         Errno : 38	/* Invalid system call number */
-
-ENOTEMPTY:      Errno : 39	/* Directory not empty */
-ELOOP:          Errno : 40	/* Too many symbolic links encountered */
-EWOULDBLOCK:    Errno : EAGAIN /* Operation would block */
-ENOMSG:         Errno : 42	/* No message of desired type */
-EIDRM:          Errno : 43	/* Identifier removed */
-ECHRNG:         Errno : 44	/* Channel number out of range */
-EL2NSYNC:       Errno : 45	/* Level 2 not synchronized */
-EL3HLT:         Errno : 46	/* Level 3 halted */
-EL3RST:         Errno : 47	/* Level 3 reset */
-ELNRNG:         Errno : 48	/* Link number out of range */
-EUNATCH:        Errno : 49	/* Protocol driver not attached */
-ENOCSI:         Errno : 50	/* No CSI structure available */
-EL2HLT:         Errno : 51	/* Level 2 halted */
-EBADE:          Errno : 52	/* Invalid exchange */
-EBADR:          Errno : 53	/* Invalid request descriptor */
-EXFULL:         Errno : 54	/* Exchange full */
-ENOANO:         Errno : 55	/* No anode */
-EBADRQC:        Errno : 56	/* Invalid request code */
-EBADSLT:        Errno : 57	/* Invalid slot */
-EDEADLOCK:      Errno : EDEADLK
-EBFONT:         Errno : 59	/* Bad font file format */
-ENOSTR:         Errno : 60	/* Device not a stream */
-ENODATA:        Errno : 61	/* No data available */
-ETIME:          Errno : 62	/* Timer expired */
-ENOSR:          Errno : 63	/* Out of streams resources */
-ENONET:         Errno : 64	/* Machine is not on the network */
-ENOPKG:         Errno : 65	/* Package not installed */
-EREMOTE:        Errno : 66	/* Object is remote */
-ENOLINK:        Errno : 67	/* Link has been severed */
-EADV:           Errno : 68	/* Advertise error */
-ESRMNT:         Errno : 69	/* Srmount error */
-ECOMM:          Errno : 70	/* Communication error on send */
-EPROTO:         Errno : 71	/* Protocol error */
-EMULTIHOP:      Errno : 72	/* Multihop attempted */
-EDOTDOT:        Errno : 73	/* RFS specific error */
-EBADMSG:        Errno : 74	/* Not a data message */
-EOVERFLOW:      Errno : 75	/* Value too large for defined data type */
-ENOTUNIQ:       Errno : 76	/* Name not unique on network */
-EBADFD:         Errno : 77	/* File descriptor in bad state */
-EREMCHG:        Errno : 78	/* Remote address changed */
-ELIBACC:        Errno : 79	/* Can not access a needed shared library */
-ELIBBAD:        Errno : 80	/* Accessing a corrupted shared library */
-ELIBSCN:        Errno : 81	/* .lib section in a.out corrupted */
-ELIBMAX:        Errno : 82	/* Attempting to link in too many shared libraries */
-ELIBEXEC:       Errno : 83	/* Cannot exec a shared library directly */
-EILSEQ:         Errno : 84	/* Illegal byte sequence */
-ERESTART:       Errno : 85	/* Interrupted system call should be restarted */
-ESTRPIPE:       Errno : 86	/* Streams pipe error */
-EUSERS:         Errno : 87	/* Too many users */
-ENOTSOCK:       Errno : 88	/* Socket operation on non-socket */
-EDESTADDRREQ:   Errno : 89	/* Destination address required */
-EMSGSIZE:       Errno : 90	/* Message too long */
-EPROTOTYPE:     Errno : 91	/* Protocol wrong type for socket */
-ENOPROTOOPT:    Errno : 92	/* Protocol not available */
-EPROTONOSUPPORT:Errno : 93	/* Protocol not supported */
-ESOCKTNOSUPPORT:Errno : 94	/* Socket type not supported */
-EOPNOTSUPP: 	Errno : 95	/* Operation not supported on transport endpoint */
-EPFNOSUPPORT: 	Errno : 96	/* Protocol family not supported */
-EAFNOSUPPORT: 	Errno : 97	/* Address family not supported by protocol */
-EADDRINUSE: 	Errno : 98	/* Address already in use */
-EADDRNOTAVAIL: 	Errno : 99	/* Cannot assign requested address */
-ENETDOWN: 		Errno : 100	/* Network is down */
-ENETUNREACH: 	Errno : 101	/* Network is unreachable */
-ENETRESET: 		Errno : 102	/* Network dropped connection because of reset */
-ECONNABORTED: 	Errno : 103	/* Software caused connection abort */
-ECONNRESET: 	Errno : 104	/* Connection reset by peer */
-ENOBUFS: 		Errno : 105	/* No buffer space available */
-EISCONN: 		Errno : 106	/* Transport endpoint is already connected */
-ENOTCONN: 		Errno : 107	/* Transport endpoint is not connected */
-ESHUTDOWN: 		Errno : 108	/* Cannot send after transport endpoint shutdown */
-ETOOMANYREFS: 	Errno : 109	/* Too many references: cannot splice */
-ETIMEDOUT: 		Errno : 110	/* Connection timed out */
-ECONNREFUSED: 	Errno : 111	/* Connection refused */
-EHOSTDOWN: 		Errno : 112	/* Host is down */
-EHOSTUNREACH: 	Errno : 113	/* No route to host */
-EALREADY: 		Errno : 114	/* Operation already in progress */
-EINPROGRESS: 	Errno : 115	/* Operation now in progress */
-ESTALE: 		Errno : 116	/* Stale file handle */
-EUCLEAN: 		Errno : 117	/* Structure needs cleaning */
-ENOTNAM: 		Errno : 118	/* Not a XENIX named type file */
-ENAVAIL: 		Errno : 119	/* No XENIX semaphores available */
-EISNAM: 		Errno : 120	/* Is a named type file */
-EREMOTEIO: 		Errno : 121	/* Remote I/O error */
-EDQUOT: 		Errno : 122	/* Quota exceeded */
-
-ENOMEDIUM: 		Errno : 123	/* No medium found */
-EMEDIUMTYPE: 	Errno : 124	/* Wrong medium type */
-ECANCELED: 		Errno : 125	/* Operation Canceled */
-ENOKEY: 		Errno : 126	/* Required key not available */
-EKEYEXPIRED: 	Errno : 127	/* Key has expired */
-EKEYREVOKED: 	Errno : 128	/* Key has been revoked */
-EKEYREJECTED: 	Errno : 129	/* Key was rejected by service */
+_Platform_Error :: linux.Errno
+EPERM           :: Platform_Error.EPERM
+ENOENT          :: Platform_Error.ENOENT
+ESRCH           :: Platform_Error.ESRCH
+EINTR           :: Platform_Error.EINTR
+EIO             :: Platform_Error.EIO
+ENXIO           :: Platform_Error.ENXIO
+EBADF           :: Platform_Error.EBADF
+EAGAIN          :: Platform_Error.EAGAIN
+ENOMEM          :: Platform_Error.ENOMEM
+EACCES          :: Platform_Error.EACCES
+EFAULT          :: Platform_Error.EFAULT
+EEXIST          :: Platform_Error.EEXIST
+ENODEV          :: Platform_Error.ENODEV
+ENOTDIR         :: Platform_Error.ENOTDIR
+EISDIR          :: Platform_Error.EISDIR
+EINVAL          :: Platform_Error.EINVAL
+ENFILE          :: Platform_Error.ENFILE
+EMFILE          :: Platform_Error.EMFILE
+ETXTBSY         :: Platform_Error.ETXTBSY
+EFBIG           :: Platform_Error.EFBIG
+ENOSPC          :: Platform_Error.ENOSPC
+ESPIPE          :: Platform_Error.ESPIPE
+EROFS           :: Platform_Error.EROFS
+EPIPE           :: Platform_Error.EPIPE
+
+ERANGE          :: Platform_Error.ERANGE          /* Result too large */
+EDEADLK         :: Platform_Error.EDEADLK         /* Resource deadlock would occur */
+ENAMETOOLONG    :: Platform_Error.ENAMETOOLONG    /* File name too long */
+ENOLCK          :: Platform_Error.ENOLCK          /* No record locks available */
+
+ENOSYS          :: Platform_Error.ENOSYS          /* Invalid system call number */
+
+ENOTEMPTY       :: Platform_Error.ENOTEMPTY       /* Directory not empty */
+ELOOP           :: Platform_Error.ELOOP           /* Too many symbolic links encountered */
+EWOULDBLOCK     :: Platform_Error.EWOULDBLOCK     /* Operation would block */
+ENOMSG          :: Platform_Error.ENOMSG          /* No message of desired type */
+EIDRM           :: Platform_Error.EIDRM           /* Identifier removed */
+ECHRNG          :: Platform_Error.ECHRNG          /* Channel number out of range */
+EL2NSYNC        :: Platform_Error.EL2NSYNC        /* Level 2 not synchronized */
+EL3HLT          :: Platform_Error.EL3HLT          /* Level 3 halted */
+EL3RST          :: Platform_Error.EL3RST          /* Level 3 reset */
+ELNRNG          :: Platform_Error.ELNRNG          /* Link number out of range */
+EUNATCH         :: Platform_Error.EUNATCH         /* Protocol driver not attached */
+ENOCSI          :: Platform_Error.ENOCSI          /* No CSI structure available */
+EL2HLT          :: Platform_Error.EL2HLT          /* Level 2 halted */
+EBADE           :: Platform_Error.EBADE           /* Invalid exchange */
+EBADR           :: Platform_Error.EBADR           /* Invalid request descriptor */
+EXFULL          :: Platform_Error.EXFULL          /* Exchange full */
+ENOANO          :: Platform_Error.ENOANO          /* No anode */
+EBADRQC         :: Platform_Error.EBADRQC         /* Invalid request code */
+EBADSLT         :: Platform_Error.EBADSLT         /* Invalid slot */
+EDEADLOCK       :: Platform_Error.EDEADLOCK
+EBFONT          :: Platform_Error.EBFONT          /* Bad font file format */
+ENOSTR          :: Platform_Error.ENOSTR          /* Device not a stream */
+ENODATA         :: Platform_Error.ENODATA         /* No data available */
+ETIME           :: Platform_Error.ETIME           /* Timer expired */
+ENOSR           :: Platform_Error.ENOSR           /* Out of streams resources */
+ENONET          :: Platform_Error.ENONET          /* Machine is not on the network */
+ENOPKG          :: Platform_Error.ENOPKG          /* Package not installed */
+EREMOTE         :: Platform_Error.EREMOTE         /* Object is remote */
+ENOLINK         :: Platform_Error.ENOLINK         /* Link has been severed */
+EADV            :: Platform_Error.EADV            /* Advertise error */
+ESRMNT          :: Platform_Error.ESRMNT          /* Srmount error */
+ECOMM           :: Platform_Error.ECOMM           /* Communication error on send */
+EPROTO          :: Platform_Error.EPROTO          /* Protocol error */
+EMULTIHOP       :: Platform_Error.EMULTIHOP       /* Multihop attempted */
+EDOTDOT         :: Platform_Error.EDOTDOT         /* RFS specific error */
+EBADMSG         :: Platform_Error.EBADMSG         /* Not a data message */
+EOVERFLOW       :: Platform_Error.EOVERFLOW       /* Value too large for defined data type */
+ENOTUNIQ        :: Platform_Error.ENOTUNIQ        /* Name not unique on network */
+EBADFD          :: Platform_Error.EBADFD          /* File descriptor in bad state */
+EREMCHG         :: Platform_Error.EREMCHG         /* Remote address changed */
+ELIBACC         :: Platform_Error.ELIBACC         /* Can not access a needed shared library */
+ELIBBAD         :: Platform_Error.ELIBBAD         /* Accessing a corrupted shared library */
+ELIBSCN         :: Platform_Error.ELIBSCN         /* .lib section in a.out corrupted */
+ELIBMAX         :: Platform_Error.ELIBMAX         /* Attempting to link in too many shared libraries */
+ELIBEXEC        :: Platform_Error.ELIBEXEC        /* Cannot exec a shared library directly */
+EILSEQ          :: Platform_Error.EILSEQ          /* Illegal byte sequence */
+ERESTART        :: Platform_Error.ERESTART        /* Interrupted system call should be restarted */
+ESTRPIPE        :: Platform_Error.ESTRPIPE        /* Streams pipe error */
+EUSERS          :: Platform_Error.EUSERS          /* Too many users */
+ENOTSOCK        :: Platform_Error.ENOTSOCK        /* Socket operation on non-socket */
+EDESTADDRREQ    :: Platform_Error.EDESTADDRREQ    /* Destination address required */
+EMSGSIZE        :: Platform_Error.EMSGSIZE        /* Message too long */
+EPROTOTYPE      :: Platform_Error.EPROTOTYPE      /* Protocol wrong type for socket */
+ENOPROTOOPT     :: Platform_Error.ENOPROTOOPT     /* Protocol not available */
+EPROTONOSUPPOR  :: Platform_Error.EPROTONOSUPPORT /* Protocol not supported */
+ESOCKTNOSUPPOR  :: Platform_Error.ESOCKTNOSUPPORT /* Socket type not supported */
+EOPNOTSUPP      :: Platform_Error.EOPNOTSUPP      /* Operation not supported on transport endpoint */
+EPFNOSUPPORT    :: Platform_Error.EPFNOSUPPORT    /* Protocol family not supported */
+EAFNOSUPPORT    :: Platform_Error.EAFNOSUPPORT    /* Address family not supported by protocol */
+EADDRINUSE      :: Platform_Error.EADDRINUSE      /* Address already in use */
+EADDRNOTAVAIL   :: Platform_Error.EADDRNOTAVAIL   /* Cannot assign requested address */
+ENETDOWN        :: Platform_Error.ENETDOWN        /* Network is down */
+ENETUNREACH     :: Platform_Error.ENETUNREACH     /* Network is unreachable */
+ENETRESET       :: Platform_Error.ENETRESET       /* Network dropped connection because of reset */
+ECONNABORTED    :: Platform_Error.ECONNABORTED    /* Software caused connection abort */
+ECONNRESET      :: Platform_Error.ECONNRESET      /* Connection reset by peer */
+ENOBUFS         :: Platform_Error.ENOBUFS         /* No buffer space available */
+EISCONN         :: Platform_Error.EISCONN         /* Transport endpoint is already connected */
+ENOTCONN        :: Platform_Error.ENOTCONN        /* Transport endpoint is not connected */
+ESHUTDOWN       :: Platform_Error.ESHUTDOWN       /* Cannot send after transport endpoint shutdown */
+ETOOMANYREFS    :: Platform_Error.ETOOMANYREFS    /* Too many references: cannot splice */
+ETIMEDOUT       :: Platform_Error.ETIMEDOUT       /* Connection timed out */
+ECONNREFUSED    :: Platform_Error.ECONNREFUSED    /* Connection refused */
+EHOSTDOWN       :: Platform_Error.EHOSTDOWN       /* Host is down */
+EHOSTUNREACH    :: Platform_Error.EHOSTUNREACH    /* No route to host */
+EALREADY        :: Platform_Error.EALREADY        /* Operation already in progress */
+EINPROGRESS     :: Platform_Error.EINPROGRESS     /* Operation now in progress */
+ESTALE          :: Platform_Error.ESTALE          /* Stale file handle */
+EUCLEAN         :: Platform_Error.EUCLEAN         /* Structure needs cleaning */
+ENOTNAM         :: Platform_Error.ENOTNAM         /* Not a XENIX named type file */
+ENAVAIL         :: Platform_Error.ENAVAIL         /* No XENIX semaphores available */
+EISNAM          :: Platform_Error.EISNAM          /* Is a named type file */
+EREMOTEIO       :: Platform_Error.EREMOTEIO       /* Remote I/O error */
+EDQUOT          :: Platform_Error.EDQUOT          /* Quota exceeded */
+
+ENOMEDIUM       :: Platform_Error.ENOMEDIUM       /* No medium found */
+EMEDIUMTYPE     :: Platform_Error.EMEDIUMTYPE     /* Wrong medium type */
+ECANCELED       :: Platform_Error.ECANCELED       /* Operation Canceled */
+ENOKEY          :: Platform_Error.ENOKEY          /* Required key not available */
+EKEYEXPIRED     :: Platform_Error.EKEYEXPIRED     /* Key has expired */
+EKEYREVOKED     :: Platform_Error.EKEYREVOKED     /* Key has been revoked */
+EKEYREJECTED    :: Platform_Error.EKEYREJECTED    /* Key was rejected by service */
 
 /* for robust mutexes */
-EOWNERDEAD: 	Errno : 130	/* Owner died */
-ENOTRECOVERABLE: Errno : 131	/* State not recoverable */
+EOWNERDEAD      :: Platform_Error.EOWNERDEAD      /* Owner died */
+ENOTRECOVERABLE :: Platform_Error.ENOTRECOVERABLE /* State not recoverable */
 
-ERFKILL: 		Errno : 132	/* Operation not possible due to RF-kill */
+ERFKILL   :: Platform_Error.ERFKILL               /* Operation not possible due to RF-kill */
 
-EHWPOISON: 		Errno : 133	/* Memory page has hardware error */
+EHWPOISON :: Platform_Error.EHWPOISON             /* Memory page has hardware error */
 
 ADDR_NO_RANDOMIZE :: 0x40000
 
@@ -520,8 +520,8 @@ _get_errno :: proc(res: int) -> Errno {
 }
 
 // get errno from libc
-get_last_error :: proc "contextless" () -> int {
-	return int(__errno_location()^)
+get_last_error :: proc "contextless" () -> Error {
+	return Error(__errno_location()^)
 }
 
 personality :: proc(persona: u64) -> (Errno) {

+ 244 - 105
core/os/os_netbsd.odin

@@ -9,148 +9,287 @@ import "core:c"
 
 Handle :: distinct i32
 File_Time :: distinct u64
-Errno :: distinct i32
 
 INVALID_HANDLE :: ~Handle(0)
 
-ERROR_NONE:     Errno : 0 		/* No error */
-EPERM:          Errno : 1		/* Operation not permitted */
-ENOENT:         Errno : 2		/* No such file or directory */
-EINTR:          Errno : 4		/* Interrupted system call */
-ESRCH:          Errno : 3		/* No such process */
-EIO:            Errno : 5		/* Input/output error */
-ENXIO:          Errno : 6		/* Device not configured */
-E2BIG:          Errno : 7		/* Argument list too long */
-ENOEXEC:        Errno : 8		/* Exec format error */
-EBADF:          Errno : 9		/* Bad file descriptor */
-ECHILD:         Errno : 10		/* No child processes */
-EDEADLK:        Errno : 11		/* Resource deadlock avoided. 11 was EAGAIN */
-ENOMEM:         Errno : 12		/* Cannot allocate memory */
-EACCES:         Errno : 13		/* Permission denied */
-EFAULT:         Errno : 14		/* Bad address */
-ENOTBLK:        Errno : 15		/* Block device required */
-EBUSY:          Errno : 16		/* Device busy */
-EEXIST:         Errno : 17		/* File exists */
-EXDEV:          Errno : 18		/* Cross-device link */
-ENODEV:         Errno : 19		/* Operation not supported by device */
-ENOTDIR:        Errno : 20		/* Not a directory */
-EISDIR:         Errno : 21		/* Is a directory */
-EINVAL:         Errno : 22		/* Invalid argument */
-ENFILE:         Errno : 23		/* Too many open files in system */
-EMFILE:         Errno : 24		/* Too many open files */
-ENOTTY:         Errno : 25		/* Inappropriate ioctl for device */
-ETXTBSY:        Errno : 26		/* Text file busy */
-EFBIG:          Errno : 27		/* File too large */
-ENOSPC:         Errno : 28		/* No space left on device */
-ESPIPE:         Errno : 29		/* Illegal seek */
-EROFS:          Errno : 30		/* Read-only file system */
-EMLINK:         Errno : 31		/* Too many links */
-EPIPE:          Errno : 32		/* Broken pipe */
+_Platform_Error :: enum i32 {
+	NONE            = 0,
+	EPERM           = 1,          /* Operation not permitted */
+	ENOENT          = 2,          /* No such file or directory */
+	EINTR           = 4,          /* Interrupted system call */
+	ESRCH           = 3,          /* No such process */
+	EIO             = 5,          /* Input/output error */
+	ENXIO           = 6,          /* Device not configured */
+	E2BIG           = 7,          /* Argument list too long */
+	ENOEXEC         = 8,          /* Exec format error */
+	EBADF           = 9,          /* Bad file descriptor */
+	ECHILD          = 10,         /* No child processes */
+	EDEADLK         = 11,         /* Resource deadlock avoided. 11 was EAGAIN */
+	ENOMEM          = 12,         /* Cannot allocate memory */
+	EACCES          = 13,         /* Permission denied */
+	EFAULT          = 14,         /* Bad address */
+	ENOTBLK         = 15,         /* Block device required */
+	EBUSY           = 16,         /* Device busy */
+	EEXIST          = 17,         /* File exists */
+	EXDEV           = 18,         /* Cross-device link */
+	ENODEV          = 19,         /* Operation not supported by device */
+	ENOTDIR         = 20,         /* Not a directory */
+	EISDIR          = 21,         /* Is a directory */
+	EINVAL          = 22,         /* Invalid argument */
+	ENFILE          = 23,         /* Too many open files in system */
+	EMFILE          = 24,         /* Too many open files */
+	ENOTTY          = 25,         /* Inappropriate ioctl for device */
+	ETXTBSY         = 26,         /* Text file busy */
+	EFBIG           = 27,         /* File too large */
+	ENOSPC          = 28,         /* No space left on device */
+	ESPIPE          = 29,         /* Illegal seek */
+	EROFS           = 30,         /* Read-only file system */
+	EMLINK          = 31,         /* Too many links */
+	EPIPE           = 32,         /* Broken pipe */
+
+	/* math software */
+	EDOM            = 33,         /* Numerical argument out of domain */
+	ERANGE          = 34,         /* Result too large or too small */
+
+	/* non-blocking and interrupt i/o */
+	EAGAIN          = 35,         /* Resource temporarily unavailable */
+	EWOULDBLOCK     = EAGAIN,     /*  Operation would block */
+	EINPROGRESS     = 36,         /* Operation now in progress */
+	EALREADY        = 37,         /* Operation already in progress */
+
+	/* ipc/network software -- argument errors */
+	ENOTSOCK        = 38,         /* Socket operation on non-socket */
+	EDESTADDRREQ    = 39,         /* Destination address required */
+	EMSGSIZE        = 40,         /* Message too long */
+	EPROTOTYPE      = 41,         /* Protocol wrong type for socket */
+	ENOPROTOOPT     = 42,         /* Protocol option not available */
+	EPROTONOSUPPORT = 43,         /* Protocol not supported */
+	ESOCKTNOSUPPORT = 44,         /* Socket type not supported */
+	EOPNOTSUPP      = 45,         /* Operation not supported */
+	EPFNOSUPPORT    = 46,         /* Protocol family not supported */
+	EAFNOSUPPORT    = 47,         /* Address family not supported by protocol family */
+	EADDRINUSE      = 48,         /* Address already in use */
+	EADDRNOTAVAIL   = 49,         /* Can't assign requested address */
+
+	/* ipc/network software -- operational errors */
+	ENETDOWN        = 50,         /* Network is down */
+	ENETUNREACH     = 51,         /* Network is unreachable */
+	ENETRESET       = 52,         /* Network dropped connection on reset */
+	ECONNABORTED    = 53,         /* Software caused connection abort */
+	ECONNRESET      = 54,         /* Connection reset by peer */
+	ENOBUFS         = 55,         /* No buffer space available */
+	EISCONN         = 56,         /* Socket is already connected */
+	ENOTCONN        = 57,         /* Socket is not connected */
+	ESHUTDOWN       = 58,         /* Can't send after socket shutdown */
+	ETOOMANYREFS    = 59,         /* Too many references: can't splice */
+	ETIMEDOUT       = 60,         /* Operation timed out */
+	ECONNREFUSED    = 61,         /* Connection refused */
+
+	ELOOP           = 62,         /* Too many levels of symbolic links */
+	ENAMETOOLONG    = 63,         /* File name too long */
+
+	/* should be rearranged */
+	EHOSTDOWN       = 64,         /* Host is down */
+	EHOSTUNREACH    = 65,         /* No route to host */
+	ENOTEMPTY       = 66,         /* Directory not empty */
+
+	/* quotas & mush */
+	EPROCLIM        = 67,         /* Too many processes */
+	EUSERS          = 68,         /* Too many users */
+	EDQUOT          = 69,         /* Disc quota exceeded */
+
+	/* Network File System */
+	ESTALE          = 70,         /* Stale NFS file handle */
+	EREMOTE         = 71,         /* Too many levels of remote in path */
+	EBADRPC         = 72,         /* RPC struct is bad */
+	ERPCMISMATCH    = 73,         /* RPC version wrong */
+	EPROGUNAVAIL    = 74,         /* RPC prog. not avail */
+	EPROGMISMATCH   = 75,         /* Program version wrong */
+	EPROCUNAVAIL    = 76,         /* Bad procedure for program */
+
+	ENOLCK          = 77,         /* No locks available */
+	ENOSYS          = 78,         /* Function not implemented */
+
+	EFTYPE          = 79,         /* Inappropriate file type or format */
+	EAUTH           = 80,         /* Authentication error */
+	ENEEDAUTH       = 81,         /* Need authenticator */
+
+	/* SystemV IPC */
+	EIDRM           = 82,         /* Identifier removed */
+	ENOMSG          = 83,         /* No message of desired type */
+	EOVERFLOW       = 84,         /* Value too large to be stored in data type */
+
+	/* Wide/multibyte-character handling, ISO/IEC 9899/AMD1:1995 */
+	EILSEQ          = 85,         /* Illegal byte sequence */
+
+	/* From IEEE Std 1003.1-2001 */
+	/* Base, Realtime, Threads or Thread Priority Scheduling option errors */
+	ENOTSUP         = 86,         /* Not supported */
+
+	/* Realtime option errors */
+	ECANCELED       = 87,         /* Operation canceled */
+
+	/* Realtime, XSI STREAMS option errors */
+	EBADMSG         = 88,         /* Bad or Corrupt message */
+
+	/* XSI STREAMS option errors  */
+	ENODATA         = 89,         /* No message available */
+	ENOSR           = 90,         /* No STREAM resources */
+	ENOSTR          = 91,         /* Not a STREAM */
+	ETIME           = 92,         /* STREAM ioctl timeout */
+
+	/* File system extended attribute errors */
+	ENOATTR         = 93,         /* Attribute not found */
+
+	/* Realtime, XSI STREAMS option errors */
+	EMULTIHOP       = 94,         /* Multihop attempted */
+	ENOLINK         = 95,         /* Link has been severed */
+	EPROTO          = 96,         /* Protocol error */
+
+	/* Robust mutexes */
+	EOWNERDEAD      = 97,         /* Previous owner died */
+	ENOTRECOVERABLE = 98,         /* State not recoverable */
+
+	ELAST           = 98,         /* Must equal largest errno */
+}
+
+EPERM           :: Platform_Error.EPERM           /* Operation not permitted */
+ENOENT          :: Platform_Error.ENOENT          /* No such file or directory */
+EINTR           :: Platform_Error.EINTR           /* Interrupted system call */
+ESRCH           :: Platform_Error.ESRCH           /* No such process */
+EIO             :: Platform_Error.EIO             /* Input/output error */
+ENXIO           :: Platform_Error.ENXIO           /* Device not configured */
+E2BIG           :: Platform_Error.E2BIG           /* Argument list too long */
+ENOEXEC         :: Platform_Error.ENOEXEC         /* Exec format error */
+EBADF           :: Platform_Error.EBADF           /* Bad file descriptor */
+ECHILD          :: Platform_Error.ECHILD          /* No child processes */
+EDEADLK         :: Platform_Error.EDEADLK         /* Resource deadlock avoided. 11 was EAGAIN */
+ENOMEM          :: Platform_Error.ENOMEM          /* Cannot allocate memory */
+EACCES          :: Platform_Error.EACCES          /* Permission denied */
+EFAULT          :: Platform_Error.EFAULT          /* Bad address */
+ENOTBLK         :: Platform_Error.ENOTBLK         /* Block device required */
+EBUSY           :: Platform_Error.EBUSY           /* Device busy */
+EEXIST          :: Platform_Error.EEXIST          /* File exists */
+EXDEV           :: Platform_Error.EXDEV           /* Cross-device link */
+ENODEV          :: Platform_Error.ENODEV          /* Operation not supported by device */
+ENOTDIR         :: Platform_Error.ENOTDIR         /* Not a directory */
+EISDIR          :: Platform_Error.EISDIR          /* Is a directory */
+EINVAL          :: Platform_Error.EINVAL          /* Invalid argument */
+ENFILE          :: Platform_Error.ENFILE          /* Too many open files in system */
+EMFILE          :: Platform_Error.EMFILE          /* Too many open files */
+ENOTTY          :: Platform_Error.ENOTTY          /* Inappropriate ioctl for device */
+ETXTBSY         :: Platform_Error.ETXTBSY         /* Text file busy */
+EFBIG           :: Platform_Error.EFBIG           /* File too large */
+ENOSPC          :: Platform_Error.ENOSPC          /* No space left on device */
+ESPIPE          :: Platform_Error.ESPIPE          /* Illegal seek */
+EROFS           :: Platform_Error.EROFS           /* Read-only file system */
+EMLINK          :: Platform_Error.EMLINK          /* Too many links */
+EPIPE           :: Platform_Error.EPIPE           /* Broken pipe */
 
 /* math software */
-EDOM:           Errno : 33		/* Numerical argument out of domain */
-ERANGE:         Errno : 34		/* Result too large or too small */
+EDOM            :: Platform_Error.EDOM            /* Numerical argument out of domain */
+ERANGE          :: Platform_Error.ERANGE          /* Result too large or too small */
 
 /* non-blocking and interrupt i/o */
-EAGAIN:         Errno : 35		/* Resource temporarily unavailable */
-EWOULDBLOCK:    Errno : EAGAIN	/* Operation would block */
-EINPROGRESS:    Errno : 36		/* Operation now in progress */
-EALREADY:       Errno : 37		/* Operation already in progress */
+EAGAIN          :: Platform_Error.EAGAIN          /* Resource temporarily unavailable */
+EWOULDBLOCK     :: EAGAIN        /*  Operation would block */
+EINPROGRESS     :: Platform_Error.EINPROGRESS     /* Operation now in progress */
+EALREADY        :: Platform_Error.EALREADY        /* Operation already in progress */
 
 /* ipc/network software -- argument errors */
-ENOTSOCK:       Errno : 38		/* Socket operation on non-socket */
-EDESTADDRREQ:   Errno : 39		/* Destination address required */
-EMSGSIZE:       Errno : 40		/* Message too long */
-EPROTOTYPE:     Errno : 41		/* Protocol wrong type for socket */
-ENOPROTOOPT:    Errno : 42		/* Protocol option not available */
-EPROTONOSUPPORT:    Errno : 43		/* Protocol not supported */
-ESOCKTNOSUPPORT:    Errno : 44		/* Socket type not supported */
-EOPNOTSUPP:     Errno : 45		/* Operation not supported */
-EPFNOSUPPORT:   Errno : 46		/* Protocol family not supported */
-EAFNOSUPPORT:   Errno : 47		/* Address family not supported by protocol family */
-EADDRINUSE:     Errno : 48		/* Address already in use */
-EADDRNOTAVAIL:  Errno : 49		/* Can't assign requested address */
+ENOTSOCK        :: Platform_Error.ENOTSOCK        /* Socket operation on non-socket */
+EDESTADDRREQ    :: Platform_Error.EDESTADDRREQ    /* Destination address required */
+EMSGSIZE        :: Platform_Error.EMSGSIZE        /* Message too long */
+EPROTOTYPE      :: Platform_Error.EPROTOTYPE      /* Protocol wrong type for socket */
+ENOPROTOOPT     :: Platform_Error.ENOPROTOOPT     /* Protocol option not available */
+EPROTONOSUPPORT :: Platform_Error.EPROTONOSUPPORT /* Protocol not supported */
+ESOCKTNOSUPPORT :: Platform_Error.ESOCKTNOSUPPORT /* Socket type not supported */
+EOPNOTSUPP      :: Platform_Error.EOPNOTSUPP      /* Operation not supported */
+EPFNOSUPPORT    :: Platform_Error.EPFNOSUPPORT    /* Protocol family not supported */
+EAFNOSUPPORT    :: Platform_Error.EAFNOSUPPORT    /* Address family not supported by protocol family */
+EADDRINUSE      :: Platform_Error.EADDRINUSE      /* Address already in use */
+EADDRNOTAVAIL   :: Platform_Error.EADDRNOTAVAIL   /* Can't assign requested address */
 
 /* ipc/network software -- operational errors */
-ENETDOWN:       Errno : 50		/* Network is down */
-ENETUNREACH:    Errno : 51		/* Network is unreachable */
-ENETRESET:      Errno : 52		/* Network dropped connection on reset */
-ECONNABORTED:   Errno : 53		/* Software caused connection abort */
-ECONNRESET:     Errno : 54		/* Connection reset by peer */
-ENOBUFS:        Errno : 55		/* No buffer space available */
-EISCONN:        Errno : 56		/* Socket is already connected */
-ENOTCONN:       Errno : 57		/* Socket is not connected */
-ESHUTDOWN:      Errno : 58		/* Can't send after socket shutdown */
-ETOOMANYREFS:   Errno : 59		/* Too many references: can't splice */
-ETIMEDOUT:      Errno : 60		/* Operation timed out */
-ECONNREFUSED:   Errno : 61		/* Connection refused */
-
-ELOOP:          Errno : 62		/* Too many levels of symbolic links */
-ENAMETOOLONG:   Errno : 63		/* File name too long */
+ENETDOWN        :: Platform_Error.ENETDOWN        /* Network is down */
+ENETUNREACH     :: Platform_Error.ENETUNREACH     /* Network is unreachable */
+ENETRESET       :: Platform_Error.ENETRESET       /* Network dropped connection on reset */
+ECONNABORTED    :: Platform_Error.ECONNABORTED    /* Software caused connection abort */
+ECONNRESET      :: Platform_Error.ECONNRESET      /* Connection reset by peer */
+ENOBUFS         :: Platform_Error.ENOBUFS         /* No buffer space available */
+EISCONN         :: Platform_Error.EISCONN         /* Socket is already connected */
+ENOTCONN        :: Platform_Error.ENOTCONN        /* Socket is not connected */
+ESHUTDOWN       :: Platform_Error.ESHUTDOWN       /* Can't send after socket shutdown */
+ETOOMANYREFS    :: Platform_Error.ETOOMANYREFS    /* Too many references: can't splice */
+ETIMEDOUT       :: Platform_Error.ETIMEDOUT       /* Operation timed out */
+ECONNREFUSED    :: Platform_Error.ECONNREFUSED    /* Connection refused */
+
+ELOOP           :: Platform_Error.ELOOP           /* Too many levels of symbolic links */
+ENAMETOOLONG    :: Platform_Error.ENAMETOOLONG    /* File name too long */
 
 /* should be rearranged */
-EHOSTDOWN:      Errno : 64		/* Host is down */
-EHOSTUNREACH:   Errno : 65		/* No route to host */
-ENOTEMPTY:      Errno : 66		/* Directory not empty */
+EHOSTDOWN       :: Platform_Error.EHOSTDOWN       /* Host is down */
+EHOSTUNREACH    :: Platform_Error.EHOSTUNREACH    /* No route to host */
+ENOTEMPTY       :: Platform_Error.ENOTEMPTY       /* Directory not empty */
 
 /* quotas & mush */
-EPROCLIM:       Errno : 67		/* Too many processes */
-EUSERS:         Errno : 68		/* Too many users */
-EDQUOT:         Errno : 69		/* Disc quota exceeded */
+EPROCLIM        :: Platform_Error.EPROCLIM        /* Too many processes */
+EUSERS          :: Platform_Error.EUSERS          /* Too many users */
+EDQUOT          :: Platform_Error.EDQUOT          /* Disc quota exceeded */
 
 /* Network File System */
-ESTALE:         Errno : 70		/* Stale NFS file handle */
-EREMOTE:        Errno : 71		/* Too many levels of remote in path */
-EBADRPC:        Errno : 72		/* RPC struct is bad */
-ERPCMISMATCH:   Errno : 73		/* RPC version wrong */
-EPROGUNAVAIL:   Errno : 74		/* RPC prog. not avail */
-EPROGMISMATCH:  Errno : 75		/* Program version wrong */
-EPROCUNAVAIL:   Errno : 76		/* Bad procedure for program */
+ESTALE          :: Platform_Error.ESTALE          /* Stale NFS file handle */
+EREMOTE         :: Platform_Error.EREMOTE         /* Too many levels of remote in path */
+EBADRPC         :: Platform_Error.EBADRPC         /* RPC struct is bad */
+ERPCMISMATCH    :: Platform_Error.ERPCMISMATCH    /* RPC version wrong */
+EPROGUNAVAIL    :: Platform_Error.EPROGUNAVAIL    /* RPC prog. not avail */
+EPROGMISMATCH   :: Platform_Error.EPROGMISMATCH   /* Program version wrong */
+EPROCUNAVAIL    :: Platform_Error.EPROCUNAVAIL    /* Bad procedure for program */
 
-ENOLCK:         Errno : 77		/* No locks available */
-ENOSYS:         Errno : 78		/* Function not implemented */
+ENOLCK          :: Platform_Error.ENOLCK          /* No locks available */
+ENOSYS          :: Platform_Error.ENOSYS          /* Function not implemented */
 
-EFTYPE:         Errno : 79		/* Inappropriate file type or format */
-EAUTH:          Errno : 80		/* Authentication error */
-ENEEDAUTH:      Errno : 81		/* Need authenticator */
+EFTYPE          :: Platform_Error.EFTYPE          /* Inappropriate file type or format */
+EAUTH           :: Platform_Error.EAUTH           /* Authentication error */
+ENEEDAUTH       :: Platform_Error.ENEEDAUTH       /* Need authenticator */
 
 /* SystemV IPC */
-EIDRM:          Errno : 82		/* Identifier removed */
-ENOMSG:         Errno : 83		/* No message of desired type */
-EOVERFLOW:      Errno : 84		/* Value too large to be stored in data type */
+EIDRM           :: Platform_Error.EIDRM           /* Identifier removed */
+ENOMSG          :: Platform_Error.ENOMSG          /* No message of desired type */
+EOVERFLOW       :: Platform_Error.EOVERFLOW       /* Value too large to be stored in data type */
 
 /* Wide/multibyte-character handling, ISO/IEC 9899/AMD1:1995 */
-EILSEQ:         Errno : 85		/* Illegal byte sequence */
+EILSEQ          :: Platform_Error.EILSEQ          /* Illegal byte sequence */
 
 /* From IEEE Std 1003.1-2001 */
 /* Base, Realtime, Threads or Thread Priority Scheduling option errors */
-ENOTSUP:        Errno : 86		/* Not supported */
+ENOTSUP         :: Platform_Error.ENOTSUP         /* Not supported */
 
 /* Realtime option errors */
-ECANCELED:      Errno : 87		/* Operation canceled */
+ECANCELED       :: Platform_Error.ECANCELED       /* Operation canceled */
 
 /* Realtime, XSI STREAMS option errors */
-EBADMSG:        Errno : 88		/* Bad or Corrupt message */
+EBADMSG         :: Platform_Error.EBADMSG         /* Bad or Corrupt message */
 
 /* XSI STREAMS option errors  */
-ENODATA:        Errno : 89		/* No message available */
-ENOSR:          Errno : 90		/* No STREAM resources */
-ENOSTR:         Errno : 91		/* Not a STREAM */
-ETIME:          Errno : 92		/* STREAM ioctl timeout */
+ENODATA         :: Platform_Error.ENODATA         /* No message available */
+ENOSR           :: Platform_Error.ENOSR           /* No STREAM resources */
+ENOSTR          :: Platform_Error.ENOSTR          /* Not a STREAM */
+ETIME           :: Platform_Error.ETIME           /* STREAM ioctl timeout */
 
 /* File system extended attribute errors */
-ENOATTR:        Errno : 93		/* Attribute not found */
+ENOATTR         :: Platform_Error.ENOATTR         /* Attribute not found */
 
 /* Realtime, XSI STREAMS option errors */
-EMULTIHOP:      Errno : 94		/* Multihop attempted */
-ENOLINK:        Errno : 95		/* Link has been severed */
-EPROTO:         Errno : 96		/* Protocol error */
+EMULTIHOP       :: Platform_Error.EMULTIHOP       /* Multihop attempted */
+ENOLINK         :: Platform_Error.ENOLINK         /* Link has been severed */
+EPROTO          :: Platform_Error.EPROTO          /* Protocol error */
 
 /* Robust mutexes */
-EOWNERDEAD:     Errno : 97		/* Previous owner died */
-ENOTRECOVERABLE:    Errno : 98		/* State not recoverable */
+EOWNERDEAD      :: Platform_Error.EOWNERDEAD      /* Previous owner died */
+ENOTRECOVERABLE :: Platform_Error.ENOTRECOVERABLE /* State not recoverable */
 
-ELAST:          Errno : 98		/* Must equal largest errno */
+ELAST           :: Platform_Error.ELAST           /* Must equal largest errno */
 
 /* end of errno */
 
@@ -338,8 +477,8 @@ is_path_separator :: proc(r: rune) -> bool {
 	return r == '/'
 }
 
-get_last_error :: proc "contextless" () -> int {
-	return int(__errno_location()^)
+get_last_error :: proc "contextless" () -> Error {
+	return Error(__errno_location()^)
 }
 
 open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) {

+ 198 - 101
core/os/os_openbsd.odin

@@ -9,108 +9,205 @@ import "base:runtime"
 Handle    :: distinct i32
 Pid       :: distinct i32
 File_Time :: distinct u64
-Errno     :: distinct i32
 
 INVALID_HANDLE :: ~Handle(0)
 
-ERROR_NONE:	Errno: 0
-
-EPERM:		Errno: 1
-ENOENT:		Errno: 2
-ESRCH:		Errno: 3
-EINTR:		Errno: 4
-EIO:		Errno: 5
-ENXIO:		Errno: 6
-E2BIG:		Errno: 7
-ENOEXEC:	Errno: 8
-EBADF:		Errno: 9
-ECHILD:		Errno: 10
-EDEADLK:	Errno: 11
-ENOMEM:		Errno: 12
-EACCES:		Errno: 13
-EFAULT:		Errno: 14
-ENOTBLK:	Errno: 15
-EBUSY:		Errno: 16
-EEXIST:		Errno: 17
-EXDEV:		Errno: 18
-ENODEV:		Errno: 19
-ENOTDIR:	Errno: 20
-EISDIR:		Errno: 21
-EINVAL:		Errno: 22
-ENFILE:		Errno: 23
-EMFILE:		Errno: 24
-ENOTTY:		Errno: 25
-ETXTBSY:	Errno: 26
-EFBIG:		Errno: 27
-ENOSPC:		Errno: 28
-ESPIPE:		Errno: 29
-EROFS:		Errno: 30
-EMLINK:		Errno: 31
-EPIPE:		Errno: 32
-EDOM:		Errno: 33
-ERANGE:		Errno: 34
-EAGAIN:		Errno: 35
-EWOULDBLOCK:	Errno: EAGAIN
-EINPROGRESS:	Errno: 36
-EALREADY:	Errno: 37
-ENOTSOCK:	Errno: 38
-EDESTADDRREQ:	Errno: 39
-EMSGSIZE:	Errno: 40
-EPROTOTYPE:	Errno: 41
-ENOPROTOOPT:	Errno: 42
-EPROTONOSUPPORT: Errno: 43
-ESOCKTNOSUPPORT: Errno: 44
-EOPNOTSUPP:	Errno: 45
-EPFNOSUPPORT:	Errno: 46
-EAFNOSUPPORT:	Errno: 47
-EADDRINUSE:	Errno: 48
-EADDRNOTAVAIL:	Errno: 49
-ENETDOWN:	Errno: 50
-ENETUNREACH:	Errno: 51
-ENETRESET:	Errno: 52
-ECONNABORTED:	Errno: 53
-ECONNRESET:	Errno: 54
-ENOBUFS:	Errno: 55
-EISCONN:	Errno: 56
-ENOTCONN:	Errno: 57
-ESHUTDOWN:	Errno: 58
-ETOOMANYREFS:	Errno: 59
-ETIMEDOUT:	Errno: 60
-ECONNREFUSED:	Errno: 61
-ELOOP:		Errno: 62
-ENAMETOOLONG:	Errno: 63
-EHOSTDOWN:	Errno: 64
-EHOSTUNREACH:	Errno: 65
-ENOTEMPTY:	Errno: 66
-EPROCLIM:	Errno: 67
-EUSERS:		Errno: 68
-EDQUOT:		Errno: 69
-ESTALE:		Errno: 70
-EREMOTE:	Errno: 71
-EBADRPC:	Errno: 72
-ERPCMISMATCH:	Errno: 73
-EPROGUNAVAIL:	Errno: 74
-EPROGMISMATCH:	Errno: 75
-EPROCUNAVAIL:	Errno: 76
-ENOLCK:		Errno: 77
-ENOSYS:		Errno: 78
-EFTYPE:		Errno: 79
-EAUTH:		Errno: 80
-ENEEDAUTH:	Errno: 81
-EIPSEC:		Errno: 82
-ENOATTR:	Errno: 83
-EILSEQ:		Errno: 84
-ENOMEDIUM:	Errno: 85
-EMEDIUMTYPE:	Errno: 86
-EOVERFLOW:	Errno: 87
-ECANCELED:	Errno: 88
-EIDRM:		Errno: 89
-ENOMSG:		Errno: 90
-ENOTSUP:	Errno: 91
-EBADMSG:	Errno: 92
-ENOTRECOVERABLE: Errno: 93
-EOWNERDEAD:	Errno: 94
-EPROTO:		Errno: 95
+_Platform_Error :: enum i32 {
+	NONE = 0,
+	EPERM           = 1,
+	ENOENT          = 2,
+	ESRCH           = 3,
+	EINTR           = 4,
+	EIO             = 5,
+	ENXIO           = 6,
+	E2BIG           = 7,
+	ENOEXEC         = 8,
+	EBADF           = 9,
+	ECHILD          = 10,
+	EDEADLK         = 11,
+	ENOMEM          = 12,
+	EACCES          = 13,
+	EFAULT          = 14,
+	ENOTBLK         = 15,
+	EBUSY           = 16,
+	EEXIST          = 17,
+	EXDEV           = 18,
+	ENODEV          = 19,
+	ENOTDIR         = 20,
+	EISDIR          = 21,
+	EINVAL          = 22,
+	ENFILE          = 23,
+	EMFILE          = 24,
+	ENOTTY          = 25,
+	ETXTBSY         = 26,
+	EFBIG           = 27,
+	ENOSPC          = 28,
+	ESPIPE          = 29,
+	EROFS           = 30,
+	EMLINK          = 31,
+	EPIPE           = 32,
+	EDOM            = 33,
+	ERANGE          = 34,
+	EAGAIN          = 35,
+	EWOULDBLOCK     = EAGAIN,
+	EINPROGRESS     = 36,
+	EALREADY        = 37,
+	ENOTSOCK        = 38,
+	EDESTADDRREQ    = 39,
+	EMSGSIZE        = 40,
+	EPROTOTYPE      = 41,
+	ENOPROTOOPT     = 42,
+	EPROTONOSUPPORT = 43,
+	ESOCKTNOSUPPORT = 44,
+	EOPNOTSUPP      = 45,
+	EPFNOSUPPORT    = 46,
+	EAFNOSUPPORT    = 47,
+	EADDRINUSE      = 48,
+	EADDRNOTAVAIL   = 49,
+	ENETDOWN        = 50,
+	ENETUNREACH     = 51,
+	ENETRESET       = 52,
+	ECONNABORTED    = 53,
+	ECONNRESET      = 54,
+	ENOBUFS         = 55,
+	EISCONN         = 56,
+	ENOTCONN        = 57,
+	ESHUTDOWN       = 58,
+	ETOOMANYREFS    = 59,
+	ETIMEDOUT       = 60,
+	ECONNREFUSED    = 61,
+	ELOOP           = 62,
+	ENAMETOOLONG    = 63,
+	EHOSTDOWN       = 64,
+	EHOSTUNREACH    = 65,
+	ENOTEMPTY       = 66,
+	EPROCLIM        = 67,
+	EUSERS          = 68,
+	EDQUOT          = 69,
+	ESTALE          = 70,
+	EREMOTE         = 71,
+	EBADRPC         = 72,
+	ERPCMISMATCH    = 73,
+	EPROGUNAVAIL    = 74,
+	EPROGMISMATCH   = 75,
+	EPROCUNAVAIL    = 76,
+	ENOLCK          = 77,
+	ENOSYS          = 78,
+	EFTYPE          = 79,
+	EAUTH           = 80,
+	ENEEDAUTH       = 81,
+	EIPSEC          = 82,
+	ENOATTR         = 83,
+	EILSEQ          = 84,
+	ENOMEDIUM       = 85,
+	EMEDIUMTYPE     = 86,
+	EOVERFLOW       = 87,
+	ECANCELED       = 88,
+	EIDRM           = 89,
+	ENOMSG          = 90,
+	ENOTSUP         = 91,
+	EBADMSG         = 92,
+	ENOTRECOVERABLE = 93,
+	EOWNERDEAD      = 94,
+	EPROTO          = 95,
+}
+
+EPERM           :: Platform_Error.EPERM
+ENOENT          :: Platform_Error.ENOENT
+ESRCH           :: Platform_Error.ESRCH
+EINTR           :: Platform_Error.EINTR
+EIO             :: Platform_Error.EIO
+ENXIO           :: Platform_Error.ENXIO
+E2BIG           :: Platform_Error.E2BIG
+ENOEXEC         :: Platform_Error.ENOEXEC
+EBADF           :: Platform_Error.EBADF
+ECHILD          :: Platform_Error.ECHILD
+EDEADLK         :: Platform_Error.EDEADLK
+ENOMEM          :: Platform_Error.ENOMEM
+EACCES          :: Platform_Error.EACCES
+EFAULT          :: Platform_Error.EFAULT
+ENOTBLK         :: Platform_Error.ENOTBLK
+EBUSY           :: Platform_Error.EBUSY
+EEXIST          :: Platform_Error.EEXIST
+EXDEV           :: Platform_Error.EXDEV
+ENODEV          :: Platform_Error.ENODEV
+ENOTDIR         :: Platform_Error.ENOTDIR
+EISDIR          :: Platform_Error.EISDIR
+EINVAL          :: Platform_Error.EINVAL
+ENFILE          :: Platform_Error.ENFILE
+EMFILE          :: Platform_Error.EMFILE
+ENOTTY          :: Platform_Error.ENOTTY
+ETXTBSY         :: Platform_Error.ETXTBSY
+EFBIG           :: Platform_Error.EFBIG
+ENOSPC          :: Platform_Error.ENOSPC
+ESPIPE          :: Platform_Error.ESPIPE
+EROFS           :: Platform_Error.EROFS
+EMLINK          :: Platform_Error.EMLINK
+EPIPE           :: Platform_Error.EPIPE
+EDOM            :: Platform_Error.EDOM
+ERANGE          :: Platform_Error.ERANGE
+EAGAIN          :: Platform_Error.EAGAIN
+EWOULDBLOCK     :: Platform_Error.EWOULDBLOCK
+EINPROGRESS     :: Platform_Error.EINPROGRESS
+EALREADY        :: Platform_Error.EALREADY
+ENOTSOCK        :: Platform_Error.ENOTSOCK
+EDESTADDRREQ    :: Platform_Error.EDESTADDRREQ
+EMSGSIZE        :: Platform_Error.EMSGSIZE
+EPROTOTYPE      :: Platform_Error.EPROTOTYPE
+ENOPROTOOPT     :: Platform_Error.ENOPROTOOPT
+EPROTONOSUPPORT :: Platform_Error.EPROTONOSUPPORT
+ESOCKTNOSUPPORT :: Platform_Error.ESOCKTNOSUPPORT
+EOPNOTSUPP      :: Platform_Error.EOPNOTSUPP
+EPFNOSUPPORT    :: Platform_Error.EPFNOSUPPORT
+EAFNOSUPPORT    :: Platform_Error.EAFNOSUPPORT
+EADDRINUSE      :: Platform_Error.EADDRINUSE
+EADDRNOTAVAIL   :: Platform_Error.EADDRNOTAVAIL
+ENETDOWN        :: Platform_Error.ENETDOWN
+ENETUNREACH     :: Platform_Error.ENETUNREACH
+ENETRESET       :: Platform_Error.ENETRESET
+ECONNABORTED    :: Platform_Error.ECONNABORTED
+ECONNRESET      :: Platform_Error.ECONNRESET
+ENOBUFS         :: Platform_Error.ENOBUFS
+EISCONN         :: Platform_Error.EISCONN
+ENOTCONN        :: Platform_Error.ENOTCONN
+ESHUTDOWN       :: Platform_Error.ESHUTDOWN
+ETOOMANYREFS    :: Platform_Error.ETOOMANYREFS
+ETIMEDOUT       :: Platform_Error.ETIMEDOUT
+ECONNREFUSED    :: Platform_Error.ECONNREFUSED
+ELOOP           :: Platform_Error.ELOOP
+ENAMETOOLONG    :: Platform_Error.ENAMETOOLONG
+EHOSTDOWN       :: Platform_Error.EHOSTDOWN
+EHOSTUNREACH    :: Platform_Error.EHOSTUNREACH
+ENOTEMPTY       :: Platform_Error.ENOTEMPTY
+EPROCLIM        :: Platform_Error.EPROCLIM
+EUSERS          :: Platform_Error.EUSERS
+EDQUOT          :: Platform_Error.EDQUOT
+ESTALE          :: Platform_Error.ESTALE
+EREMOTE         :: Platform_Error.EREMOTE
+EBADRPC         :: Platform_Error.EBADRPC
+ERPCMISMATCH    :: Platform_Error.ERPCMISMATCH
+EPROGUNAVAIL    :: Platform_Error.EPROGUNAVAIL
+EPROGMISMATCH   :: Platform_Error.EPROGMISMATCH
+EPROCUNAVAIL    :: Platform_Error.EPROCUNAVAIL
+ENOLCK          :: Platform_Error.ENOLCK
+ENOSYS          :: Platform_Error.ENOSYS
+EFTYPE          :: Platform_Error.EFTYPE
+EAUTH           :: Platform_Error.EAUTH
+ENEEDAUTH       :: Platform_Error.ENEEDAUTH
+EIPSEC          :: Platform_Error.EIPSEC
+ENOATTR         :: Platform_Error.ENOATTR
+EILSEQ          :: Platform_Error.EILSEQ
+ENOMEDIUM       :: Platform_Error.ENOMEDIUM
+EMEDIUMTYPE     :: Platform_Error.EMEDIUMTYPE
+EOVERFLOW       :: Platform_Error.EOVERFLOW
+ECANCELED       :: Platform_Error.ECANCELED
+EIDRM           :: Platform_Error.EIDRM
+ENOMSG          :: Platform_Error.ENOMSG
+ENOTSUP         :: Platform_Error.ENOTSUP
+EBADMSG         :: Platform_Error.EBADMSG
+ENOTRECOVERABLE :: Platform_Error.ENOTRECOVERABLE
+EOWNERDEAD      :: Platform_Error.EOWNERDEAD
+EPROTO          :: Platform_Error.EPROTO
 
 O_RDONLY   :: 0x00000
 O_WRONLY   :: 0x00001
@@ -295,8 +392,8 @@ is_path_separator :: proc(r: rune) -> bool {
 	return r == '/'
 }
 
-get_last_error :: proc "contextless" () -> int {
-	return int(__error()^)
+get_last_error :: proc "contextless" () -> Error {
+	return Error(__error()^)
 }
 
 fork :: proc() -> (Pid, Errno) {

+ 4 - 2
core/os/os_wasi.odin

@@ -4,11 +4,13 @@ import "core:sys/wasm/wasi"
 import "base:runtime"
 
 Handle :: distinct i32
-Errno :: distinct i32
+_Platform_Error :: enum i32 {
+	NONE = 0,
+}
 
 INVALID_HANDLE :: -1
 
-ERROR_NONE :: Errno(wasi.errno_t.SUCCESS)
+// ERROR_NONE :: Errno(wasi.errno_t.SUCCESS) // that is a weird error code. Probably better to remap it
 
 O_RDONLY   :: 0x00000
 O_WRONLY   :: 0x00001

+ 30 - 31
core/os/os_windows.odin

@@ -7,7 +7,6 @@ import "base:intrinsics"
 
 Handle    :: distinct uintptr
 File_Time :: distinct u64
-Errno     :: distinct int
 
 
 INVALID_HANDLE :: ~Handle(0)
@@ -27,38 +26,38 @@ O_SYNC     :: 0x01000
 O_ASYNC    :: 0x02000
 O_CLOEXEC  :: 0x80000
 
-
-ERROR_NONE:                   Errno : 0
-ERROR_FILE_NOT_FOUND:         Errno : 2
-ERROR_PATH_NOT_FOUND:         Errno : 3
-ERROR_ACCESS_DENIED:          Errno : 5
-ERROR_INVALID_HANDLE:         Errno : 6
-ERROR_NOT_ENOUGH_MEMORY:      Errno : 8
-ERROR_NO_MORE_FILES:          Errno : 18
-ERROR_HANDLE_EOF:             Errno : 38
-ERROR_NETNAME_DELETED:        Errno : 64
-ERROR_FILE_EXISTS:            Errno : 80
-ERROR_INVALID_PARAMETER:      Errno : 87
-ERROR_BROKEN_PIPE:            Errno : 109
-ERROR_BUFFER_OVERFLOW:        Errno : 111
-ERROR_INSUFFICIENT_BUFFER:    Errno : 122
-ERROR_MOD_NOT_FOUND:          Errno : 126
-ERROR_PROC_NOT_FOUND:         Errno : 127
-ERROR_DIR_NOT_EMPTY:          Errno : 145
-ERROR_ALREADY_EXISTS:         Errno : 183
-ERROR_ENVVAR_NOT_FOUND:       Errno : 203
-ERROR_MORE_DATA:              Errno : 234
-ERROR_OPERATION_ABORTED:      Errno : 995
-ERROR_IO_PENDING:             Errno : 997
-ERROR_NOT_FOUND:              Errno : 1168
-ERROR_PRIVILEGE_NOT_HELD:     Errno : 1314
-WSAEACCES:                    Errno : 10013
-WSAECONNRESET:                Errno : 10054
+_Platform_Error :: win32.System_Error
+
+ERROR_FILE_NOT_FOUND      :: _Platform_Error(2)
+ERROR_PATH_NOT_FOUND      :: _Platform_Error(3)
+ERROR_ACCESS_DENIED       :: _Platform_Error(5)
+ERROR_INVALID_HANDLE      :: _Platform_Error(6)
+ERROR_NOT_ENOUGH_MEMORY   :: _Platform_Error(8)
+ERROR_NO_MORE_FILES       :: _Platform_Error(18)
+ERROR_HANDLE_EOF          :: _Platform_Error(38)
+ERROR_NETNAME_DELETED     :: _Platform_Error(64)
+ERROR_FILE_EXISTS         :: _Platform_Error(80)
+ERROR_INVALID_PARAMETER   :: _Platform_Error(87)
+ERROR_BROKEN_PIPE         :: _Platform_Error(109)
+ERROR_BUFFER_OVERFLOW     :: _Platform_Error(111)
+ERROR_INSUFFICIENT_BUFFER :: _Platform_Error(122)
+ERROR_MOD_NOT_FOUND       :: _Platform_Error(126)
+ERROR_PROC_NOT_FOUND      :: _Platform_Error(127)
+ERROR_DIR_NOT_EMPTY       :: _Platform_Error(145)
+ERROR_ALREADY_EXISTS      :: _Platform_Error(183)
+ERROR_ENVVAR_NOT_FOUND    :: _Platform_Error(203)
+ERROR_MORE_DATA           :: _Platform_Error(234)
+ERROR_OPERATION_ABORTED   :: _Platform_Error(995)
+ERROR_IO_PENDING          :: _Platform_Error(997)
+ERROR_NOT_FOUND           :: _Platform_Error(1168)
+ERROR_PRIVILEGE_NOT_HELD  :: _Platform_Error(1314)
+WSAEACCES                 :: _Platform_Error(10013)
+WSAECONNRESET             :: _Platform_Error(10054)
 
 // Windows reserves errors >= 1<<29 for application use
-ERROR_FILE_IS_PIPE:           Errno : 1<<29 + 0
-ERROR_FILE_IS_NOT_DIR:        Errno : 1<<29 + 1
-ERROR_NEGATIVE_OFFSET:        Errno : 1<<29 + 2
+ERROR_FILE_IS_PIPE        :: _Platform_Error(1<<29 + 0)
+ERROR_FILE_IS_NOT_DIR     :: _Platform_Error(1<<29 + 1)
+ERROR_NEGATIVE_OFFSET     :: _Platform_Error(1<<29 + 2)
 
 // "Argv" arguments converted to Odin strings
 args := _alloc_command_line_arguments()

+ 2 - 2
core/prof/spall/spall_unix.odin

@@ -23,8 +23,8 @@ foreign libc {
 }
 
 @(no_instrumentation)
-get_last_error :: proc "contextless" () -> int {
-	return int(__error()^)
+get_last_error :: proc "contextless" () -> os.Platform_Error {
+	return os.Platform_Error(__error()^)
 }
 
 MAX_RW :: 0x7fffffff

+ 5 - 6
core/sync/futex_haiku.odin

@@ -2,7 +2,6 @@
 package sync
 
 import "core:c"
-import "base:runtime"
 import "core:sys/haiku"
 import "core:sys/unix"
 import "core:time"
@@ -86,10 +85,10 @@ _futex_wait :: proc "contextless" (f: ^Futex, expect: u32) -> (ok: bool) {
 	waiter.prev.next = waiter.next
 	waiter.next.prev = waiter.prev
 
- 	unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
+	_ = unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
 
  	// FIXME: Add error handling!
- 	return
+	return
 }
 
 _futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expect: u32, duration: time.Duration) -> (ok: bool) {
@@ -133,10 +132,10 @@ _futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expect: u32, duration
 	waiter.prev.next = waiter.next
 	waiter.next.prev = waiter.prev
 
- 	unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
+	unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
 
- 	// FIXME: Add error handling!
- 	return 
+	// FIXME: Add error handling!
+	return
 }
 
 _futex_signal :: proc "contextless" (f: ^Futex) {

+ 1 - 1
core/sys/haiku/os.odin

@@ -399,7 +399,7 @@ cpu_topology_node_info :: struct {
 		},
 		_package: struct {
 			vendor:          cpu_vendor,
-			cache_line_size: u32
+			cache_line_size: u32,
 		},
 		_core: struct {
 			model:             u32,

+ 21 - 0
src/check_expr.cpp

@@ -127,6 +127,8 @@ gb_internal bool complete_soa_type(Checker *checker, Type *t, bool wait_to_finis
 
 gb_internal bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y);
 
+gb_internal bool is_exact_value_zero(ExactValue const &v);
+
 enum LoadDirectiveResult {
 	LoadDirective_Success  = 0,
 	LoadDirective_Error    = 1,
@@ -4364,6 +4366,25 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
 	}
 
 	switch (t->kind) {
+	// IMPORTANT NOTE HACK(bill): This is just to allow for comparisons against `0` with the `os.Error` type
+	// as a kind of transition period
+	case Type_Enum:
+		if (operand->mode == Addressing_Constant &&
+		    target_type->kind == Type_Named &&
+		    target_type->Named.name == "Error") {
+			Entity *e = target_type->Named.type_name;
+			if (e->pkg && e->pkg->name == "os") {
+				if (is_exact_value_zero(operand->value)) {
+					check_is_expressible(c, operand, t);
+					if (operand->mode == Addressing_Invalid) {
+						return;
+					}
+					update_untyped_expr_value(c, operand->expr, operand->value);
+				}
+			}
+		}
+		break;
+
 	case Type_Basic:
 		if (operand->mode == Addressing_Constant) {
 			check_is_expressible(c, operand, t);