errno v0.1.0
CRuntime
// Windows
pub const CRuntime = "ucrtbase.dll";
// Linux
pub const CRuntime = "libc.so.6";
// macOS
pub const CRuntime = "libSystem.B.dylib";
// FreeBSD
pub const CRuntime = "libc.so.7";
The shared object this target's C runtime lives in.
StreamRuntime
// Windows
pub const StreamRuntime = "msvcrt.dll";
// Linux
pub const StreamRuntime = "libc.so.6";
// macOS
pub const StreamRuntime = "libSystem.B.dylib";
// FreeBSD
pub const StreamRuntime = "libc.so.7";
The shared object C::StdIo and C::Time are bound to, which on Windows is a different one.
The Universal CRT does not export the formatted-output family, so those two modules bind the legacy
runtime. It keeps its own errno, its own stream table and its own locale, so a failure reported by a
call through either module is readable only through ErrnoFor(CRuntimeArea::Streams).
| Overload | Summary |
|---|---|
pub const StreamRuntime = "msvcrt.dll"; | The shared object C::StdIo and C::Time are bound to, which on Windows is a different one. |
pub const StreamRuntime = "libc.so.6"; | The shared object C::StdIo and C::Time are bound to, which on this target is the same one. |
pub const StreamRuntime = "libSystem.B.dylib"; | The shared object C::StdIo and C::Time are bound to, which on this target is the same one. |
pub const StreamRuntime = "libc.so.7"; | The shared object C::StdIo and C::Time are bound to, which on this target is the same one. |
CRuntimeArea
pub enum CRuntimeArea: uint8 {
General = 0,
Streams = 1
}
Which of the package's C runtimes a call belongs to.
On Windows this package spans two: StdLib and Math bind the Universal CRT, while StdIo and Time bind the
legacy runtime, because the Universal CRT does not export the formatted-output family. The two keep separate
errno storage, so reading one after a call into the other reports a value belonging to something else
entirely.
Everywhere else there is one runtime and both cases name it, so a caller that always passes the area matching
the module it called is right on all four systems and needs no target branch of its own.
Cases
| Name | Value | Description |
|---|---|---|
General | 0 | Where C::StdLib and C::Math are bound, and what plain Errno reads. |
Streams | 1 | Where C::StdIo and C::Time are bound. The same runtime as General except on Windows. |
SeparateStreamRuntime
pub const SeparateStreamRuntime: bool = #target.os == OperatingSystem::Windows;
Whether the two areas are really two runtimes on this target. True on Windows and false everywhere else. A caller that passes the right area never needs to read this; it is here so that a program can say why it is being careful, and so that a test can assert the split exists where it is supposed to and does not where it is not.
ErrnoLocationFor
pub func ErrnoLocationFor(area: CRuntimeArea) -> *var c_int
The address of the calling thread's errno, in the runtime area names.
Returns a pointer that runtime owns, valid for as long as the calling thread runs. Writing through it is how
C's errno = 0 is spelled, which a caller does before a call whose failure is only reported through errno.
Pass the area matching the module whose call is being checked: Streams after anything from C::StdIo or
C::Time, General after anything from C::StdLib or C::Math. Passing the wrong one is not a compile error
and not a crash; it reads a different thread-local integer, which is the whole hazard this exists to remove.
Cannot fail. Runs in constant time and allocates nothing.
The address belongs to the calling thread and must not be handed to another one.
Parameters
| Name | Type | Description |
|---|---|---|
area | CRuntimeArea | which runtime's storage to reach |
Returns: the address of that runtime's errno for this thread
ErrnoFor
pub func ErrnoFor(area: CRuntimeArea) -> c_int
The calling thread's current errno value, in the runtime area names.
Meaningful only after a call that documents setting it: no C function clears errno on success, so a value left
over from an earlier failure is still there. Clear it through ErrnoLocationFor before the call whose failure
is to be read.
Cannot fail. Runs in constant time and allocates nothing.
Parameters
| Name | Type | Description |
|---|---|---|
area | CRuntimeArea | which runtime's storage to read |
Returns: that runtime's errno for this thread
ErrnoLocation
pub func ErrnoLocation() -> *var c_int
The address of the calling thread's errno, in the runtime C::StdLib and C::Math are bound to.
Exactly ErrnoLocationFor(CRuntimeArea::General), and the spelling to use when the call being checked came from
one of those two modules. After a call from C::StdIo or C::Time on Windows this reads the wrong runtime's
storage, which is what ErrnoLocationFor exists to let a caller avoid.
Writing through it is how C's errno = 0 is spelled, which a caller does before a call whose failure is only
reported through errno.
Cannot fail. Runs in constant time and allocates nothing.
The address belongs to the calling thread and must not be handed to another one.
Returns: the address of the general runtime's errno for this thread
Errno
pub func Errno() -> c_int
The calling thread's current errno value.
Takes nothing and returns the value by copy. Meaningful only after a call that documents setting it: no C function
clears errno on success, so a value left over from an earlier failure is still there. Clear it with
*ErrnoLocation() = 0 before the call whose failure is to be read.
On Windows this reads the Universal CRT's errno, which is the one C::StdLib and C::Math set. C::StdIo and
C::Time are still bound to the legacy msvcrt.dll, whose errno is a different variable in a different
runtime, so a failure reported by a call in either of those modules is not visible here. That split is a known
defect: the Universal CRT does not export the formatted-output family, so moving those modules across needs the
__stdio_common_* entry points declared first.
Cannot fail. Runs in constant time and allocates nothing.
Returns: the general runtime's errno for this thread
EDOM
pub const EDOM: c_int = 33;
EDOM: an argument outside the domain over which a math function is defined.
ERANGE
pub const ERANGE: c_int = 34;
ERANGE: a result too large or too small for the return type to express.
EILSEQ
// Windows
pub const EILSEQ: c_int = 42;
// Linux
pub const EILSEQ: c_int = 84;
// macOS
pub const EILSEQ: c_int = 92;
// FreeBSD
pub const EILSEQ: c_int = 86;
EILSEQ: a byte sequence that does not form a valid character.