Sortix volatile manual
This manual documents Sortix volatile, a development build that has not been officially released. You can instead view this document in the latest official manual.
standard library portability information
alloca(3) and variable length arrays are implemented by the compiler, however the main thread stack size is fixed and does not grow unlike other operating systems, and large stack uses should instead use malloc(3) or set the stack size explicitly for another thread using pthread_attr_setstacksize(2).
memcpy(3) is the standard replacement. Note how the order of the source and destination parameters is swapped.
void * is the standard type.
clock(3) is implemented but can overflow, and clock_gettime(2) CLOCK_PROCESS_CPUTIME_ID is the modern replacement with nanosecond precision.
daemon(7) and be managed by init(8).
noreturn from <stdnoreturn.h> is the modern standard replacement or the __attribute__((noreturn)) extension can be used.
flock(2) is not currently implemented. It might be safe enough to omit the file locking as a workaround.
closefrom(2) and iterated using psctl(2).
getpgid(3) and setpgid(3) are the standard portable replacements without disagreement on the function signatures.
gettimeofday(2) is implemented but the second parameter is defunct and is typed void * per POSIX instead of struct timezone *. clock_gettime(2) is the modern replacement with nanosecond precision.
gid_t is 64-bit unsigned and can be formatted portably cast to a uintmax_t using “%ju”.
inet_pton(3) and getaddrinfo(3) are the modern standard replacements, however they don't support the unusual IPv4 notations.
limits.h> is currently implemented by the compiler instead of the standard library and it does not define everything required by POSIX. <sortix/limits.h> can be included instead as a temporary workaround if the required definitions are absent.
mkfifo(2) named pipes are not currently implemented but unnamed pipes are available using pipe(2), or alternatively AF_UNIX sockets can be used instead.
off_t is 64-bit signed and can be formatted portably cast to an intmax_t using “%jd”.
PATH_MAX limit does not currently exist and may be added in the future. Applications should be written as if this limit does not exist, but if required, it can be defined to 4096 as a fallback.
pid_t is 64-bit signed and can be formatted portably cast to an intmax_t using “%jd”.
poll(2) is implemented in <poll.h> per POSIX, however some operating systems have a <sys/poll.h> alias which is not implemented.
printf(3) is implemented, however floating point formatting is not currently implemented and the format specifier will instead be output verbatim. Position parameters are also not implemented yet.
setenv(3) is the standard replacement. Note how the string provided could technically be modified at a later time.
rand(3) and srand(3) are implemented, however invocations will warn that the functions are not random, and arc4random(3), arc4random_uniform(3), or arc4random_buf(3) should be used instead for random numbers.
realpath(3) with a non-null second parameter is undefined behavior as there is no PATH_MAX limit, and should always be invoked with a null second parameter which allocates a destination buffer of the appropriate size using malloc(3).
select(2) is implemented, but is defined in <sys/select.h> instead of <sys/time.h> per POSIX, however the superior poll(2) should be used instead as the fdset_t type overflows on file descriptors whose value is too large.
socklen_t is typedef to size_t instead of int or unsigned int as on other operating systems.
sprintf(3) is implemented, however invocations will warn the function is dangerous as it does not know the size of the destination buffer and may buffer overflow if the output is unexpectedly large. snprintf(3) should be use instead as the destination buffer size should always be known, otherwise the invocation is suspicious. The superior alternative is to combine allocation and initialization using asprintf(3).
sys/param.h> is not implemented as there is little agreement on what it's supposed to contain and all the contents have standard replacements or can be provided by the application itself. Inclusions are almost always unnecessary and can be removed.
times(2) is implemented, however the clock_t type may overflow, and the timens(2) non-standard extension with struct timespec precision can be used instead.
time_t is 64-bit signed and can be formatted portably cast to an intmax_t using “%ji” or with strftime(3) and such.CLOCK_REALTIME counts the number of seconds since the epoch including leap seconds, unlike other operating systems and in violation of POSIX. CLOCK_REALTIME_HAS_LEAP_SECONDS definition advertises CLOCK_REALTIME contains leap seconds since the epoch in the TAI-10 format.sub_leap_seconds(3) converts timestamps from TAI-10 to UTC by subtracting the leap seconds, while add_leap_seconds(3) converts timestamps from UTC TO TAI-10 by adding the leap seconds. These functions are useful when communicating with other operating systems either via the network or exchanged data files.
unsigned char, unsigned short, unsigned int, and unsigned long are the standard types. Applications can supply the typedefs themselves if desired.
uid_t is 64-bit unsigned and can be formatted portably cast to a uintmax_t using “%ju”.
uint8_t, uint16_t, uint32_t, and uint64_t are the standard types. Applications can supply the typedefs themselves if desired.