a64l
Converts base64 to 32-bit integer, the posix way.
- const char* s
- long
abort
Terminates program abnormally.
This function first tries to trigger your SIGABRT handler. If the
signal handler returns, then signal(SIGABRT, SIG_DFL)
is called
before SIGABRT is raised again.
abs
Returns absolute value of 𝑥.
This function is a footgun since your argument may be narrrowed. Consider using labs(), llabs(), or better yet a macro like this:
#define ABS(X) ((X) >= 0 ? (X) : -(X))Note that passing
x
as INT_MIN
is undefined behavior, which
depends on whether or not your c library as well as the objects
that call it were built using the -fwrapv
or -ftrapv
flags.
- int x
- int
accept
Creates client socket file descriptor for incoming connection.
On Windows, when this function blocks, there may be a 10 millisecond delay on the handling of signals or thread cancelation.
- int fd
- is the server socket file descriptor
- struct sockaddr* opt_out_addr
- will receive the remote address
- unsigned int* opt_inout_addrsize
- provides and receives addr's byte length
- int
- client fd which needs close(), or -1 w/ errno
accept4
Creates client socket file descriptor for incoming connection.
When fd
is in O_NONBLOCK
mode, this function will raise EAGAIN
when no client is available to accept. To wait until a client exists
the poll() function may be called using POLLIN
.
On Linux, your SO_RCVTIMEO
will timeout accept4(). Other OSes (i.e.
Windows, MacOS, and BSDs) do not support this and will block forever.
On Windows, when this function blocks, there may be a 10 millisecond delay on the handling of signals or thread cancelation.
- int fd
- is the server socket file descriptor
- struct sa* opt_out_addr
- will receive the remote address
- unsigned int* opt_inout_addrsize
- provides and receives out_addr's byte length
- int flags
- can have SOCK_{CLOEXEC,NONBLOCK}, which may apply to both the newly created socket and the server one
- int
- client fd which needs close(), or -1 w/ errno
O_NONBLOCK
and no clients pending
access
Checks if effective user can access path in particular ways.
This is equivalent to saying:
faccessat(AT_FDCWD, path, mode, 0);
- const char* path
- is a filename or directory
- int mode
- can be R_OK, W_OK, X_OK, F_OK
- int
- 0 if ok, or -1 w/ errno
acos
Returns arc cosine of 𝑥.
- double x
- double
- value in range [0,M_PI]
- NAN if 𝑥 ∈ {NAN,+INFINITY,-INFINITY}
- NAN if 𝑥 ∉ [-1,1]
- NAN if 𝑥 ∈ {NAN,+INFINITY,-INFINITY}
acosh
Returns inverse hyperbolic cosine of 𝑥.
- double x
- double
acoshf
Returns inverse hyperbolic cosine of 𝑥.
- float x
- float
acosl
Returns arc cosine of 𝑥.
- long double x
- long double
AcquireToken
Atomically decrements signed byte index if it's positive.
Multiple threads are able to call this method, to determine if enough
tokens exist to perform an operation. Return values greater than zero
mean a token was atomically acquired. Values less than, or equal zero
means the bucket is empty. There must exist 1 << c
signed bytes (or
buckets) in the b
array.
Since this design uses signed bytes, your returned number may be used to control how much burstiness is allowed. For example:
int t = AcquireToken(tok.b, ip, 22); if (t < 64) { if (t > 8) write(client, "HTTP/1.1 429 \r\n\r\n", 17); close(client); return; }Could be used to send rejections to clients that exceed their tokens, whereas clients who've grossly exceeded their tokens, could simply be dropped.
- _Atomic char* b
- is array of token buckets
- unsigned int x
- is ipv4 address
- int c
- is cidr
- int
aligned_alloc
Same as memalign(a, n) but requires IS2POW(a).
- unsigned long a
- unsigned long n
- number of bytes needed
- void*
- memory address, or NULL w/ errno
AppendResourceReport
Generates process resource usage report.
- char** b
- struct rusage* ru
- const char* nl
- struct rusage* ru
- void
appends
Appends string to buffer, e.g.
char *b = 0; appends(&b, "hello"); free(b);The resulting buffer is guaranteed to be NUL-terminated, i.e.
!b[appendz(b).i]
will be the case.
- char** b
- const char* s
- long
- bytes appended (always
strlen(s)
) or -1 ifENOMEM
asin
Returns arc sine of 𝑥.
- double x
- double
- value in range [-M_PI/2,M_PI/2]
- NAN if 𝑥 ∈ {NAN,+INFINITY,-INFINITY}
- NAN if 𝑥 ∉ [-1,1]
- NAN if 𝑥 ∈ {NAN,+INFINITY,-INFINITY}
asinhf
Returns inverse hyperbolic sine of 𝑥.
- float x
- float
asinl
Returns arc sine of 𝑥.
- long double x
- long double
asprintf
Formats string, allocating needed memory.
- char** strp
- const char* fmt
- ...
- const char* fmt
- int
- bytes written (excluding NUL) or -1 w/ errno
__assert_fail
Handles assert() failure.
- const char* expr
- const char* file
- int line
- const char* file
- void
atanh
Returns inverse hyperbolic tangent of 𝑥.
- double x
- double
atanhf
Returns inverse hyperbolic tangent of 𝑥.
- float x
- float
atanhl
Returns inverse hyperbolic tangent of 𝑥.
- long double x
- long double
atexit
Adds global destructor.
Destructors are called in reverse order. They won't be called if the program aborts or _exit() is called. Invocations of this function are usually generated by the C++ compiler.
- void(*)() f
- int
- 0 on success or nonzero if out of space
atoi
Turns string into int.
Decimal is the only radix supported. Leading whitespace (as specified
by the isspace() function) is skipped over. Unlike strtol(), the atoi
function has undefined behavior on error and it never changes errno
- const char* nptr
- is a non-null nul-terminated string
- int
- the decoded signed saturated integer
atol
Turns string into long.
Decimal is the only radix supported. Leading whitespace (as specified
by the isspace() function) is skipped over. Unlike strtol(), the atoi
function has undefined behavior on error and it never changes errno
- const char* nptr
- is a non-null nul-terminated string
- long
- the decoded signed saturated integer
basename
Returns pointer to last filename component in path, e.g.
path │ dirname() │ basename() ───────────────────────────────── 0 │ . │ . . │ . │ . .. │ . │ .. / │ / │ / usr │ . │ usr /usr/ │ / │ usr /usr/lib │ /usr │ libBoth / and \ are are considered valid component separators on all platforms. Trailing slashes are ignored. We don't grant special consideration to things like foo/., c:/, \\?\Volume, etc.
- char* path
- is UTF-8 and may be mutated, but not expanded in length
- char*
- pointer to path, or inside path, or to a special r/o string
bcmp
Tests inequality of first 𝑛 bytes of 𝑝 and 𝑞.
- void* a
- void* b
- unsigned long n
- void* b
- int
- 0 if a and b have equal contents, otherwise nonzero
bcopy
Moves memory the BSD way.
Please use memmove() instead. Note the order of arguments.
- void* src
- void* dest
- unsigned long n
- void* dest
- void
bind
Assigns local address and port number to socket, e.g.
struct sockaddr_in in = {AF_INET, htons(12345), {htonl(0x7f000001)}}; int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); bind(fd, (struct sockaddr *)&in, sizeof(in));On Windows, Cosmopolitan's implementation of bind() takes care of always setting the WIN32-specific
SO_EXCLUSIVEADDRUSE
option on
inet stream sockets in order to safeguard your servers from tests
- int fd
- is the file descriptor returned by socket()
- struct sa* addr
- is usually the binary-encoded ip:port on which to listen
- unsigned int addrsize
- is the byte-length of addr's true polymorphic form
- int
- 0 on success or -1 w/ errno
bsf
Returns position of first bit set.
ctz(𝑥) 31^clz(𝑥) clz(𝑥) uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥) 0x00000000 wut 32 0 wut 32 0x00000001 0 0 1 0 31 0x80000001 0 0 1 31 0 0x80000000 31 31 32 31 0 0x00000010 4 4 5 4 27 0x08000010 4 4 5 27 4 0x08000000 27 27 28 27 4 0xffffffff 0 0 1 31 0
- int x
- is a 32-bit integer
- int
- number in range 0..31 or undefined if 𝑥 is 0
bsfl
Returns position of first bit set.
ctz(𝑥) 31^clz(𝑥) clz(𝑥) uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥) 0x00000000 wut 32 0 wut 32 0x00000001 0 0 1 0 31 0x80000001 0 0 1 31 0 0x80000000 31 31 32 31 0 0x00000010 4 4 5 4 27 0x08000010 4 4 5 27 4 0x08000000 27 27 28 27 4 0xffffffff 0 0 1 31 0
- long x
- int
- number in range 0..63 or undefined if 𝑥 is 0
bsr
Returns binary logarithm of 𝑥.
ctz(𝑥) 31^clz(𝑥) clz(𝑥) uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥) 0x00000000 wut 32 0 wut 32 0x00000001 0 0 1 0 31 0x80000001 0 0 1 31 0 0x80000000 31 31 32 31 0 0x00000010 4 4 5 4 27 0x08000010 4 4 5 27 4 0x08000000 27 27 28 27 4 0xffffffff 0 0 1 31 0
- int x
- is a 32-bit integer
- int
- number in range 0..31 or undefined if 𝑥 is 0
bsrl
Returns binary logarithm of 𝑥.
ctz(𝑥) 31^clz(𝑥) clz(𝑥) uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥) 0x00000000 wut 32 0 wut 32 0x00000001 0 0 1 0 31 0x80000001 0 0 1 31 0 0x80000000 31 31 32 31 0 0x00000010 4 4 5 4 27 0x08000010 4 4 5 27 4 0x08000000 27 27 28 27 4 0xffffffff 0 0 1 31 0
- long x
- is a 64-bit integer
- int
- number in range 0..63 or undefined if 𝑥 is 0
bulk_free
Frees and clears (sets to NULL) each non-null pointer in given array.
This is twice as fast as freeing them one-by-one. If footers are used, pointers that have been allocated in different mspaces are not freed or cleared, and the count of all such pointers is returned. For large arrays of pointers with poor locality, it may be worthwhile to sort this array before calling bulk_free.
- void** p
- unsigned long n
- unsigned long
bzero
Sets memory to zero.
bzero n=0 661 picoseconds bzero n=1 661 ps/byte 1,476 mb/s bzero n=2 330 ps/byte 2,952 mb/s bzero n=3 220 ps/byte 4,428 mb/s bzero n=4 165 ps/byte 5,904 mb/s bzero n=7 94 ps/byte 10,333 mb/s bzero n=8 41 ps/byte 23,618 mb/s bzero n=15 44 ps/byte 22,142 mb/s bzero n=16 20 ps/byte 47,236 mb/s bzero n=31 21 ps/byte 45,760 mb/s bzero n=32 20 ps/byte 47,236 mb/s bzero n=63 10 ps/byte 92,997 mb/s bzero n=64 15 ps/byte 62,982 mb/s bzero n=127 15 ps/byte 62,490 mb/s bzero n=128 10 ps/byte 94,473 mb/s bzero n=255 14 ps/byte 68,439 mb/s bzero n=256 9 ps/byte 105 gb/s bzero n=511 15 ps/byte 62,859 mb/s bzero n=512 11 ps/byte 83,976 mb/s bzero n=1023 15 ps/byte 61,636 mb/s bzero n=1024 10 ps/byte 88,916 mb/s bzero n=2047 9 ps/byte 105 gb/s bzero n=2048 8 ps/byte 109 gb/s bzero n=4095 8 ps/byte 115 gb/s bzero n=4096 8 ps/byte 118 gb/s bzero n=8191 7 ps/byte 129 gb/s bzero n=8192 7 ps/byte 130 gb/s bzero n=16383 6 ps/byte 136 gb/s bzero n=16384 6 ps/byte 137 gb/s bzero n=32767 6 ps/byte 140 gb/s bzero n=32768 6 ps/byte 141 gb/s bzero n=65535 15 ps/byte 64,257 mb/s bzero n=65536 15 ps/byte 64,279 mb/s bzero n=131071 15 ps/byte 63,166 mb/s bzero n=131072 15 ps/byte 63,115 mb/s bzero n=262143 15 ps/byte 62,052 mb/s bzero n=262144 15 ps/byte 62,097 mb/s bzero n=524287 15 ps/byte 61,699 mb/s bzero n=524288 15 ps/byte 61,674 mb/s bzero n=1048575 16 ps/byte 60,179 mb/s bzero n=1048576 15 ps/byte 61,330 mb/s bzero n=2097151 15 ps/byte 61,071 mb/s bzero n=2097152 15 ps/byte 61,065 mb/s bzero n=4194303 16 ps/byte 60,942 mb/s bzero n=4194304 16 ps/byte 60,947 mb/s bzero n=8388607 16 ps/byte 60,872 mb/s bzero n=8388608 16 ps/byte 60,879 mb/s
- void* p
- is memory address
- unsigned long n
- is byte length
- void
- p
cachestat
Query the page cache statistics of a file.
- int fd
- The open file descriptor to retrieve statistics from.
- struct cachestat_range* cstat_range
- The byte range in
fd
to query. Whenlen > 0
, the range is[off..off + len]
. Whenlen
== 0, the range is fromoff
to the end offd
. - struct cachestat* cstat
- The structure where page cache statistics are stored.
- unsigned int flags
- Currently unused, and must be set to
0
.
- int
- 0 on success, or -1 w/ errno.
cstat_range
or cstat
points to invalid memory
flags
is nonzero
fd
is negative or not open
fd
refers to a hugetlbfs file
calloc
Allocates n * itemsize bytes, initialized to zero.
- unsigned long n
- is number of items
- unsigned long itemsize
- is size of each item
- void*
- rax is memory address, or NULL w/ errno
CategorizeIp
Classifies IP address.
- unsigned int x
- int
- integer e.g. kIpLoopback, kIpPrivate, etc.
cfgetispeed
Returns input baud rate.
- struct termios* t
- unsigned int
cfgetospeed
Returns output baud rate.
- struct termios* t
- unsigned int
cfsetispeed
Sets input baud rate.
- struct termios* t
- unsigned int speed
- can be
B0
,B50
,B38400
,B4000000
, etc.
- int
- 0 on success, or -1 w/ errno
speed
isn't valid
cfsetospeed
Sets output baud rate.
- struct termios* t
- unsigned int speed
- can be
B0
,B50
,B38400
,B4000000
, etc.
- int
- 0 on success, or -1 w/ errno
speed
isn't valid
cfsetspeed
Sets input and output baud rate.
- struct termios* t
- unsigned int speed
- can be
B0
,B50
,B38400
,B4000000
, etc.
- int
- 0 on success, or -1 w/ errno
speed
isn't valid
chmod
Changes permissions on file, e.g.:
CHECK_NE(-1, chmod("foo/bar.txt", 0644)); CHECK_NE(-1, chmod("o/default/program", 0755)); CHECK_NE(-1, chmod("privatefolder/", 0700));The esoteric bits generally available on System Five are:
CHECK_NE(-1, chmod("/opt/", 01000)); // sticky bit CHECK_NE(-1, chmod("/usr/bin/sudo", 04755)); // setuid bit CHECK_NE(-1, chmod("/usr/bin/wall", 02755)); // setgid bit
- const char* pathname
- must exist
- unsigned int mode
- contains octal flags (base 8)
- int
chomp
Mutates line to remove line-ending characters.
- char* line
- is NULL-propagating
- char*
chomp16
Mutates line to remove line-ending characters.
- unsigned short* line
- is NULL-propagating
- unsigned short*
chown
Changes owner and/or group of pathname.
- const char* pathname
- unsigned int uid
- is user id, or -1u to not change
- unsigned int gid
- is group id, or -1u to not change
- int
- 0 on success, or -1 w/ errno
chroot
Changes root directory.
Please consider using unveil() instead of chroot(). If you use this system call then consider using both chdir() and closefrom() before calling this function. Otherwise there's a small risk that fchdir() could be used to escape the chroot() environment. Cosmopolitan Libc focuses on static binaries which make chroot() infinitely easier to use since you don't need to construct an entire userspace each time however unveil() is still better to use on modern Linux and OpenBSD because it doesn't require root privileges.
- const char* path
- shall become the new root directory
- int
- 0 on success, or -1 w/ errno
path
path
exists as non-directory
path
length exceeds PATH_MAX
path
exists longer than NAME_MAX
path
is bad memory
path
doesn't exist
clearerr
Clears eof and error state indicators on stream.
- struct FILE* f
- is file object stream pointer
- void
clearerr_unlocked
Clears eof and error state indicators on stream.
- struct FILE* f
- is file object stream pointer
- void
__clk_tck
Returns system clock ticks per second.
The returned value is memoized. This function is intended to be
used via the CLK_TCK
macro wrapper.
The returned value is always greater than zero. It's usually 100 hertz which means each clock tick is 10 milliseconds long.
- int
clock
Returns sum of CPU time consumed by current process since birth.
This function provides a basic idea of how computationally expensive your program is, in terms of both the userspace and kernel processor resources it's hitherto consumed. Here's an example of how you might display this information:
printf("consumed %g seconds of cpu time\n", (double)clock() / CLOCKS_PER_SEC);This function offers at best microsecond accuracy on all supported platforms. Please note the reported values might be a bit chunkier depending on the kernel scheduler sampling interval see
CLK_TCK
.
- long
- units of CPU time consumed, where each unit's time length
should be
1./CLOCKS_PER_SEC
seconds; Cosmopolitan currently returns the unit count in microseconds, i.e.CLOCKS_PER_SEC
is hard-coded as 1000000. On failure this returns -1 / errno.
clock_getres
Returns granularity of clock.
- int clock
- struct timespec* ts
- int
- 0 on success, or -1 w/ errno
clock
isn't supported on this system
ts
points to bad memory
clock_gettime
Returns nanosecond time.
The clock
parameter may bo set to:
CLOCK_REALTIME
returns a wall clock timestamp represented in nanoseconds since the UNIX epoch (~1970). It'll count time in the suspend state. This clock is subject to being smeared by various adjustments made by NTP. These timestamps can have unpredictable discontinuous jumps when clock_settime() is used. Therefore this clock is the default clock for everything, even pthread condition variables. Cosmopoiltan guarantees this clock will never raiseEINVAL
and also guaranteesCLOCK_REALTIME == 0
will always be the case. On Windows this maps to GetSystemTimePreciseAsFileTime(). On platforms with vDSOs like Linux, Windows, and MacOS ARM64 this should take about 20 nanoseconds.CLOCK_MONOTONIC
returns a timestamp with an unspecified epoch, that should be when the system was powered on. These timestamps shouldn't go backwards. Timestamps shouldn't count time spent in the sleep, suspend, and hibernation states. These timestamps won't be impacted by clock_settime(). These timestamps may be impacted by frequency adjustments made by NTP. Cosmopoiltan guarantees this clock will never raiseEINVAL
. MacOS and BSDs use the word "uptime" to describe this clock. On Windows this maps to QueryUnbiasedInterruptTimePrecise().CLOCK_BOOTTIME
is a monotonic clock returning a timestamp with an unspecified epoch, that should be relative to when the host system was powered on. These timestamps shouldn't go backwards. Timestamps should also include time spent in a sleep, suspend, or hibernation state. These timestamps aren't impacted by clock_settime(), but they may be impacted by frequency adjustments made by NTP. This clock will raise anEINVAL
error on extremely old Linux distros like RHEL5. MacOS and BSDs use the word "monotonic" to describe this clock. On Windows this maps to QueryInterruptTimePrecise().CLOCK_MONOTONIC_RAW
returns a timestamp from an unspecified epoch. These timestamps don't count time spent in the sleep, suspend, and hibernation states. This clock is not impacted by clock_settime(). UnlikeCLOCK_MONOTONIC
this clock is guaranteed to not be impacted by frequency adjustments. Providing this level of assurances may make this clock 10x slower than the monotonic clock. Furthermore this clock may causeEINVAL
to be raised if running on a host system that doesn't provide those guarantees, e.g. OpenBSD and MacOS on AMD64.CLOCK_REALTIME_COARSE
is the same asCLOCK_REALTIME
except it'll go faster if the host OS provides a cheaper way to read the wall time. Please be warned that coarse can be really coarse. Rather than nano precision, you're looking atCLK_TCK
precision, which can lag as far as 30 milliseconds behind or possibly more. Cosmopolitan may fallback toCLOCK_REALTIME
if a faster less accurate clock isn't provided by the system. This clock will raise anEINVAL
error on extremely old Linux distros like RHEL5. On platforms with vDSOs like Linux, Windows, and MacOS ARM64 this should take about 5 nanoseconds.CLOCK_MONOTONIC_COARSE
is the same asCLOCK_MONOTONIC
except it'll go faster if the host OS provides a cheaper way to read the unbiased time. Please be warned that coarse can be really coarse. Rather than nano precision, you're looking atCLK_TCK
precision, which can lag as far as 30 milliseconds behind or possibly more. Cosmopolitan may fallback toCLOCK_REALTIME
if a faster less accurate clock isn't provided by the system. This clock will raise anEINVAL
error on extremely old Linux distros like RHEL5. On platforms with vDSOs like Linux, Windows, and MacOS ARM64 this should take about 5 nanoseconds.CLOCK_PROCESS_CPUTIME_ID
returns the amount of time this process was actively scheduled. This is similar to getrusage() and clock().CLOCK_THREAD_CPUTIME_ID
returns the amount of time this thread was actively scheduled. This is similar to getrusage() and clock().
- int clock
- struct memory* ts
- is where the result is stored (or null to do clock check)
- int
- 0 on success, or -1 w/ errno
ts
points to invalid memory
clock
isn't supported on this system
clock
wasn't found
clock_nanosleep
Sleeps for particular amount of time.
Here's how you could sleep for one second:
clock_nanosleep(0, 0, &(struct timespec){1}, 0);Your sleep will be interrupted automatically if you do something like press ctrl-c during the wait. That's an
EINTR
error and it lets you
immediately react to status changes. This is always the case, even if
you're using SA_RESTART
since this is a @norestart
system call.
void OnCtrlC(int sig) {} // EINTR only happens after delivery signal(SIGINT, OnCtrlC); // do delivery rather than kill proc printf("save me from sleeping forever by pressing ctrl-c\n"); clock_nanosleep(0, 0, &(struct timespec){INT_MAX}, 0); printf("you're my hero\n");If you want to perform an uninterruptible sleep without having to use sigprocmask() to block all signals then this function provides a good solution to that problem. For example:
struct timespec rel, now, abs; clock_gettime(CLOCK_REALTIME, &now); rel = timespec_frommillis(100); abs = timespec_add(now, rel); while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &abs, 0));will accurately spin on
EINTR
errors. That way you're not impeding
signal delivery and you're not loosing precision on the wait timeout.
This function has first-class support on Linux, FreeBSD, and NetBSD;
on OpenBSD it's good; on XNU it's bad; and on Windows it's ugly.
- int clock
- may be
CLOCK_REALTIME
CLOCK_MONOTONIC
CLOCK_REALTIME_COARSE
but is likely to sleep negative timeCLOCK_MONTONIC_COARSE
but is likely to sleep negative time
- int flags
- can be 0 for relative and
TIMER_ABSTIME
for absolute - struct timespec* req
- can be a relative or absolute time, depending on
flags
- struct timespec* rem
- shall be updated with the remainder of unslept time when
(1) it's non-null; (2)
flags
is 0; and (3) -1 w/EINTR
is returned; if this function returns 0 thenrem
is undefined; if flags isTIMER_ABSTIME
thenrem
is ignored
- int
- 0 on success, or errno on error
clock
is known but we can't use it here
req
or null or bad memory was passed
clock
is unknown to current platform
flags
has an unrecognized value
req->tv_nsec ∉ [0,1000000000)
close_range
Closes inclusive range of file descriptors, e.g.
// close all non-stdio file descriptors if (close_range(3, -1, 0) == -1) { for (int i = 3; i < 256; ++i) { close(i); } }The following flags are available:
CLOSE_RANGE_UNSHARE
(Linux-only)CLOSE_RANGE_CLOEXEC
(Linux-only)
- unsigned int first
- unsigned int last
- unsigned int flags
- unsigned int last
- int
- 0 on success, or -1 w/ errno
closefrom
Closes extra file descriptors, e.g.
if (closefrom(3)) for (int i = 3; i < 256; ++i) close(i);
- int first
- int
- 0 on success, or -1 w/ errno
first
is negative
first
is greater than highest fd
CloseSymbolTable
Frees symbol table.
- struct SymbolTable** table
- int
- 0 on success or -1 on system error
commandv
Resolves full pathname of executable.
- const char* name
- char* pathbuf
- unsigned long pathbufsz
- char* pathbuf
- char*
- execve()'able path, or NULL w/ errno
commandvenv
Finds full executable path in overridable way.
This is a higher level version of the commandv() function. Programs that spawn subprocesses can use this function to determine the path at startup. Here's an example how you could use it:
if ((strace = commandvenv("STRACE", "strace"))) { strace = strdup(strace); } else { fprintf(stderr, "error: please install strace\n"); exit(1); }
- const char* var
- is environment variable which may be used to override PATH search, and it can force a NULL result if it's empty
- const char* cmd
- is name of program, which is returned asap if it's an absolute path
- const char*
- pointer to exe path string, or NULL if it couldn't be found or the environment variable was empty; noting that the caller should copy this string before saving it
connect
Connects socket to remote end.
When fd
is in O_NONBLOCK
mode, this raises EINPROGRESS
. To wait
for establishment poll() function may be called using POLLOUT
. Then
SO_ERROR
may be used to check for errors.
Connectionless sockets, e.g. UDP, can be connected too. The benefit is not needing to specify the remote address on each send. It also means getsockname() can be called to retrieve routing details.
On Linux, your SO_SNDTIMEO
will timeout connect(). Other OSes (i.e.
Windows, MacOS, and BSDs) do not support this and will block forever.
On Windows, when this function blocks, there may be a 10 millisecond delay on the handling of signals or thread cancelation.
- int fd
- struct sa* addr
- unsigned int addrsize
- struct sa* addr
- int
- 0 on success or -1 w/ errno
O_NONBLOCK
and connecting process initiated
O_NONBLOCK
connecting already in flight
copy_file_range
Transfers data between files.
If this system call is available (Linux c. 2018 or FreeBSD c. 2021) and the file system supports it (e.g. ext4) and the source and dest files are on the same file system, then this system call shall make copies go about 2x faster.
This implementation requires Linux 5.9+ even though the system call was introduced in Linux 4.5. That's to ensure ENOSYS works reliably due to a faulty backport, that happened in RHEL7. FreeBSD detection on the other hand will work fine.
- int infd
- is source file, which should be on same file system
- long* opt_in_out_inoffset
- may be specified for pread() behavior
- int outfd
- should be a writable file, but not
O_APPEND
- long* opt_in_out_outoffset
- may be specified for pwrite() behavior
- unsigned long uptobytes
- is maximum number of bytes to transfer
- unsigned int flags
- is reserved for future use and must be zero
- long
- number of bytes transferred, or -1 w/ errno
infd
or outfd
aren't open files or append-only
fdout
refers to an immutable file on Linux
flags
is non-zero
setrlimit(RLIMIT_FSIZE)
is exceeded
cosf
Returns cosine of y.
This is a fast cosf implementation. The worst-case ULP is 0.5607, and the maximum relative error is 0.5303 * 2^-23. A single-step range reduction is used for small values. Large inputs have their range reduced using fast integer arithmetic.
- float y
- float
cosh
Returns hyperbolic cosine of 𝑥.
cosh(x) = (exp(x) + 1/exp(x))/2 = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x) = 1 + x*x/2 + o(x^4)
- double x
- double
coshf
Returns hyperbolic cosine of 𝑥.
cosh(x) = (exp(x) + 1/exp(x))/2 = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x) = 1 + x*x/2 + o(x^4)
- float x
- float
cosmo
Cosmopolitan runtime.
- edi
- is argc
- rsi
- is argv
- rdx
- is environ
- rcx
- is auxv
cosmo_once
Ensures initialization function is called exactly once.
This is the same as pthread_once
except that it always uses a tiny
spinlock implementation and won't make any system calls. It's needed
since this function is an upstream dependency of both pthread_once()
and nsync_once(). Most code should favor calling those functions.
- _Atomic unsigned int* once
- void(*)() init
- int
- 0 on success, or errno on error
cosmoaudio_describe_open_options
- char* buf
- int n
- struct CosmoAudioOpenOptions* options
- int n
- const char*
cosmoaudio_describe_poll_frames
- char* buf
- int n
- int* in_out_frames
- int n
- const char*
cosmoaudio_describe_status
- char* buf
- int n
- int status
- int n
- const char*
_countbits
Returns population count of array.
- void* a
- is byte sequence
- unsigned long n
- unsigned long
- number of bits set to one
CountTokens
Returns current number of tokens in bucket.
- _Atomic char* b
- is array of token buckets
- unsigned int x
- is ipv4 address
- int c
- is cidr
- int
__cpu_march
Returns microarchitecture name, e.g.
puts(__cpu_march(__cpu_model.__cpu_subtype));
- unsigned int subtype
- const char*
crc32c
Computes 32-bit Castagnoli Cyclic Redundancy Check.
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 0b00011110110111000110111101000001
- unsigned int init
- is the initial hash value
- void* data
- points to the data
- unsigned long size
- is the byte size of data
- unsigned int
- eax is the new hash value
creat
Creates file.
This is equivalent to saying:
int fd = openat(AT_FDCWD, file, O_CREAT | O_WRONLY | O_TRUNC, mode);
- const char* file
- specifies filesystem path to create
- unsigned int mode
- is octal bits, e.g. 0644 usually
- int
- file descriptor, or -1 w/ errno
critbit0_allprefixed
Invokes callback for all items with prefix.
- struct critbit0* t
- const char* prefix
- long(*)() callback
- void* arg
- const char* prefix
- long
- 0 unless iteration was halted by CALLBACK returning nonzero, in which case that value is returned
critbit0_clear
Removes all items from 𝑡.
- struct critbit0* t
- tree
- void
critbit0_contains
Returns non-zero iff 𝑢 ∈ 𝑡.
- struct critbit0* t
- tree
- const char* u
- NUL-terminated string
- _Bool
critbit0_delete
Removes 𝑢 from 𝑡.
- struct critbit0* t
- tree
- const char* u
- NUL-terminated string
- _Bool
- true if 𝑡 was mutated
critbit0_emplace
Inserts 𝑢 into 𝑡 without copying.
- struct critbit0* t
- void* u
- unsigned long ulen
- void* u
- int
- 1 if 𝑡 was mutated, 0 if present, or -1 w/ errno
critbit0_get
Returns first item in 𝑡 with prefix 𝑢.
- struct critbit0* t
- tree
- const char* u
- NUL-terminated string
- char*
- item or NULL if not found
critbit0_insert
Inserts 𝑢 into 𝑡.
- struct critbit0* t
- tree
- const char* u
- NUL-terminated string
- int
- 1 if 𝑡 was mutated, 0 if present, or -1 w/ errno
crypt
Encrypts password the old fashioned way.
The method of encryption depends on the first three chars of salt:
$1$
is MD5$2$
is Blowfish$5$
is SHA-256$6$
is SHA-512- Otherwise DES
- const char* key
- const char* salt
- char*
- static memory with encrypted password
crypt_r
Encrypts password the old fashioned way.
The method of encryption depends on the first three chars of salt:
$1$
is MD5$2$
is Blowfish$5$
is SHA-256$6$
is SHA-512- Otherwise DES
- const char* key
- const char* salt
- struct crypt_data* data
- const char* salt
- char*
- static memory with encrypted password
ctermid
Generates path of controlling terminal.
This function always returns /dev/tty since that's supported by all supported platforms, and polyfilled on Windows.
- char* s
- may optionally specify an outut buffer L_ctermid in size
- char*
- pointer to
s
(or image memory ifs
was null) which contains path of controlling terminal, or empty string if if this program is a win32 app running in gui mode
__cxa_atexit
Adds global destructor.
Destructors are called in reverse order. They won't be called if the program aborts or _exit() is called. Invocations of this function are usually generated by the C++ compiler. Behavior is limitless if some other module has linked calloc().
- void* fp
- is void(*)(T)
- void* arg
- is passed to callback
- void* pred
- can be non-null for things like dso modules
- int
- 0 on success or nonzero w/ errno
__cxa_finalize
Triggers global destructors.
They're called in LIFO order. If a destructor adds more destructors, then those destructors will be called immediately following, before iteration continues.
- void* pred
- can be null to match all
- void
__cxa_printexits
Prints global destructors.
- struct FILE* f
- void* pred
- can be null to match all
- void
_Cz_adler32
Updates running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is Z_NULL, this function returns the required initial value for the checksum.
- unsigned long
_Cz_adler32_combine
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note that the off_t type (like off_t) is a signed integer. If len2 is negative, the result has no meaning or utility.
- unsigned long
_Cz_compress
Compresses source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed data. compress() is equivalent to compress2() with a level parameter of Z_DEFAULT_COMPRESSION.
- int
- Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer.
_Cz_compress2
Compresses source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed data.
- int
- Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid.
_Cz_compressBound
Returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer.
- unsigned long
_Cz_crc32
Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. If buf is Z_NULL, this function returns the required initial value for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application.
Usage example:
uLong crc = crc32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error();
- unsigned long
_Cz_crc32_combine
Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and len2.
- unsigned long
_Cz_deflate
deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush.
The detailed semantics are as follows. deflate performs one or both of the following actions:
- Compress more input starting at next_in and update next_in and
- Generate more output starting at next_out and update next_out and
Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. See deflatePending(), which can be used if desired to determine whether or not there is more ouput in that case.
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to decide how much data to accumulate before producing output, in order to maximize compression.
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. This completes the current deflate block and follows it with an empty stored block that is three bits plus filler bits to the next byte, followed by four bytes (00 00 ff ff).
If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the output buffer, but the output is not aligned to a byte boundary. All of the input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. This completes the current deflate block and follows it with an empty fixed codes block that is 10 bits long. This assures that enough bytes are output in order for the decompressor to finish the block before the empty fixed codes block.
If flush is set to Z_BLOCK, a deflate block is completed and emitted, as for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to seven bits of the current block are held to be written as the next byte after the next deflate block is completed. In this case, the decompressor may not be provided enough bits at this point in order to complete decompression of the data provided so far to the compressor. It may need to wait for the next block to be emitted. This is for advanced applications that need to control the emission of deflate blocks.
If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade compression.
If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return.
If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd.
Z_FINISH can be used in the first deflate call after deflateInit if all the compression is to be done in a single step. In order to complete in one call, avail_out must be at least the value returned by deflateBound (see below). Then deflate is guaranteed to return Z_STREAM_END. If not enough output space is provided, deflate will not return Z_STREAM_END, and it must be called again as described above.
deflate() sets strm->adler to the Adler-32 checksum of all input read so far (that is, total_in bytes). If a gzip stream is being generated, then strm->adler will be the CRC-32 checksum of the input read so far. (See deflateInit2 below.)
deflate() may update strm->data_type if it can make a good guess about the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner.
- int
- Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was Z_NULL or the state was inadvertently written over by the application), or Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again with more input and more output space to continue compressing.
_Cz_deflateBound
deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(), and after deflateSetHeader(), if used. This would be used to allocate an output buffer for deflation in a single pass, and so would be called before deflate(). If that first deflate() call is provided the sourceLen input bytes, an output buffer allocated to the size returned by deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed to return Z_STREAM_END. Note that it is possible for the compressed size to be larger than the value returned by deflateBound() if flush options other than Z_FINISH or Z_NO_FLUSH are used.
- unsigned long
_Cz_deflateCopy
Sets destination stream as a complete copy of the source stream.
This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory.
- int
- Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being Z_NULL). msg is left unchanged in both source and destination.
_Cz_deflateEnd
All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output.
- int
- Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated).
_Cz_deflateGetDictionary
Returns the sliding dictionary being maintained by deflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied to dictionary. dictionary must have enough space, where 32768 bytes is always enough. If deflateGetDictionary() is called with dictionary equal to Z_NULL, then only the dictionary length is returned, and nothing is copied. Similary, if dictLength is Z_NULL, then it is not set.
deflateGetDictionary() may return a length less than the window size, even when more than the window size in input has been provided. It may return up to 258 bytes less in that case, due to how zlib's implementation of deflate manages the sliding window and lookahead for matches, where matches can be up to 258 bytes long. If the application needs the last window-size bytes of input, then that would need to be saved by the application outside of zlib.
- int
- Z_OK on success, or Z_STREAM_ERROR if the stream state is inconsistent.
_Cz_deflateInit
Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions.
The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6).
- int
- Z_OK if success, Z_MEM_ERROR if there was not enough memory, or Z_STREAM_ERROR if level is not a valid compression level. msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate().
_Cz_deflateInit2
This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller.
The method parameter is the compression method. It must be Z_DEFLATED in this version of the library.
The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead.
For the current implementation of deflate(), a windowBits value of 8 (a window size of 256 bytes) is not supported. As a result, a request for 8 will result in 9 (a 512-byte window). In that case, providing 8 to inflateInit2() will result in an error when the zlib header with 9 is checked against the initialization of inflate(). The remedy is to not use 8 with deflateInit2() with this initialization, or at least in that case use 9 with inflateInit2().
windowBits can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size. deflate() will then generate raw deflate data with no zlib header or trailer, and will not compute a check value.
windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no header crc, and the operating system will be set to the appropriate value, if the operating system was determined at compile time. If a gzip stream is being written, strm->adler is a CRC-32 instead of an Adler-32.
For raw deflate or gzip encoding, a request for a 256-byte window is rejected as invalid, since only the zlib header provides a means of transmitting the window size to the decompressor.
The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel.
The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no string match), or Z_RLE to limit match distances to one (run-length encoding). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications.
- int
- Z_OK if success, Z_MEM_ERROR if there was not enough memory, or Z_STREAM_ERROR if any parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate().
_Cz_deflateParams
Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2(). This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression approach (which is a function of the level) or the strategy is changed, and if any input has been consumed in a previous deflate() call, then the input available so far is compressed with the old level and strategy using deflate(strm, Z_BLOCK). There are three approaches for the compression levels 0, 1..3, and 4..9 respectively. The new level and strategy will take effect at the next call of deflate().
If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does not have enough output space to complete, then the parameter change will not take effect. In this case, deflateParams() can be called again with the same parameters and more output space to try again.
In order to assure a change in the parameters on the first try, the deflate stream should be flushed using deflate() with Z_BLOCK or other flush request until strm.avail_out is not zero, before calling deflateParams(). Then no more input data should be provided before the deflateParams() call. If this is done, the old level and strategy will be applied to the data compressed before deflateParams(), and the new level and strategy will be applied to the the data compressed after deflateParams().
deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if there was not enough output space to complete the compression of the available input data before a change in the strategy or approach. Note that in the case of a Z_BUF_ERROR, the parameters are not changed. A return value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be retried with more output space.
- int
_Cz_deflatePending
deflatePending() returns the number of bytes and bits of output that have been generated, but not yet provided in the available output. The bytes not provided would be due to the available output space having being consumed. The number of bits of output not provided are between 0 and 7, where they await more bits to join them in order to fill out a full byte. If pending or bits are Z_NULL, then those values are not set.
- int
- Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent.
_Cz_deflatePrime
deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits leftover from a previous deflate stream when appending to it. As such, this function can only be used for raw deflate, and must be used before the first deflate() call after a deflateInit2() or deflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the output.
- int
- Z_OK if success, Z_BUF_ERROR if there was not enough room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the source stream state was inconsistent.
_Cz_deflateReset
This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate the internal compression state. The stream will leave the compression level and any other attributes that may have been set unchanged.
deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL).
- int
_Cz_deflateSetDictionary
Initializes the compression dictionary from the given byte sequence without producing any compressed output. When using the zlib format, this function must be called immediately after deflateInit, deflateInit2 or deflateReset, and before any call of deflate. When doing raw deflate, this function must be called either before any call of deflate, or immediately after the completion of a deflate block, i.e. after all input has been consumed and all output has been delivered when using any of the flush options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary).
The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary.
Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size provided in deflateInit or deflateInit2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. In addition, the current implementation of deflate will use at most the window size minus 262 bytes of the provided dictionary.
Upon return of this function, strm->adler is set to the Adler-32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The Adler-32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the Adler-32 value is not computed and strm->adler is not set.
- int
- Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent (for example if deflate has already been called for this stream or if not at a block boundary for raw deflate). deflateSetDictionary does not perform any compression: this will be done by deflate().
_Cz_deflateSetHeader
Provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called after deflateInit2() or deflateReset() and before the first call of deflate(). The text, time, os, extra field, name, and comment information in the provided gz_header structure are written to the gzip header (xflag is ignored -- the extra flags are set according to the compression level). The caller must assure that, if not Z_NULL, name and comment are terminated with a zero byte, and that if extra is not Z_NULL, that extra_len bytes are available there. If hcrc is true, a gzip header crc is included. Note that the current versions of the command-line version of gzip (up through version 1.3.x) do not support header crc's, and will report that it is a "multi-part gzip file" and give up.
If deflateSetHeader is not used, the default gzip header has text false, the time set to zero, and os set to 255, with no extra, name, or comment fields. The gzip header is returned to the default state by deflateReset().
deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent.
- int
_Cz_deflateTune
Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for searching for the best matching string, and even then only by the most fanatic optimizer trying to squeeze out the last compressed bit for their specific input data. Read the deflate.c source code for the meaning of the max_lazy, good_length, nice_length, and max_chain parameters.
deflateTune() can be called after deflateInit() or deflateInit2(), and returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
- int
_Cz_gzbuffer
Sets internal buffer size used by this library's functions. The default buffer size is 8192 bytes. This function must be called after gzopen() or gzdopen(), and before any other calls that read or write the file. The buffer memory allocation is always deferred to the first read or write. Three times that size in buffer space is allocated. A larger buffer size of, for example, 64K or 128K bytes will noticeably increase the speed of decompression (reading).
The new buffer size also affects the maximum length for gzprintf().
- int
- Z_OK on success, or -1 on failure, such as being called too late.
_Cz_gzclearerr
Clears the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently.
- void
_Cz_gzclose
Flushes all pending output if necessary, closes the compressed file and deallocates the (de)compression state. Note that once file is closed, you cannot call gzerror with file, since its structures have been deallocated. gzclose must not be called more than once on the same file, just as free must not be called more than once on the same allocation.
- int
- Z_STREAM_ERROR if file is not valid, Z_ERRNO on a file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the last read ended in the middle of a gzip stream, or Z_OK on success.
_Cz_gzclose_r
Same as gzclose(), but gzclose_r() is only for use when reading, and gzclose_w() is only for use when writing or appending. The advantage to using these instead of gzclose() is that they avoid linking in zlib compression or decompression code that is not used when only reading or only writing respectively. If gzclose() is used, then both compression and decompression code will be included the application when linking to a static zlib library.
- int
_Cz_gzdirect
Returns true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed.
If the input file is empty, gzdirect() will return true, since the input does not contain a gzip stream.
If gzdirect() is used immediately after gzopen() or gzdopen() it will cause buffers to be allocated to allow reading the file to determine if it is a gzip file. Therefore if gzbuffer() is used, it should be called before gzdirect().
When writing, gzdirect() returns true (1) if transparent writing was requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: gzdirect() is not needed when writing. Transparent writing must be explicitly requested, so the application already knows the answer. When linking statically, using gzdirect() will include all of the zlib code for gzip file reading and decompression, which may not be desired.)
- int
_Cz_gzdopen
Associates gzFile with the file descriptor.
File descriptors are obtained from calls like open, dup, creat, pipe or fileno (if the file has been previously opened with fopen). The mode parameter is as in gzopen.
The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, mode);. The duplicated descriptor should be saved to avoid a leak, since gzdopen does not close fd if it fails. If you are using fileno() to get the file descriptor from a FILE *, then you will have to use dup() to avoid double-close()ing the file descriptor. Both gzclose() and fclose() will close the associated file descriptor, so they need to have different file descriptors.
- struct gzFile_s*
- Z_OK if there was insufficient memory to allocate the gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not provided, or '+' was provided), or if fd is -1. The file descriptor is not used until the next gz* read, write, seek, or close operation, so gzdopen will not detect if fd is invalid (unless fd is -1).
_Cz_gzeof
Returns true (1) if the end-of-file indicator has been set while reading, false (0) otherwise. Note that the end-of-file indicator is set only if the read tried to go past the end of the input, but came up short. Therefore, just like feof(), gzeof() may return false even if there is no more data to read, in the event that the last read request was for the exact number of bytes remaining in the input file. This will happen if the input file size is an exact multiple of the buffer size.
If gzeof() returns true, then the read functions will return no more data, unless the end-of-file indicator is reset by gzclearerr() and the input file has grown since the previous end of file was detected.
- int
_Cz_gzerror
Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code.
The application must not modify the returned string. Future calls to this function may invalidate the previously returned string. If file is closed, then the string previously returned by gzerror will no longer be available.
gzerror() should be used to distinguish errors from end-of-file for those functions above that do not distinguish those cases in their return values.
- const char*
_Cz_gzflush
Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush is only permitted when writing.
If the flush parameter is Z_FINISH, the remaining data is written and the gzip stream is completed in the output. If gzwrite() is called again, a new gzip stream will be started in the output. gzread() is able to read such concatenated gzip streams.
gzflush should be called only when strictly necessary because it will degrade compression if called too often.
- int
_Cz_gzfread
Read up to nitems items of size size from file to buf, otherwise operating as gzread() does. This duplicates the interface of stdio's fread(), with size_t request and return types. If the library defines size_t, then size_t is identical to size_t. If not, then size_t is an unsigned integer type that can contain a pointer.
gzfread() returns the number of full items read of size size, or zero if the end of the file was reached and a full item could not be read, or if there was an error. gzerror() must be consulted if zero is returned in order to determine if there was an error. If the multiplication of size and nitems overflows, i.e. the product does not fit in a size_t, then nothing is read, zero is returned, and the error state is set to Z_STREAM_ERROR.
In the event that the end of file is reached and only a partial item is available at the end, i.e. the remaining uncompressed data length is not a multiple of size, then the final partial item is nevetheless read into buf and the end-of-file flag is set. The length of the partial item read is not provided, but could be inferred from the result of gztell(). This behavior is the same as the behavior of fread() implementations in common libraries, but it prevents the direct use of gzfread() to read a concurrently written file, reseting and retrying on end-of-file, when size is not 1.
- unsigned long
_Cz_gzfwrite
Writes nitems items of size size from buf to file, duplicating the interface of stdio's fwrite(), with size_t request and return types. If the library defines size_t, then size_t is identical to size_t. If not, then size_t is an unsigned integer type that can contain a pointer.
gzfwrite() returns the number of full items written of size size, or zero if there was an error. If the multiplication of size and nitems overflows, i.e. the product does not fit in a size_t, then nothing is written, zero is returned, and the error state is set to Z_STREAM_ERROR.
- unsigned long
_Cz_gzgetc
Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. This is implemented as a macro for speed. As such, it does not do all of the checking the other functions do. I.e. it does not check to see if file is NULL, nor whether the structure file points to has been clobbered or not.
- int
_Cz_gzgets
Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. If any characters are read or if len == 1, the string is terminated with a null character. If no characters are read due to an end-of-file or len < 1, then the buffer is left untouched.
- char*
- buf which is a null-terminated string, or it returns NULL for end-of-file or in case of error. If there was an error, the contents at buf are indeterminate.
_Cz_gzoffset
Returns current offset in the file being read or written. This offset includes the count of bytes that precede the gzip stream, for example when appending or when using gzdopen() for reading. When reading, the offset does not include as yet unused buffered input. This information can be used for a progress indicator. On error, gzoffset() returns -1.
- long
_Cz_gzopen
Opens a gzip (.gz) file for reading or writing.
The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression as in "wb9F". (See the description of deflateInit2 for more information about the strategy parameter.) 'T' will request transparent writing or appending with no compression and not using the gzip format.
"a" can be used instead of "w" to request that the gzip stream that will be written be appended to the file. "+" will result in an error, since reading and writing to the same gzip file is not supported. The addition of "x" when writing will create the file exclusively, which fails if the file already exists. On systems that support it, the addition of "e" when reading or writing will set the flag to close the file on an execve() call.
These functions, as well as gzip, will read and decode a sequence of gzip streams in a file. The append function of gzopen() can be used to create such a file. (Also see gzflush() for another way to do this.) When appending, gzopen does not test whether the file begins with a gzip stream, nor does it look for the end of the gzip streams to begin appending. gzopen will simply append a gzip stream to the existing file.
gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. When reading, this will be detected automatically by looking for the magic two- byte gzip header.
- struct gzFile_s*
- Z_OK if the file could not be opened, if there was insufficient memory to allocate the gzFile state, or if an invalid mode was specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). errno can be checked to determine if the reason gzopen failed was that the file could not be opened.
_Cz_gzprintf
Converts, formats, and writes the arguments to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written, or a negative zlib error code in case of error. The number of uncompressed bytes written is limited to 8191, or one less than the buffer size given to gzbuffer(). The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will return an error (0) with nothing written. In this case, there may also be a buffer overflow with unpredictable consequences, which is possible only if zlib was compiled with the insecure functions sprintf() or vsprintf() because the secure snprintf() or vsnprintf() functions were not available. This can be determined using zlibCompileFlags().
- ...
- int
_Cz_gzputc
Writes character converted to an unsigned char into compressed file.
- int
- value that was written, or -1 on error
_Cz_gzputs
Writes the given null-terminated string to the compressed file, excluding the terminating null character.
- int
- Z_OK number of characters written, or -1 in case of error.
_Cz_gzread
Reads given number of uncompressed bytes from the compressed file. If the input file is not in gzip format, gzread copies the given number of bytes into the buffer directly from the file.
After reaching the end of a gzip stream in the input, gzread will continue to read, looking for another gzip stream. Any number of gzip streams may be concatenated in the input file, and will all be decompressed by gzread(). If something other than a gzip stream is encountered after a gzip stream, that remaining trailing garbage is ignored (and no error is returned).
gzread can be used to read a gzip file that is being concurrently written. Upon reaching the end of the input, gzread will return with the available data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then gzclearerr can be used to clear the end of file indicator in order to permit gzread to be tried again. Z_OK indicates that a gzip stream was completed on the last gzread. Z_BUF_ERROR indicates that the input file ended in the middle of a gzip stream. Note that gzread does not return -1 in the event of an incomplete gzip stream. This error is deferred until gzclose(), which will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip stream. Alternatively, gzerror can be used before gzclose to detect this case.
- int
- Z_OK number of uncompressed bytes actually read, less than len for end of file, or -1 for error. If len is too large to fit in an int, then nothing is read, -1 is returned, and the error state is set to Z_STREAM_ERROR.
_Cz_gzrewind
Rewinds file.
This function is supported only for reading.
- int
_Cz_gzseek
Sets starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported.
If the file is opened for reading, this function is emulated but can be extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position.
- long
- resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position.
_Cz_gzsetparams
Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. Previously provided data is flushed before the parameter change.
- int
- Z_OK if success, Z_STREAM_ERROR if the file was not opened for writing, Z_ERRNO if there is an error writing the flushed data, or Z_MEM_ERROR if there is a memory allocation error.
_Cz_gztell
Returns starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream, and is zero when starting, even if appending or reading a gzip stream from the middle of a file using gzdopen().
- long
_Cz_gzungetc
Pushes one character back onto the stream to be read as the first character on the next read. At least one character of push-back is allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will fail if c is -1, and may fail if a character has been pushed but not read yet. If gzungetc is used immediately after gzopen or gzdopen, at least the output buffer size of pushed characters is allowed. (See gzbuffer above.) The pushed character will be discarded if the stream is repositioned with gzseek() or gzrewind().
- int
_Cz_gzwrite
Writes given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes written or 0 in case of error.
- int
_Cz_inflate
inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush.
The detailed semantics are as follows. inflate performs one or both of the following actions:
- Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), then next_in and avail_in are updated accordingly, and processing will resume at this point for the next call of inflate().
- Generate more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter).
The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much output as possible to the output buffer. Z_BLOCK requests that inflate() stop if and when it gets to the next deflate block boundary. When decoding the zlib or gzip format, this will cause inflate() to return immediately after the header and before the first block. When doing a raw inflate, inflate() will go ahead and process the first block, and will return when it gets to the end of that block, or when it runs out of data.
The Z_BLOCK option assists in appending to or combining deflate streams. To assist in this, on return inflate() always sets strm->data_type to the number of unused bits in the last byte taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or decoding the complete header up to just before the first byte of the deflate stream. The end-of-block will not be indicated until all of the uncompressed data from that block has been written to strm->next_out. The number of unused bits may in general be greater than seven, except when bit 7 of data_type is set, in which case the number of unused bits will be less than eight. data_type is set as noted here every time inflate() returns for all flush options, and so can be used to determine the amount of currently consumed input in bits.
The Z_TREES option behaves as Z_BLOCK does, but it also returns when the end of each deflate block header is reached, before any actual data in that block is decoded. This allows the caller to determine the length of the deflate block header for later use in random access within a deflate block. 256 is added to the value of strm->data_type when inflate() returns immediately after reaching the end of the deflate block header.
inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all of the uncompressed data for the operation to complete. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The use of Z_FINISH is not required to perform an inflation in one step. However it may be used to inform inflate that a faster approach can be used for the single inflate() call. Z_FINISH also informs inflate to not maintain a sliding window if the stream completes, which reduces inflate's memory footprint. If the stream does not complete, either because not all of the stream is provided or not enough output space is provided, then a sliding window will be allocated and inflate() can be called again to continue the operation as if Z_NO_FLUSH had been used.
In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the first call. So the effects of the flush parameter in this implementation are on the return value of inflate() as noted below, when inflate() returns early when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of memory for a sliding window when Z_FINISH is used.
If a preset dictionary is needed after this call (see inflateSetDictionary below), inflate sets strm->adler to the Adler-32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the Adler-32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed Adler-32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct.
inflate() can decompress and check either zlib-wrapped or gzip-wrapped deflate data. The header type is detected automatically, if requested when initializing with inflateInit2(). Any information contained in the gzip header is not retained unless inflateGetHeader() is used. When processing gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output produced so far. The CRC-32 is checked against the gzip trailer, as is the uncompressed length, modulo 2^32.
- int
- Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check value, in which case strm->msg points to a string with a more specific error), Z_STREAM_ERROR if the stream structure was inconsistent (for example next_in or next_out was Z_NULL, or the state was inadvertently written over by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress was possible or if there was not enough room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing. If Z_DATA_ERROR is returned, the application may then call inflateSync() to look for a good compression block if a partial recovery of the data is to be attempted.
_Cz_inflateBack
inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is potentially more efficient than inflate() for file i/o applications, in that it avoids copying between the output and the sliding window by simply making the window itself the output buffer. inflate() can be faster on modern CPUs when used with large buffers. inflateBack() trusts the application to not change the output buffer passed by the output function, at least until inflateBack() returns.
inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. inflateBack() may then be used multiple times to inflate a complete, raw deflate stream with each call. inflateBackEnd() is then called to free the allocated state.
A raw deflate stream is one with no zlib or gzip header or trailer. This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the header and process the trailer on its own, hence this routine expects only the raw deflate stream to decompress. This is different from the default behavior of inflate(), which expects a zlib header and trailer around the deflate stream.
inflateBack() uses two subroutines supplied by the caller that are then called by inflateBack() for input and output. inflateBack() calls those routines until it reads a complete deflate stream and writes out all of the uncompressed data, or until it encounters an error. The function's parameters and return types are defined above in the in_func and out_func typedefs. inflateBack() will call in(in_desc, &buf) which should return the number of bytes of provided input, and a pointer to that input in buf. If there is no input available, in() must return zero -- buf is ignored in that case -- and inflateBack() will return a buffer error. inflateBack() will call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() should return zero on success, or non-zero on failure. If out() returns non-zero, inflateBack() will return with an error. Neither in() nor out() are permitted to change the contents of the window provided to inflateBackInit(), which is also the buffer that out() uses to write from. The length written by out() will be at most the window size. Any non-zero amount of input may be provided by in().
For convenience, inflateBack() can be provided input on the first call by setting strm->next_in and strm->avail_in. If that input is exhausted, then in() will be called. Therefore strm->next_in must be initialized before calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in must also be initialized, and then if strm->avail_in is not zero, input will initially be taken from strm->next_in[0 .. strm->avail_in - 1].
The in_desc and out_desc parameters of inflateBack() is passed as the first parameter of in() and out() respectively when they are called. These descriptors can be optionally used to pass any information that the caller- supplied in() and out() functions need to do their job.
On return, inflateBack() will set strm->next_in and strm->avail_in to pass back any unused input that was provided by the last in() call. The return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR if in() or out() returned an error, Z_DATA_ERROR if there was a format error in the deflate stream (in which case strm->msg is set to indicate the nature of the error), or Z_STREAM_ERROR if the stream was not properly initialized. In the case of Z_BUF_ERROR, an input or output error can be distinguished using strm->next_in which will be Z_NULL only if in() returned an error. If strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning non-zero. (in() will always be called before out(), so strm->next_in is assured to be defined if out() returns non-zero.) Note that inflateBack() cannot return Z_OK.
- int
_Cz_inflateBackEnd
All memory allocated by inflateBackInit() is freed.
- int
- Z_OK on success, or Z_STREAM_ERROR if the stream state was inconsistent.
_Cz_inflateCopy
Sets the destination stream as a complete copy of the source stream.
This function can be useful when randomly accessing a large stream. The first pass through the stream can periodically record the inflate state, allowing restarting inflate at those points when randomly accessing the stream.
- int
- Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being Z_NULL). msg is left unchanged in both source and destination.
_Cz_inflateEnd
All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output.
- int
- Z_OK or Z_STREAM_ERROR if stream state inconsistent
_Cz_inflateGetDictionary
Returns the sliding dictionary being maintained by inflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied to dictionary. dictionary must have enough space, where 32768 bytes is always enough. If inflateGetDictionary() is called with dictionary equal to Z_NULL, then only the dictionary length is returned, and nothing is copied. Similary, if dictLength is Z_NULL, then it is not set.
- int
- Z_OK on success, or Z_STREAM_ERROR if the stream state is inconsistent.
_Cz_inflateGetHeader
inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after inflateInit2() or inflateReset(), and before the first call of inflate(). As inflate() processes the gzip stream, head->done is zero until the header is completed, at which time head->done is set to one. If a zlib stream is being decoded, then head->done is set to -1 to indicate that there will be no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be used to force inflate() to return immediately after header processing is complete and before any actual data is decompressed.
The text, time, xflags, and os fields are filled in with the gzip header contents. hcrc is set to true if there is a header CRC. (The header CRC was valid if done is set to one.) If extra is not Z_NULL, then extra_max contains the maximum number of bytes to write to extra. Once done is true, extra_len contains the actual extra field length, and extra contains the extra field, or that field truncated if extra_max is less than extra_len. If name is not Z_NULL, then up to name_max characters are written there, terminated with a zero unless the length is greater than name_max. If comment is not Z_NULL, then up to comm_max characters are written there, terminated with a zero unless the length is greater than comm_max. When any of extra, name, or comment are not Z_NULL and the respective field is not present in the header, then that field is set to Z_NULL to signal its absence. This allows the use of deflateSetHeader() with the returned structure to duplicate the header. However if those fields are set to allocated memory, then the application will need to save those pointers elsewhere so that they can be eventually freed.
If inflateGetHeader is not used, then the header information is simply discarded. The header is always checked for validity, including the header CRC if present. inflateReset() will reset the process to discard the header information. The application would need to call inflateGetHeader() again to retrieve the header from the next gzip stream.
- int
- Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent.
_Cz_inflateInit
Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. In the current version of inflate, the provided input is not read or consumed. The allocation of a sliding window will be deferred to the first call of inflate (if the decompression does not complete on the first call). If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions.
- int
- Z_OK if success, Z_MEM_ERROR if there was not enough memory, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if there is no error message. inflateInit does not perform any decompression. Actual decompression will be done by inflate(). So next_in, and avail_in, next_out, and avail_out are unused and unchanged. The current implementation of inflateInit() does not process any header information -- that is deferred until inflate() is called.
_Cz_inflateInit2
This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller.
The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if deflateInit2() was not used. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window.
windowBits can also be zero to request that inflate use the window size in the zlib header of the compressed stream.
windowBits can also be -8..-15 for raw inflate. In this case, -windowBits determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not looking for any check values for comparison at the end of the stream. This is for use with other formats that use the deflate compressed data format such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is recommended that a check value such as an Adler-32 or a CRC-32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits.
windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see below), inflate() will not automatically decode concatenated gzip streams. inflate() will return Z_STREAM_END at the end of the gzip stream. The state would need to be reset to continue decoding a subsequent gzip stream.
- int
- Z_OK if success, Z_MEM_ERROR if there was not enough memory, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from possibly reading the zlib header if present: actual decompression will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unused and unchanged.) The current implementation of inflateInit2() does not process any header information -- that is deferred until inflate() is called.
_Cz_inflateMark
Returns two values, one in the lower 16 bits of the return value, and the other in the remaining upper bits, obtained by shifting the return value down 16 bits. If the upper value is -1 and the lower value is zero, then inflate() is currently decoding information outside of a block. If the upper value is -1 and the lower value is non-zero, then inflate is in the middle of a stored block, with the lower value equaling the number of bytes from the input remaining to copy. If the upper value is not -1, then it is the number of bits back from the current bit position in the input of the code (literal or length/distance pair) currently being processed. In that case the lower value is the number of bytes already emitted for that code.
A code is being processed if inflate is waiting for more input to complete decoding of the code, or if it has completed decoding but is waiting for more output space to write the literal or match data.
inflateMark() is used to mark locations in the input data for random access, which may be at bit positions, and to note those cases where the output of a code may span boundaries of random access blocks. The current location in the input stream can be determined from avail_in and data_type as noted in the description for the Z_BLOCK flush parameter for inflate.
- long
- the value noted above, or -65536 if the provided source stream state was inconsistent.
_Cz_inflatePrime
This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the middle of a byte. The provided bits will be used before any bytes are used from next_in. This function should only be used with raw inflate, and should be used before the first inflate() call after inflateInit2() or inflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the input.
If bits is negative, then the input stream bit buffer is emptied. Then inflatePrime() can be called again to put bits in the buffer. This is used to clear out bits leftover after feeding inflate a block description prior to feeding inflate codes.
- int
- Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent.
_Cz_inflateReset
This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate the internal decompression state. The stream will keep attributes that may have been set by inflateInit2.
- int
- Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL).
_Cz_inflateReset2
This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted the same as it is for inflateInit2. If the window size is changed, then the memory allocated for the window is freed, and the window will be reallocated by inflate() if needed.
- int
- Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL), or if the windowBits parameter is invalid.
_Cz_inflateSetDictionary
Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the Adler-32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called at any time to set the dictionary. If the provided dictionary is smaller than the window and there is already data in the window, then the provided dictionary will amend what's there. The application must insure that the dictionary that was used for compression is provided.
- int
- Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect Adler-32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate().
_Cz_inflateSync
Skips invalid compressed data until a possible full flush point (see above for the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided.
inflateSync searches for a 00 00 FF FF pattern in the compressed data. All full flush points have this pattern, but not all occurrences of this pattern are full flush points.
- int
- Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data.
_Cz_uncompress
Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the uncompressed data.
- int
- Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In the case where there is not enough room, uncompress() will fill the output buffer with the uncompressed data up to that point.
_Cz_uncompress2
Same as uncompress, except that sourceLen is a pointer, where the length of the source is *sourceLen. On return, *sourceLen is the number of source bytes consumed.
- int
_Cz_zlibVersion
The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit.
- const char*
DecodeBase64
Decodes base64 ascii representation to binary.
This supports the following alphabets:
- ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
- ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
- const char* data
- is input value
- unsigned long size
- if -1 implies strlen
- unsigned long* out_size
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
DecodeLatin1
Decodes ISO-8859-1 to UTF-8.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
_DescribeClockName
Describes clock_gettime() clock argument.
- char* buf
- int x
- const char*
_DescribeRlimitName
Describes setrlimit() / getrlimit() argument.
- char* buf
- int x
- const char*
_DescribeSchedParam
Describes clock_gettime() clock argument.
- char* buf
- struct sched_param* x
- const char*
_DescribeSchedPolicy
Describes clock_gettime() clock argument.
- char* buf
- int x
- const char*
_DescribeSiCode
Returns symbolic name for siginfo::si_code value.
- char* b
- int sig
- int si_code
- int sig
- const char*
_DescribeSleepFlags
Describes clock_nanosleep() flags argument.
- char* buf
- int x
- const char*
_DescribeSockLevel
Describes setsockopt() level arguments.
- char* buf
- int x
- const char*
_DescribeSockOptname
Describes setsockopt() optname arguments.
- char* buf
- int l
- int x
- int l
- const char*
dirname
Returns directory portion of path, e.g.
path │ dirname() │ basename() ───────────────────────────────── . │ . │ . .. │ . │ .. / │ / │ / usr │ . │ usr /usr/ │ / │ usr /usr/lib │ /usr │ lib
- char* path
- is UTF-8 and may be mutated, but not expanded in length
- char*
- pointer to path, or inside path, or to a special r/o string
div
Divides integers yielding numerator and denominator.
- int num
- int den
- struct retval
__divmodti4
Divides 128-bit signed integers w/ remainder.
- __int128 a
- is numerator
- __int128 b
- is denominator
- unsigned __int128* opt_out_rem
- receives euclidean division remainder if not null
- __int128
- quotient or result of division
__divti3
Divides 128-bit signed integers.
- __int128 a
- is numerator
- __int128 b
- is denominator
- __int128
- quotient or result of division
djbsort
D.J. Bernstein's outrageously fast integer sorting algorithm.
- int* a
- unsigned long n
- void
djbsort_avx2
D.J. Bernstein's outrageously fast integer sorting algorithm.
- rdi
- is int32 array
- rsi
- is number of elements in rdi
dlmalloc_requires_more_vespene_gas
Acquires more system memory for dlmalloc.
- unsigned long size
- void*
- memory map address on success, or null w/ errno
dn_comp
- const char* src
- unsigned char* dst
- int space
- unsigned char** dnptrs
- unsigned char** lastdnptr
- unsigned char* dst
- int
dprintf
Formats string directly to file descriptor.
- int fd
- const char* fmt
- ...
- const char* fmt
- int
dup
Duplicates file descriptor.
The O_CLOEXEC
flag shall be cleared from the resulting file
descriptor; see dup3() to preserve it.
One use case for duplicating file descriptors is to be able to reassign an open()'d file or pipe() to the stdio of an executed subprocess. On Windows, in order for this to work, the subprocess needs to be a Cosmopolitan program that has socket() linked.
Only small programs should duplicate sockets. That's because this implementation uses DuplicateHandle() on Windows, which Microsoft says might cause its resources to leak internally. Thus it likely isn't a good idea to design a server that does it a lot and lives a long time, without contributing a patch to this implementation.
- int fd
- remains open afterwards
- int
- some arbitrary new number for fd
fd
is a zip file descriptor
fd
is negative or not open
eaccess
Performs access() check using effective user/group id.
- const char* filename
- int amode
- int
EAGAIN
Resource temporarily unavailable (e.g. SO_RCVTIMEO expired, too many processes, too much memory locked, read or write with O_NONBLOCK needs polling, etc.).
- const int
EFAULT
Pointer passed to system call that would otherwise segfault.
- const int
_EfiPostboot
Start the Cosmopolitan runtime after exiting UEFI Boot Services.
- rdi
- is mm
- rsi
- is new pml4t
- rdx
- is argc
- rcx
- is argv
EncodeBase64
Encodes binary to base64 ascii representation.
- const char* data
- is input value
- unsigned long size
- if -1 implies strlen
- unsigned long* out_size
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EncodeHttpHeaderValue
Encodes HTTP header value.
This operation involves the following:
- Trim whitespace.
- Turn UTF-8 into ISO-8859-1.
- Make sure no C0 or C1 control codes are present (except tab).
- const char* data
- is input value
- unsigned long size
- if -1 implies strlen
- unsigned long* out_size
- if non-NULL receives output length on success
- char*
- allocated NUL-terminated string, or NULL w/ errno
EncodeLatin1
Encodes UTF-8 to ISO-8859-1.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- int f
- can kControlC0, kControlC1, kControlWs to forbid
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EncodeUrl
Encodes URL.
- struct Url* h
- unsigned long* z
- if not null receives string length of result
- char*
- nul-terminated url string needing free
endswith
Returns true if s has suffix.
- const char* s
- is a NUL-terminated string
- const char* suffix
- is also NUL-terminated
- int
endswith16
Returns true if s has suffix.
- const unsigned short* s
- is a NUL-terminated string
- const unsigned short* suffix
- is also NUL-terminated
- int
ENOSYS
System call unavailable.
- const int
erf
Returns error function of x.
Highest measured error is 1.01 ULPs at 0x1.39956ac43382fp+0.
- double x
- double
__errno
Global variable for last error.
The system call wrappers update this with WIN32 error codes. Unlike traditional libraries, Cosmopolitan error codes are defined as variables. By convention, system calls and other functions do not update this variable when nothing's broken.
- int
EscapeFragment
Escapes URL fragment.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EscapeHost
Escapes URL host or registry name.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EscapeHtml
Escapes HTML entities.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EscapeIp
Escapes URL IP-literal.
This is the same as EscapeHost except colon is permitted.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EscapeJsStringLiteral
Escapes UTF-8 data for JavaScript or JSON string literal.
HTML entities and forward slash are escaped too for added safety.
Single quote ('
) is \uxxxx-encoded for consistency, as it's
allowed in JavaScript, but not in JSON strings.
We assume the UTF-8 is well-formed and can be represented as UTF-16. Things that can't be decoded will fall back to binary. Things that can't be encoded will use invalid codepoint markers. This function is agnostic to numbers that have been used with malicious intent in the past under buggy software. Noncanonical encodings such as overlong NUL are canonicalized as NUL. Therefore it isn't necessary to say EscapeJsStringLiteral(Underlong(𝑥)) since EscapeJsStringLiteral(𝑥) will do the same thing.
- char** r
- is realloc'able output buffer reused between calls
- unsigned long* y
- is used to track byte length of
*r
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- char*
- *r on success, or null w/ errno
EscapeParam
Escapes query/form name/parameter.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EscapePass
Escapes URL password.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EscapePath
Escapes URL path.
This is the same as EscapePathSegment() except slash is allowed.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EscapeSegment
Escapes URL path segment.
Please note this will URI encode the slash character. That's because segments are the labels between the slashes in a path.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EscapeUrl
Escapes URL component using generic table.
This function is agnostic to the underlying charset. Always using UTF-8 is a good idea.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- const char* T
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
EscapeUrlView
Escapes URL component using generic table w/ stpcpy() api.
- char* p
- struct fragment* v
- const char* T
- struct fragment* v
- char*
EscapeUser
Escapes URL user name.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
euidaccess
Performs access() check using effective user/group id.
- const char* filename
- int amode
- int
execlp
Executes program, with PATH search and current environment.
The current process is replaced with the executed one.
- const char* prog
- is program to launch (may be PATH searched)
- const char* arg
- ...
- int
- doesn't return on success, otherwise -1 w/ errno
execve
Replaces current process with program.
On Windows, argv
and envp
can't contain binary strings. They need
to be valid UTF-8 in order to round-trip the WIN32 API, without being
corrupted.
On Windows, only file descriptors 0, 1 and 2 can be passed to a child process in such a way that allows them to be automatically discovered when the child process initializes. Cosmpolitan currently treats your other file descriptors as implicitly O_CLOEXEC.
- const char* prog
- char** argv
- char** envp
- char** argv
- int
- doesn't return, or -1 w/ errno
prog
open in write mode
execvpe
Executes program, with path environment search.
This function is a wrapper of the execve() system call that does path
resolution. The PATH
environment variable is taken from your global
environ
rather than the envp
argument.
- const char* prog
- is the program to launch
- char** argv
- is [file,argv₁..argvₙ₋₁,NULL]
- char** envp
- is ["key=val",...,NULL]
- int
- doesn't return on success, otherwise -1 w/ errno
exit
Exits process with grace.
This calls functions registered by atexit() before terminating the current process, and any associated threads. It also calls all the legacy linker registered destructors in reversed order
This implementation allows exit() to be called recursively via atexit() handlers.
- int exitcode
- is masked with 255
fabs
Returns absolute value of floating point number.
- double x
- double
faccessat
Checks if effective user can access path in particular ways.
- int dirfd
- is normally AT_FDCWD but if it's an open directory and file is a relative path, then file is opened relative to dirfd
- const char* path
- is a filename or directory
- int amode
- can be
R_OK
,W_OK
,X_OK
, orF_OK
- int flags
- can have
AT_EACCESS
and/orAT_SYMLINK_NOFOLLOW
- int
- 0 if ok, or -1 and sets errno
amode
or flags
had invalid values
amode
would be denied
path
exists as non-directory
path
doesn't exist or path
is empty
path
is a zip file and dirfd
isn't AT_FDCWD
flags
is only supported on Linux 5.8+
fadvise
Drops hints to O/S about intended I/O behavior.
It makes a huge difference. For example, when copying a large file, it can stop the system from persisting GBs of useless memory content.
- int fd
- unsigned long offset
- unsigned long len
- unsigned long offset
- 0 means until end of file
- int advice
- can be MADV_SEQUENTIAL, MADV_RANDOM, etc.
- int
- 0 on success, or -1 w/ errno
fd
isn't a valid file descriptor
fd
refers to a pipe
advice
was invalid
fchdir
Sets current directory based on file descriptor.
This does *not* update the PWD
environment variable.
- int dirfd
- int
dirfd
doesn't refer to a directory
dirfd
isn't a valid file descriptor
dirfd
refers to /zip/...
file
fchmod
Changes file permissions via open()'d file descriptor.
- int fd
- unsigned int mode
- contains octal flags (base 8)
- int
fd
is a /zip/...
file
fchmodat
Changes permissions on file, e.g.:
CHECK_NE(-1, fchmodat(AT_FDCWD, "foo/bar.txt", 0644)); CHECK_NE(-1, fchmodat(AT_FDCWD, "o/default/program", 0755)); CHECK_NE(-1, fchmodat(AT_FDCWD, "privatefolder/", 0700));
- int dirfd
- const char* path
- must exist
- unsigned int mode
- contains octal flags (base 8)
- int flags
- can have
AT_SYMLINK_NOFOLLOW
- int
dirfd
or path
use zip file system
path
is a symbolic link, AT_SYMLINK_NOFOLLOW
is set in flags
, and filesystem does not support setting the mode of
symbolic links.
fchown
Changes owner and/or group of file, via open()'d descriptor.
- int fd
- unsigned int uid
- is user id, or -1u to not change
- unsigned int gid
- is group id, or -1u to not change
- int
- 0 on success, or -1 w/ errno
fchownat
Changes owner and/or group of path.
- int dirfd
- is open()'d relative-to directory, or AT_FDCWD, etc.
- const char* path
- unsigned int uid
- is user id, or -1 to not change
- unsigned int gid
- is group id, or -1 to not change
- int flags
- can have AT_SYMLINK_NOFOLLOW, etc.
- int
- 0 on success, or -1 w/ errno
dirfd
or path
use zip file system
fclose
Closes standard i/o stream and its underlying thing.
- struct FILE* f
- is the file object
- int
- 0 on success or -1 on error, which can be a trick for differentiating between EOF and real errors during previous i/o calls, without needing to call ferror()
fcntl
Does things with file descriptor, e.g.
CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));This function lets you duplicate file descriptors without running into an edge case where they take over stdio handles:
CHECK_GE((newfd = fcntl(oldfd, F_DUPFD, 3)), 3); CHECK_GE((newfd = fcntl(oldfd, F_DUPFD_CLOEXEC, 3)), 3);This function implements file record locking, which lets independent processes (and on Linux 3.15+, threads too!) lock arbitrary ranges associated with a file. See
test/libc/calls/lock_test.c
and other
locking related tests in that folder.
On Windows, the Cosmopolitan Libc polyfill for POSIX advisory locks
only implements enough of its nuances to support SQLite's needs. Some
possibilities, e.g. punching holes in lock, will raise ENOTSUP
.
- int fd
- is the file descriptor
- int cmd
- can be one of:
F_GETFD
getsFD_CLOEXEC
status offd
F_SETFDsets
FD_CLOEXECstatus of
argfile descriptor
F_GETFLreturns file descriptor status flags
F_SETFLsets file descriptor status flags -
O_NONBLOCKmay be changed -
O_APPENDmay be changed -
O_DIRECTmay be changed -
O_SEQUENTIALmay be changed (no-op on non-Windows) -
O_RANDOMmay be changed (no-op on non-Windows) - Other bits (
O_ACCMODE,
O_CREAT, etc.) are ignored
F_DUPFDis like dup() but
argis a minimum result, e.g. 3
F_DUPFD_CLOEXECditto but sets
O_CLOEXECon returned fd
F_SETLKfor record locking where
argis
struct flock *ditto but waits for lock (SQLite avoids this)
F_GETLKto retrieve information about a record lock
F_OFD_SETLKfor better non-blocking lock (Linux 3.15+ only)
F_OFD_SETLKWfor better blocking lock (Linux 3.15+ only)
F_OFD_GETLKfor better lock querying (Linux 3.15+ only)
F_FULLFSYNCon MacOS for fsync() with release barrier
F_BARRIERFSYNCon MacOS for fsync() with even more barriers
F_SETNOSIGPIPEon MacOS and NetBSD to control
SIGPIPEon MacOS and NetBSD to control
SIGPIPEon MacOS and NetBSD where arg is
char[PATH_MAX]on NetBSD to get max open file descriptor
F_NOCACHEon MacOS to toggle data caching
F_GETPIPE_SZon Linux to get pipe size
F_SETPIPE_SZon Linux to set pipe size
F_NOTIFYraise
SIGIOupon
fdevents in
arg(Linux only) -
DN_ACCESSfor file access -
DN_MODIFYfor file modifications -
DN_CREATEfor file creations -
DN_DELETEfor file deletions -
DN_RENAMEfor file renames -
DN_ATTRIBfor file attribute changes -
DN_MULTISHOTbitwise or for realtime signals (non-coalesced)
- ...
- int
- 0 on success, or -1 w/ errno
fd
isn't a valid open file descriptor
cmd
is unknown or unsupported by os
cmd
is invalid or unsupported by os
stdio
or flock
promise
F_SETLKW
would have exceeded RLIMIT_LOCKS
cmd
is F_SETOWN
and we weren't authorized
cmd
is F_SETOWN
and process group not found
cmd
was F_SETLKW
and waiting would deadlock
cmd
is F_DUPFD
or F_DUPFD_CLOEXEC
and
RLIMIT_NOFILE
would be exceeded
cmd
is F_SETLKW
or F_OFD_SETLKW
fdexists
Returns true if file descriptor exists.
This function is equivalent to:
fcntl(fd, F_GETFL) != -1Except it won't clobber
errno
and has minimal linkage.
- int fd
- int
fdopen
Allocates stream object for already-opened file descriptor.
- int fd
- existing file descriptor or -1 for plain old buffer
- const char* mode
- is passed to fopenflags()
- struct FILE*
- new stream or NULL w/ errno
feclearexcept
Clears floating point exception status, e.g.
feclearexcept(FE_ALL_EXCEPT);
- excepts
- may bitwise-or the following:
FE_INVALID
FE_DIVBYZERO
FE_OVERFLOW
FE_UNDERFLOW
FE_INEXACT
FE_ALL_EXCEPT
(all of the above)
- 0 on success, or nonzero on error
fedisableexcept
Disables floating point exception trapping, e.g.
feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW);When trapping is enabled, something should handle SIGFPE. Calling ShowCrashReports() at startup will install a generic handler with backtraces and the symbol of the
si->si_code
which UNIX defines
FPE_INTOVF
: integer overflowFPE_INTDIV
: integer divide by zeroFPE_FLTDIV
: floating point divide by zeroFPE_FLTOVF
: floating point overflowFPE_FLTUND
: floating point underflowFPE_FLTRES
: floating point inexactFPE_FLTINV
: invalid floating point operationFPE_FLTSUB
: subscript out of range
-ffast-math
or -Ofast
flags when
compiling code that needs to be debugged. Using -fsignaling-nans
will also help, since GCC doesn't enable that by default.
- int excepts
- may bitwise-or the following:
FE_INVALID
FE_DIVBYZERO
FE_OVERFLOW
FE_UNDERFLOW
FE_INEXACT
FE_ALL_EXCEPT
(all of the above)
- int
feenableexcept
Enables floating point exception trapping, e.g.
feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW);When trapping is enabled, something should handle SIGFPE. Calling ShowCrashReports() at startup will install a generic handler with backtraces and the symbol of the
si->si_code
which UNIX defines
FPE_INTOVF
: integer overflowFPE_INTDIV
: integer divide by zeroFPE_FLTDIV
: floating point divide by zeroFPE_FLTOVF
: floating point overflowFPE_FLTUND
: floating point underflowFPE_FLTRES
: floating point inexactFPE_FLTINV
: invalid floating point operationFPE_FLTSUB
: subscript out of range
-ffast-math
or -Ofast
flags when
compiling code that needs to be debugged. Using -fsignaling-nans
will also help, since GCC doesn't enable that by default.
- int excepts
- may bitwise-or the following:
FE_INVALID
FE_DIVBYZERO
FE_OVERFLOW
FE_UNDERFLOW
FE_INEXACT
FE_ALL_EXCEPT
(all of the above)
- int
feholdexcept
Saves floating-point environment and clears current exceptions.
- void** envp
- int
feof
Returns true if stream is in end-of-file state.
- struct FILE* f
- is file object stream pointer
- int
feof_unlocked
Returns true if stream is in end-of-file state.
- struct FILE* f
- is file object stream pointer
- int
ferror
Returns nonzero if stream is in error state.
- struct FILE* f
- is file stream pointer
- int
- non-zero if and only if it's an error state
ferror_unlocked
Returns nonzero if stream is in error state.
- struct FILE* f
- is file stream pointer
- int
- non-zero w/ errno only if
f
is in error state
fesetround
Sets rounding mode.
This configures the x87 FPU as well as SSE.
- int r
- int
- 0 on success, or -1 on error
fetestexcept
- excepts
- may bitwise-or the following:
FE_INVALID
FE_DIVBYZERO
FE_OVERFLOW
FE_UNDERFLOW
FE_INEXACT
FE_ALL_EXCEPT
(all of the above)
- mask of which exception status codes are currently set, or zero if there aren't any floating point exceptions
feupdateenv
Restores floating point environment and raises exceptions.
- void** envp
- int
fflush
Blocks until data from stream buffer is written out.
- struct FILE* f
- is the stream handle, or 0 for all streams
- int
- is 0 on success or -1 on error
fgetc
Reads byte from stream.
- struct FILE* f
- is non-null file object stream pointer
- int
- byte in range 0..255, or -1 w/ errno
fgetc_unlocked
Reads byte from stream.
- struct FILE* f
- is file object stream pointer
- int
- byte in range 0..255, or -1 w/ errno
fgetln
Retrieves line from stream, e.g.
char *line; while ((line = chomp(fgetln(stdin, 0)))) { printf("%s\n", line); }The returned memory is owned by the stream. It'll be reused when fgetln() is called again. It's free()'d upon fclose() / fflush()
When reading from the console on Windows in ICANON
mode, the
returned line will end with \r\n
rather than \n
.
- struct FILE* stream
- specifies non-null open input stream
- unsigned long* len
- optionally receives byte length of line
- char*
- nul-terminated line string, including the
\n
character unless a line happened before EOF without\n
, otherwise it returnsNULL
and feof() and ferror() can examine the state
fgets
Reads line from stream.
This function is similar to getline() except it'll truncate lines exceeding size. The line ending marker is included and may be removed using chomp().
When reading from the console on Windows in ICANON
mode, the
returned line will end with \r\n
rather than \n
.
- char* s
- is output buffer
- int size
- is capacity of s
- struct FILE* f
- is non-null file object stream pointer
- char*
- s on success, NULL on error, or NULL if EOF happens when zero characters have been read
fgets_unlocked
Reads line from stream.
This function is similar to getline() except it'll truncate lines exceeding size. The line ending marker is included and may be removed using chomp().
- char* s
- is output buffer
- int size
- is capacity of s
- struct FILE* f
- is non-null file object stream pointer
- char*
- s on success, NULL on error, or NULL if EOF happens when zero characters have been read
fgetwc
Reads UTF-8 character from stream.
- struct FILE* f
- is non-null file object stream pointer
- unsigned int
- wide character or -1 on EOF or error
fgetwc_unlocked
Reads UTF-8 character from stream.
- struct FILE* f
- unsigned int
- wide character or -1 on EOF or error
fgetws
Reads UTF-8 content from stream into UTF-32 buffer.
This function is similar to getline() except it'll truncate lines exceeding size. The line ending marker is included and may be removed using chomp().
- int* s
- is is nul-terminated string that's non-null
- int size
- is byte length of
s
- struct FILE* f
- is file stream object pointer
- int*
fgetws_unlocked
Reads UTF-8 content from stream into UTF-32 buffer.
This function is similar to getline() except it'll truncate lines exceeding size. The line ending marker is included and may be removed using chomp().
- int* s
- is is nul-terminated string that's non-null
- int size
- is byte length of
s
- struct FILE* f
- is file stream object pointer
- int*
fileno
Returns file descriptor associated with stream.
- struct FILE* f
- is file stream object pointer
- int
- fd on success or -1 w/ errno;
fileno_unlocked
Returns file descriptor associated with stream.
- struct FILE* f
- is file stream object pointer
- int
- fd on success or -1 w/ errno;
FindComBinary
Returns path of binary without debug information, or null.
- const char*
- path to non-debug binary, or -1 w/ errno
FindContentType
Returns Content-Type for file extension.
- const char* p
- unsigned long n
- const char*
FindDebugBinary
Returns path of binary with the debug information, or null.
You can specify the COMDBG environment variable, with the path of the debug binary, in case the automatic heuristics fail. What we look for is GetProgramExecutableName() with ".dbg", ".com.dbg", etc. appended.
- const char*
- path to debug binary, or NULL if we couldn't find it
FindElfSectionByName
Returns ELF section header for section with name.
- struct Elf64_Ehdr* elf
- points to the start of the executable image data
- unsigned long mapsize
- is the number of bytes past
elf
we can access - char* shdrstrtab
- const char* name
- struct Elf64_Shdr*
- pointer to section header within image, or null
__flbf
Returns nonzero if stream is line buffered.
- struct FILE* f
- int
flock
Acquires lock on file.
Please note multiple file descriptors means multiple locks.
- int fd
- int op
- can have LOCK_{SH,EX,NB,UN} for shared, exclusive, non-blocking, and unlocking
- int
- 0 on success, or -1 w/ errno
fma
Performs fused multiply add.
- double x
- double y
- double z
- double y
- double
𝑥 * 𝑦 + 𝑧
rounded as one ternary operation
fmaf
Performs fused multiply add.
- float x
- float y
- float z
- float y
- float
𝑥 * 𝑦 + 𝑧
with a single rounding error
fmax
Returns maximum of two doubles.
If one argument is NAN then the other is returned. This function is designed to do the right thing with signed zeroes.
- double x
- double y
- double
fmaxf
Returns maximum of two floats.
If one argument is NAN then the other is returned. This function is designed to do the right thing with signed zeroes.
- float x
- float y
- float
fmaxl
Returns maximum of two long doubles.
If one argument is NAN then the other is returned. This function is designed to do the right thing with signed zeroes.
- long double x
- long double y
- long double
fmemopen
Opens buffer as stream.
- void* buf
- becomes owned by this function, and is allocated if NULL
- unsigned long size
- const char* mode
- struct FILE*
- new stream or NULL w/ errno
buf
is NULL and we failed to allocate it
buf
is NULL and malloc() wasn't linked
buf
is NULL when +
isn't in mode
fmin
Returns minimum of two doubles.
If one argument is NAN then the other is returned. This function is designed to do the right thing with signed zeroes.
- double x
- double y
- double
fminl
Returns minimum of two long doubles.
If one argument is NAN then the other is returned. This function is designed to do the right thing with signed zeroes.
- long double x
- long double y
- long double
fmod
Does (𝑥 rem 𝑦) w/ round()-style rounding.
- double x
- double y
- double
- remainder ∈ (-|𝑦|,|𝑦|) in %xmm0
fmodl
Does (𝑥 rem 𝑦) w/ round()-style rounding.
- long double x
- long double y
- long double
- remainder ∈ (-|𝑦|,|𝑦|) in %xmm0
FoldHeader
Collapses repeating headers onto a single line.
- struct HttpMessage* msg
- const char* b
- int h
- unsigned long* z
- const char* b
- char*
fopen
Opens file as stream object.
- const char* pathname
- is a utf-8 ideally relative filename
- const char* mode
- is the string mode/flag DSL see fopenflags()
- struct FILE*
- new object to be free'd by fclose() or NULL w/ errno
FormatBinary64
Converts unsigned 64-bit integer to binary string.
- char* p
- needs at least 67 bytes
- unsigned long x
- char z
- is 0 for DIGITS, 1 for 0bDIGITS, 2 for 0bDIGITS if ≠0
- char*
- pointer to nul byte
FormatFlex64
Formats integer using decimal or hexadecimal.
This formats as int64 signed decimal. However it's a:
- positive number
- with population count of 1
- and a magnitude of at least 256
- char* p
- long x
- char z
- long x
- char*
FormatHex64
Converts unsigned 64-bit integer to hex string.
- char* p
- needs at least 19 bytes
- unsigned long x
- char z
- is 0 for DIGITS, 1 for 0xDIGITS, 2 for 0xDIGITS if ≠0
- char*
- pointer to nul byte
FormatInt32
Converts signed 32-bit integer to string.
- char* p
- needs at least 12 bytes
- int x
- char*
- pointer to nul byte
FormatInt64
Converts signed 64-bit integer to string.
- char* p
- needs at least 21 bytes
- long x
- char*
- pointer to nul byte
FormatInt64Thousands
Converts 64-bit integer to string w/ commas.
- char* p
- needs at least 27 bytes
- long x
- char*
- pointer to nul byte
FormatOctal32
Converts unsigned 32-bit integer to octal string.
- char* p
- needs at least 12 bytes
- unsigned int x
- int z
- ensures it starts with zero
- char*
- pointer to nul byte
FormatOctal64
Converts unsigned 64-bit integer to octal string.
- char* p
- needs at least 24 bytes
- unsigned long x
- int z
- ensures it starts with zero
- char*
- pointer to nul byte
FormatUint32
Converts unsigned 32-bit integer to string.
- char* p
- needs at least 12 bytes
- unsigned int x
- char*
- pointer to nul byte
FormatUint64
Converts unsigned 64-bit integer to string.
- char* p
- needs at least 21 bytes
- unsigned long x
- char*
- pointer to nul byte
FormatUint64Thousands
Converts unsigned 64-bit integer to string w/ commas.
- char* p
- needs at least 27 bytes
- unsigned long x
- char*
- pointer to nul byte
fprintf
Formats and writes text to stream.
- struct FILE* f
- const char* fmt
- ...
- const char* fmt
- int
fprintf_unlocked
Formats and writes text to stream.
- struct FILE* f
- const char* fmt
- ...
- const char* fmt
- int
fpurge
Discards contents of stream buffer.
- struct FILE* f
- int
fputc
Writes byte to stream.
- int c
- is byte to buffer or write, which is masked
- struct FILE* f
- int
- c as unsigned char if written or -1 w/ errno
fputc_unlocked
Writes byte to stream.
- int c
- is byte to buffer or write, which is masked
- struct FILE* f
- int
- c as unsigned char if written or -1 w/ errno
fputs
Writes string to stream.
Writing stops at the NUL-terminator, which isn't included in output. This function blocks until the full string is written, unless an unrecoverable error happens.
- const char* s
- is a NUL-terminated string that's non-NULL
- struct FILE* f
- is an open stream
- int
- bytes written, or -1 w/ errno
fputs_unlocked
Writes string to stream.
Writing stops at the NUL-terminator, which isn't included in output. This function blocks until the full string is written, unless an unrecoverable error happens.
- const char* s
- is a NUL-terminated string that's non-NULL
- struct FILE* f
- is an open stream
- int
- bytes written, or -1 w/ errno
fputwc
Writes wide character to stream.
- int wc
- has wide character
- struct FILE* f
- is file object stream pointer
- unsigned int
- wide character if written or -1 w/ errno
fputwc_unlocked
Writes wide character to stream.
- int wc
- has wide character
- struct FILE* f
- is file object stream pointer
- unsigned int
- wide character if written or -1 w/ errno
fputws
Writes wide character string to stream.
Writing stops at the NUL-terminator, which isn't included in output. This function blocks until the full string is written, unless an unrecoverable error happens.
- const int* s
- is a NUL-terminated string that's non-NULL
- struct FILE* f
- is an open stream
- int
- strlen(s), or -1 w/ errno
fputws_unlocked
Writes wide character string to stream.
Writing stops at the NUL-terminator, which isn't included in output. This function blocks until the full string is written, unless an unrecoverable error happens.
- const int* s
- is a NUL-terminated string that's non-NULL
- struct FILE* f
- is an open stream
- int
- strlen(s), or -1 w/ errno
fread
Reads data from stream.
- void* buf
- unsigned long stride
- specifies the size of individual items
- unsigned long count
- is the number of strides to fetch
- struct FILE* f
- unsigned long
- count on success, [0,count) on eof, or 0 on error or count==0
fread_unlocked
Reads data from stream.
- void* buf
- unsigned long stride
- specifies the size of individual items
- unsigned long count
- is the number of strides to fetch
- struct FILE* f
- unsigned long
- count on success, [0,count) on eof, or 0 on error or count==0
free
Free memory returned by malloc() & co.
Releases the chunk of memory pointed to by p, that had been previously allocated using malloc or a related routine such as realloc. It has no effect if p is null.
- void* p
- is allocation address, which may be NULL
- void
freeifaddrs
Frees network interface address list.
- struct ifaddrs* ifp
- void
freopen
Overwrites existing stream.
This function can be used in two ways. The first is sort of a mutating assignment. The second behavior, if pathname is NULL, is just changing the mode of an already open file descriptor.
- const char* pathname
- is the file to open or NULL
- const char* mode
- is the mode string flags, see fopenflags()
- struct FILE* stream
- is the existing allocated stream memory, which is flushed and closed if already open
- struct FILE*
- stream object if successful, or NULL w/ errno
fscanf
Decodes data from stream.
To read a line of data from a well-formed trustworthy file:
int x, y; char text[256]; fscanf(f, "%d %d %s\n", &x, &y, text);Please note that this function is brittle by default, which makes it a good fit for yolo coding. With some toil it can be used in a way that makes it reasonably hardened although getline() may be better.
- struct FILE* stream
- const char* fmt
- ...
- const char* fmt
- int
fseek
Repositions open file stream.
This function flushes the buffer (unless it's currently in the EOF state) and then calls lseek() on the underlying file. If the stream is in the EOF state, this function can be used to restore it without needing to reopen the file.
- struct FILE* f
- is a non-null stream handle
- long offset
- is the byte delta
- int whence
- can be SEET_SET, SEEK_CUR, or SEEK_END
- int
fseek_unlocked
Repositions open file stream.
This function flushes the buffer (unless it's currently in the EOF state) and then calls lseek() on the underlying file. If the stream is in the EOF state, this function can be used to restore it without needing to reopen the file.
- struct FILE* f
- is a non-null stream handle
- long offset
- is the byte delta
- int whence
- can be SEET_SET, SEEK_CUR, or SEEK_END
- int
__fsetlocking
Does nothing and returns FSETLOCKING_INTERNAL
.
- struct FILE* f
- int type
- int
fstat
Returns information about file, via open()'d descriptor.
On Windows, this implementation always sets st_uid
and st_gid
to
getuid()
and getgid()
. The st_mode
field is generated based on
the current umask().
- int fd
- struct stat* st
- int
- 0 on success or -1 w/ errno
fd
isn't a valid file descriptor
fstatat
Returns information about thing.
On Windows, this implementation always sets st_uid
and st_gid
to
getuid()
and getgid()
. Anyone who relies upon the information to
secure a multi-tenant personal computer should consider improving it
and further note that the st_mode
group / other bits will be clear
- int dirfd
- is normally
AT_FDCWD
but if it's an open directory and file is a relative path, thenpath
becomes relative todirfd
- const char* path
- struct stat* st
- is where the result is stored
- int flags
- can have
AT_SYMLINK_NOFOLLOW
- int
- 0 on success, or -1 w/ errno
path
path
exceeds NAME_MAX
path
contains illegal UTF-8 sequences (Windows/MacOS)
path
is relative and dirfd
isn't an open directory
path
is a zip path and this executable isn't a zip file
SYMLOOP_MAX
symlinks were dereferenced
path
exceeded PATH_MAX
path
or st
point to invalid memory
flags
has unsupported bits
fstatfs
Returns information about filesystem.
- int fd
- struct statfs* sf
- int
- 0 on success, or -1 w/ errno
fstatvfs
Returns information about filesystem.
- int fd
- struct statvfs* sv
- int
- 0 on success, or -1 w/ errno
fsum
Adds doubles in array.
- const double* p
- unsigned long n
- double
ftell
Returns current position of stream.
- struct FILE* f
- long
ftok
Convert pathname and a project ID to System V IPC key.
- const char* path
- int id
- int
__ftrace
Function tracing enabled state.
After ftrace_install() has been called, the logging of C function
calls may be controlled by changing this variable. If __ftrace
is
greater than zero, functions are logged. Otherwise, they aren't.
By convention, functions wishing to disable function tracing for a short time period should say:
void foo() { ftrace_enabled(-1); bar(); ftrace_enabled(+1); }This way you still have some flexibility to force function tracing, by setting
__ftrace
to a higher number like 2
or 200
. Even
though under normal circumstances, __ftrace
should only be either
zero or one.
- int
ftruncate
Changes size of open file.
If the file size is increased, the extended area shall appear as if it were zero-filled. If your file size is decreased, the extra data shall be lost.
This function never changes the file position. This is true even if ftruncate() causes the position to become beyond the end of file in which case, the rules described in the lseek() documentation apply.
Some operating systems implement an optimization, where length
is
treated as a logical size and the requested physical space won't be
allocated until non-zero values get written into it. Our tests show
this happens on Linux (usually with 4096 byte granularity), FreeBSD
(which favors 512-byte granularity), and MacOS (prefers 4096 bytes)
however Windows, OpenBSD, and NetBSD always reserve physical space.
This may be inspected using fstat() and consulting stat::st_blocks.
- int fd
- must be open for writing
- long length
- may be greater than current current file size
- int
- 0 on success, or -1 w/ errno
length
is negative
length
is too huge
fd
isn't an open file descriptor
fd
is a non-file, e.g. pipe, socket
fd
wasn't opened in a writeable mode
fd
is on a read-only filesystem (e.g. zipos)
ftrylockfile
Tries to acquire reentrant stdio object lock.
- struct FILE* f
- int
- 0 on success, or non-zero if another thread owns the lock
ftw
Walks file tree.
- const char* dirpath
- int(*)() fn
- int fd_limit
- int(*)() fn
- int
- 0 on success, -1 on error, or non-zero
fn
result
futimens
Changes access/modified time on open file, the modern way.
XNU only has microsecond (1e-6) accuracy. Windows only has hectonanosecond (1e-7) accuracy. RHEL5 (Linux c. 2007) doesn't support this system call.
- int fd
- is file descriptor of file whose timestamps will change
- struct timespec* ts
- is {access, modified} timestamps, or null for current time
- int
- 0 on success, or -1 w/ errno
flags
had an unrecognized value
fattr
promise
ts
specifies a nanosecond value that's out of range
fd
is a zip file or on a read-only filesystem
fd
isn't an open file descriptor
ts
memory was invalid
futimes
Sets atime/mtime on file descriptor.
- int fd
- struct timeval* tv
- int
- 0 on success, or -1 w/ errno
fd
isn't an open file descriptor
fd
is on zip or read-only filesystem
fattr
promise
tv
specifies a microsecond value that's out of range
futimesat
Changes last accessed/modified times on file.
- int dirfd
- const char* pathname
- struct timeval* tv
- const char* pathname
- int
- 0 on success or -1 w/ errno
fwrite
Writes data to stream.
- void* data
- unsigned long stride
- specifies the size of individual items
- unsigned long count
- is the number of strides to write
- struct FILE* f
- unsigned long
- count on success, [0,count) on EOF, 0 on error or count==0
fwrite_unlocked
Writes data to stream.
- void* data
- unsigned long stride
- specifies the size of individual items
- unsigned long count
- is the number of strides to write
- struct FILE* f
- unsigned long
- count on success, [0,count) on EOF, 0 on error or count==0
__g_Qfmt_p
Converts quadruple-precision floating-point number to string.
- char* buf
- void* V
- int ndig
- unsigned long bufsize
- int nik
- void* V
- char*
__gc
Invokes deferred function calls.
This offers behavior similar to std::unique_ptr. Functions overwrite their return addresses jumping here, and pushing exactly one entry on the shadow stack below. Functions may repeat that process multiple times, in which case the body of this gadget loops and unwinds as a natural consequence.
- rax,rdx,xmm0,xmm1,st0,st1
- is return value
gclongjmp
Jumps up stack to previous setjmp() invocation.
This is the same as longjmp() but also unwinds the stack to free memory, etc. that was registered using gc() or defer(). If GC isn't linked, this behaves the same as longjmp().
- rdi
- points to the jmp_buf which must be the same stack
- esi
- is returned by setjmp() invocation (coerced nonzero)
get_current_dir_name
Returns current working directory.
If the PWD
environment variable is set, and it's correct, then
that'll be returned in its exact canonical or non-canonical form
instead of calling getcwd().
- char*
- pointer that must be free()'d, or NULL w/ errno
__get_tmpdir
Returns pretty good temporary directory.
The order of precedence is:
- $TMPDIR/ is always favored if defined
- GetTempPath(), for the New Technology
- /tmp/ to make security scene go crazy
PATH_MAX
bytes. The string will
be short enough that at least NAME_MAX
bytes remain. This function
is thread safe so long as callers don't modified the returned memory
- char*
getauxval
Returns auxiliary value.
- unsigned long key
- unsigned long
- auxiliary value or 0 if
key
not found
getchar
Reads byte from stdin.
- int
- byte in range 0..255, or -1 w/ errno
getcontext
Gets machine state.
- 0 on success, or -1 w/ errno
getcwd
Returns current working directory, e.g.
const char *dirname = gc(getcwd(0,0)); // if malloc is linked const char *dirname = getcwd(alloca(PATH_MAX),PATH_MAX);
- char* buf
- is where UTF-8 NUL-terminated path string gets written, which may be NULL to ask this function to malloc a buffer
- unsigned long size
- is number of bytes available in buf, e.g. PATH_MAX+1, which may be 0 if buf is NULL
- char*
- buf containing system-normative path or NULL w/ errno
size
wasn't big enough for path and nul byte
size
is zero and buf
is non-null
buf
points to invalid memory
getdelim
Reads string from stream, e.g.
char *line = NULL; size_t linesize = 0; while (getdelim(&line, &linesize, '\n', stdin) > 0) { chomp(line); printf("%s\n", line); } free(line);
- char** s
- is the caller's buffer (in/out) which is extended or allocated automatically, also NUL-terminated is guaranteed
- unsigned long* n
- is the capacity of s (in/out)
- int delim
- is the stop char (and NUL is implicitly too)
- struct FILE* f
- long
- number of bytes read >0, including delim, excluding NUL, or -1 w/ errno on EOF or error; see ferror() and feof()
getdelim_unlocked
Reads string from unlocked stream.
- char** s
- unsigned long* n
- int delim
- struct FILE* f
- unsigned long* n
- long
getdomainname
Returns domain of current host.
For example, if the fully-qualified hostname is "host.domain.example" then this SHOULD return "domain.example" however, it might not be the case; it depends on how the host machine is configured.
The nul / mutation semantics are tricky. Here is some safe copypasta:
char domain[254]; if (getdomainname(domain, sizeof(domain))) { strcpy(domain, "(none)"); }On Linux this is the same as
/proc/sys/kernel/domainname
. However,
we turn the weird "(none)"
string into empty string.
- char* name
- receives output name, which is guaranteed to be complete and have a nul-terminator if this function return zero
- unsigned long len
- is size of
name
consider usingDNS_NAME_MAX + 1
(254)
- int
- 0 on success, or -1 w/ errno
len
is negative
name
is an invalid address
len
in
which case this error is raised and the buffer is modified, with
as many bytes of hostname as possible excluding a nul-terminator
getegid
Returns effective group ID of calling process.
- unsigned int
- group id
GetElfProgramHeaderAddress
Returns program header at elf.phdr[i]
.
- struct Elf64_Ehdr* elf
- points to the start of the executable image
- unsigned long mapsize
- is the number of bytes past
elf
we can access - unsigned short i
- is the program header index, starting at zero
- struct Elf64_Phdr*
- program header pointer, or null on error
GetElfSectionAddress
Returns pointer to ELF section file content.
This function computes elf + sh_offset
with safety checks.
- struct Elf64_Ehdr* elf
- points to the start of the executable image data
- unsigned long mapsize
- is the number of bytes of
elf
we can access - struct Elf64_Shdr* shdr
- is from GetElfSectionHeaderAddress(), or null
- void*
- pointer to section data within image, or null if
shdr
was null, or- content wasn't contained within
[elf,elf+mapsize)
, or - an arithmetic overflow occurred
GetElfSectionHeaderAddress
Returns section header object at elf.section[i]
.
- struct Elf64_Ehdr* elf
- points to the start of the executable image data
- unsigned long mapsize
- is the number of bytes past
elf
we can access - unsigned short i
- is the index of the section header
- struct Elf64_Shdr*
- pointer to section header within image, or null if
i
was a magic number, i.e.i >= SHN_LORESERVE
, ore_shoff
was zero (image has no section headers), ore_shentsize
had fewer than the mandatory 60 bytes, or- section header wasn't contained by
[elf,elf+mapsize)
, or - an arithmetic overflow occurred
GetElfSectionName
- struct Elf64_Ehdr* elf
- unsigned long mapsize
- struct Elf64_Shdr* shdr
- unsigned long mapsize
- char*
GetElfSectionNameStringTable
Returns section name string table.
- struct Elf64_Ehdr* elf
- points to the start of the executable image
- unsigned long mapsize
- is the number of bytes past
elf
we can access
- char*
- double-nul terminated string list, or null on error
GetElfSegmentAddress
Returns pointer to ELF segment file content.
This function computes elf + p_offset
with safety checks.
- struct Elf64_Ehdr* elf
- points to the start of the executable image data
- unsigned long mapsize
- is the number of bytes of
elf
we can access - struct Elf64_Phdr* phdr
- is from GetElfProgramHeaderAddress(), or null
- void*
- pointer to segment data within image, or null if
phdr
was null, orp_filesz
was zero, or- content wasn't contained within
[elf,elf+mapsize)
, or - an arithmetic overflow occurred
GetElfString
Returns strtab + i
from elf string table.
- struct Elf64_Ehdr* elf
- points to the start of the executable image data
- unsigned long mapsize
- is the number of bytes past
elf
we can access - const char* strtab
- is double-nul string list from GetElfStringTable()
which may be null, in which case only the
!i
name is valid - unsigned int i
- is byte index into strtab where needed string starts or zero (no name) in which case empty string is always returned as a pointer to the read-only string literal, rather than in the elf image, since the elf spec permits an empty or absent string table section
- char*
- a const nul-terminated string pointer, otherwise null if
i
was nonzero andstrtab
was null, orstrtab+i
wasn't inside[elf,elf+mapsize)
, or- a nul byte wasn't present within
[strtab+i,elf+mapsize)
, or - an arithmetic overflow occurred
GetElfStringTable
Returns pointer to elf string table.
- struct Elf64_Ehdr* elf
- points to the start of the executable image data
- unsigned long mapsize
- is the number of bytes past
elf
we can access - const char* section_name
- is usually
".strtab"
,".dynstr"
, or null
- char*
- pointer to string table within
elf
image, which should normally be a sequence of NUL-terminated strings whose first string is the empty string; otherwise NULL is returned, when either: (1)section_name
is not found, (2) it did not have theSHT_STRTAB
section type, (3) the section size was zero noting that the ELF spec does consider that legal, or lastly (4) an overflow or boundary violation occurred
GetElfSymbols
Returns pointer to array of elf symbols.
This is a shortcut composing GetElfSymbolTable() and GetElfSectionAddress(), that can be used as follows:
Elf64_Xword i, n; Elf64_Sym *st = GetElfSymbols(map, size, SHT_SYMTAB, &n); for (i = 0; st && i < n; ++i) { // st[i] holds a symbol }The above code will iterate over the relocatable and/or statically-linked symbols defined by an ELF image.
- struct Elf64_Ehdr* elf
- points to the start of the executable image data
- unsigned long mapsize
- is the number of bytes past
elf
we can access - int section_type
- is usually
SHT_SYMTAB
orSHT_DYNSYM
- unsigned long* out_count
- optionally receives number of symbols
- struct Elf64_Sym*
- pointer to array of elf symbol array, otherwise null
GetElfSymbolTable
Returns pointer to the elf section header for a symbol table.
The easiest way to get the symbol table is:
Elf64_Xword i, n; Elf64_Sym *st = GetElfSymbols(map, size, SHT_SYMTAB, &n); for (i = 0; st && i < n; ++i) { // st[i] holds a symbol }This API is more verbose than the GetElfSymbols() shortcut, however calling this the long way makes tricks like the following possible:
Elf64_Xword i, n; Elf64_Shdr *sh = GetElfSymbolTable(map, size, SHT_SYMTAB, &n); Elf64_Sym *st = GetElfSectionAddress(map, size, sh); if (st) { for (i = sh->sh_info; i < n; ++i) { // st[i] holds a non-local symbol } }Our code here only cares about
STB_GLOBAL
and STB_WEAK
symbols
however SHT_SYMTAB
usually has countless STB_LOCAL
entries too
that must be skipped over. The trick is that the ELF spec requires
local symbols be ordered before global symbols, and that the index
dividing the two be stored to sh_info
. So, if we start iterating
there, then we've cleverly avoided possibly dozens of page faults!
- struct Elf64_Ehdr* elf
- points to the start of the executable image data
- unsigned long mapsize
- is the number of bytes past
elf
we can access - int section_type
- is usually
SHT_SYMTAB
orSHT_DYNSYM
- unsigned long* out_count
- optionally receives number of symbols
- struct Elf64_Shdr*
- pointer to symbol table section header, otherwise null
geteuid
Returns effective user ID of calling process.
- unsigned int
- user id
getgid
Returns real group id of process.
This never fails. On Windows, which doesn't really have this concept, we return a hash of the username.
- unsigned int
- group id (always successful)
getgrgid_r
- unsigned int gid
- struct gr* gr
- char* buf
- unsigned long size
- struct gr** res
- struct gr* gr
- int
getgrnam_r
- const char* name
- struct gr* gr
- char* buf
- unsigned long size
- struct gr** res
- struct gr* gr
- int
getgroups
Gets list of supplementary group IDs
- int size
- maximum number of items that can be stored in list
- unsigned int* list
- buffer to store output gid_t
- int
- -1 w/ EFAULT
gethostbyaddr_r
- void* a
- unsigned int l
- int af
- struct hostent* h
- char* buf
- unsigned long buflen
- struct hostent** res
- int* err
- unsigned int l
- int
gethostbyname_r
- const char* name
- struct hostent* h
- char* buf
- unsigned long buflen
- struct hostent** res
- int* err
- struct hostent* h
- int
gethostname
Returns name of current host.
For example, if the fully-qualified hostname is "host.domain.example" then this SHOULD return "host" however that might not be the case; it depends on how the host machine is configured. It's fair to say if it has a dot, it's a FQDN, otherwise it's a node.
The nul / mutation semantics are tricky. Here is some safe copypasta:
char host[254]; if (gethostname(host, sizeof(host))) { strcpy(host, "localhost"); }On Linux this is the same as
/proc/sys/kernel/hostname
.
- char* name
- receives output name, which is guaranteed to be complete and have a nul-terminator if this function return zero
- unsigned long len
- is size of
name
consider usingDNS_NAME_MAX + 1
(254)
- int
- 0 on success, or -1 w/ errno
len
is negative
name
is an invalid address
len
in
which case this error is raised and the buffer is modified, with
as many bytes of hostname as possible excluding a nul-terminator
GetHttpHeader
Returns small number for HTTP header, or -1 if not found.
- const char* str
- unsigned long len
- int
GetHttpReason
Returns string describing HTTP reason phrase.
- int code
- const char*
getifaddrs
Gets network interface address list.
- struct ifaddrs** out_ifpp
- int
- 0 on success, or -1 w/ errno
GetInterpreterExecutableName
Returns path of executable interpreter.
Unlike program_executable_name
which is designed to figure out the
absolute path of the first argument passed to execve()
, what we do
here is probe things like /proc
and sysctl()
to figure out if we
were launched by something like ape-loader
, and then we return its
path. If we can't determine that path, possibly because we're on XNU
or OpenBSD, then we return -1 with an error code.
- char* p
- receives utf8 output
- unsigned long n
- is byte size of res buffer
- char*
- p on success or null w/ errno if out of buf or error
getitimer
Retrieves last setitimer() value, correcting for remaining time.
- int which
- can be ITIMER_REAL, ITIMER_VIRTUAL, etc.
- struct itimerval* curvalue
- int
- 0 on success or -1 w/ errno
getline
Reads line from stream, e.g.
char *line = NULL; size_t linesize = 0; while (getline(&line, &linesize, stdin) > 0) { chomp(line); printf("%s\n", line); } free(line);This function delegates to getdelim(), which provides further documentation. Concerning lines, please note the \n or \r\n are included in results, and can be removed with chomp().
When reading from the console on Windows in ICANON
mode, the
returned line will end with \r\n
rather than \n
.
- char** linebuf
- is the caller's buffer (in/out) which is extended automatically. *line may be NULL but only if *capacity is 0; NUL-termination is guaranteed FTMP
- unsigned long* capacity
- struct FILE* f
- long
- number of bytes read, including delim, excluding NUL, or -1 w/ errno on EOF or error; see ferror() and feof()
getloadavg
Returns system load average.
- double* a
- should be array of 3 doubles
- int n
- should be 3
- int
- number of items placed in
a
or -1 w/ errno
__getntsyspath
Obtains WIN32 magic path, e.g. GetTempPathA.
- rax
- is address of ANSI path provider function
- rdi
- is output buffer
- rdx
- is output buffer size in bytes that's >0
- eax is string length w/ NUL that's ≤ edx
- rdi is rdi+edx
getopt_long
- int nargc
- char** nargv
- const char* options
- struct option* long_options
- int* idx
- char** nargv
- int
getopt_long_only
- int nargc
- char** nargv
- const char* options
- struct option* long_options
- int* idx
- char** nargv
- int
getpeername
Returns details about remote end of connected socket.
- int fd
- struct sa* out_addr
- unsigned int* inout_addrsize
- struct sa* out_addr
- int
- 0 on success or -1 w/ errno
getpgrp
Returns process group id of calling process.
This function is equivalent to getpgid(0)
.
- int
getpid
Returns process id.
This function does not need to issue a system call. The PID is
tracked by a global variable which is updated at fork(). The only
exception is when the process is vfork()'d in which case a system
call shall be issued. This optimization helps make functions like
_rand64() fork-safe, however it could lead to race conditions in
programs that mix fork() with threads. In that case, apps should
consider using sys_getpid().ax
instead to force a system call.
On Linux, and only Linux, getpid() is guaranteed to equal gettid() for the main thread.
- int
- process id (always successful)
getppid
Returns parent process id.
- int
- parent process id (always successful)
getpriority
Returns nice value of thing.
Since -1 might be a valid return value for this API, it's necessary
to clear errno
beforehand and see if it changed, in order to truly
determine if an error happened.
On Windows, there's only six priority classes. We define them as -16 (realtime), -10 (high), -5 (above), 0 (normal), 5 (below), 15 (idle) which are the only values that'll roundtrip getpriority/setpriority.
- int which
- can be one of:
PRIO_PROCESS
is supported universallyPRIO_PGRP
is supported on unixPRIO_USER
is supported on unix
- unsigned int who
- is the pid, pgid, or uid (0 means current)
- int
- value ∈ [-NZERO,NZERO) or -1 w/ errno
which
was invalid or unsupported
getpwent
Returns next entry in password database.
- struct pw*
- pointer to entry static memory, or NULL on EOF
getpwnam
Returns password database entry for user name.
This is essentially guaranteed to succeed if uid == getenv("USER")
,
since this implementation will generate an entry based on environ
if /etc/passwd
doesn't exist, or is fake (e.g. MacOS).
- const char* name
- struct pw*
- pointer to passwd entry static memory, or NULL if not found
getpwnam_r
- const char* name
- struct pw* pw
- char* buf
- unsigned long size
- struct pw** res
- struct pw* pw
- int
getpwuid
Returns password database entry for user id.
This is essentially guaranteed to succeed if uid == getuid()
, since
this implementation will generate an entry based on the environment
if /etc/passwd
doesn't exist, or is fake (e.g. MacOS).
- unsigned int uid
- struct pw*
- pointer to passwd entry static memory, or NULL if not found
getpwuid_r
- unsigned int uid
- struct pw* pw
- char* buf
- unsigned long size
- struct pw** res
- struct pw* pw
- int
getresgid
Gets real, effective, and "saved" group ids.
- unsigned int* real
- receives real user id, or null to do nothing
- unsigned int* effective
- receives effective user id, or null to do nothing
- unsigned int* saved
- receives saved user id, or null to do nothing
- int
- 0 on success or -1 w/ errno
getresuid
Gets real, effective, and "saved" user ids.
- unsigned int* real
- receives real user id, or null to do nothing
- unsigned int* effective
- receives effective user id, or null to do nothing
- unsigned int* saved
- receives saved user id, or null to do nothing
- int
- 0 on success or -1 w/ errno
getrusage
Returns resource usage statistics.
- int who
- can be RUSAGE_{SELF,CHILDREN,THREAD}
- struct rusage* usage
- int
- 0 on success, or -1 w/ errno
getservbyname_r
- const char* name
- const char* prots
- struct servent* se
- char* buf
- unsigned long buflen
- struct servent** res
- const char* prots
- int
getservbyport_r
- int port
- const char* prots
- struct servent* se
- char* buf
- unsigned long buflen
- struct servent** res
- const char* prots
- int
getsid
Creates session and sets the process group id.
- int pid
- int
getsockname
Returns details about network interface kernel granted socket.
- int fd
- struct sa* out_addr
- unsigned int* inout_addrsize
- struct sa* out_addr
- int
- 0 on success or -1 w/ errno
getsockopt
Retrieves socket setting.
- int fd
- int level
- can be SOL_SOCKET, IPPROTO_TCP, etc.
- int optname
- can be SO_{REUSE{PORT,ADDR},KEEPALIVE,etc.} etc.
- void* out_opt_optval
- unsigned int* out_optlen
- int
- 0 on success, or -1 w/ errno
out_optlen
is invalid somehow
fd
is valid but not a socket
fd
isn't valid
gettid
Returns current thread id.
On Linux, and Linux only, this is guaranteed to be equal to getpid() if this is the main thread. On NetBSD, gettid() for the main thread is always 1.
- int
- thread id greater than zero or -1 w/ errno
gettimeofday
Returns system wall time in microseconds, e.g.
int64_t t; char p[20]; struct tm tm; struct timeval tv; gettimeofday(&tv, 0); t = tv.tv_sec; gmtime_r(&t, &tm); iso8601(p, &tm); printf("%s\n", p);
- struct timeval* tv
- points to timeval that receives result if non-null
- struct timezone* tz
- is completely ignored
- int
- 0 on success, or -1 w/ errno
tv
points to invalid memory
getuid
Returns real user id of process.
This never fails. On Windows, which doesn't really have this concept, we return a hash of the username.
- unsigned int
- user id (always successful)
getwchar
Reads UTF-8 character from stream.
- unsigned int
- wide character or -1 on EOF or error
getwchar_unlocked
Reads UTF-8 character from stream.
- unsigned int
- wide character or -1 on EOF or error
getx86processormodel
Identifies microarchitecture of host processor.
- short key
- can be kX86ProcessorModelKey for host info
- struct X86ProcessorModel*
GetZipCdirComment
Returns comment of zip central directory.
- const unsigned char* eocd
- void*
GetZipCdirCommentSize
Returns comment of zip central directory.
- const unsigned char* eocd
- unsigned long
GetZipCdirOffset
Returns offset of zip central directory.
- const unsigned char* eocd
- unsigned long
GetZipCdirRecords
Returns number of records in zip central directory.
- const unsigned char* eocd
- unsigned long
GetZipCdirSize
Returns size of zip central directory.
- const unsigned char* eocd
- unsigned long
GetZipCfileCompressedSize
Returns compressed size in bytes from zip central directory header.
- const unsigned char* z
- long
GetZipCfileMode
Returns st_mode from ZIP central directory record.
- const unsigned char* p
- int
GetZipCfileTimestamps
Extracts modified/access/creation timestamps from zip entry.
- const unsigned char* cf
- is pointer to central directory header for file
- ANONYMOUS-STRUCT* mtim
- optionally receives last modified timestamp
- ANONYMOUS-STRUCT* atim
- optionally receives modified timestamp
- ANONYMOUS-STRUCT* ctim
- optionally receives creation timestamp
- int gmtoff
- is seconds adjustment for legacy dos timestamps
- void
GetZipCfileUncompressedSize
Returns uncompressed size in bytes from zip central directory header.
- const unsigned char* z
- long
GetZipEocd
Locates End Of Central Directory record in ZIP file.
The ZIP spec says this header can be anywhere in the last 64kb. We search it backwards for the ZIP-64 "PK♠•" magic number. If that's not found, then we search again for the original "PK♣♠" magnum. The caller needs to check the first four bytes of the returned value to determine whether to use ZIP_CDIR_xxx() or ZIP_CDIR64_xxx() macros.
- void* f
- points to file memory
- unsigned long n
- is byte size of file
- int* e
- may receive error code when null is returned
- void*
- pointer to EOCD64 or EOCD, otherwise null
GetZipLfileCompressedSize
Returns compressed size in bytes from zip local file header.
- const unsigned char* z
- long
GetZipLfileUncompressedSize
Returns uncompressed size in bytes from zip local file header.
- const unsigned char* z
- long
glob
Finds pathnames matching pattern.
For example:
glob_t g = {.gl_offs = 2}; glob("*.*", GLOB_DOOFFS, NULL, &g); glob("../.*", GLOB_DOOFFS | GLOB_APPEND, NULL, &g); g.gl_pathv[0] = "ls"; g.gl_pathv[1] = "-l"; execvp("ls", &g.gl_pathv[0]); globfree(g);
- const char* pat
- can have star wildcard see fnmatch()
- int flags
- int(*)() errfunc
- struct glob_t* g
- int(*)() errfunc
- will receive matching entries and needs globfree()
- int
- 0 on success or GLOB_NOMATCH, GLOB_NOSPACE on OOM, or GLOB_ABORTED on read error
GoodSocket
Returns new socket with modern goodness enabled.
- int family
- int type
- int protocol
- _Bool isserver
- struct timeval* timeout
- int type
- int
grantpt
Grants access to subordinate pseudoteletypewriter.
- int fd
- int
- 0 on success, or -1 w/ errno
HasControlCodes
Returns true if C0 or C1 control codes are present
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- int f
- can have kControlWs, kControlC0, kControlC1 to forbid
- long
- index of first forbidden character or -1
heapsort
Sorts array.
Runs in O (N lg N), both average and worst. While heapsort is faster than the worst case of quicksort, the BSD quicksort does median selection so that the chance of finding a data set that will trigger the worst case is nonexistent. Heapsort's only advantage over quicksort is that it requires little additional memory.
- void* vbase
- is base of array
- unsigned long nmemb
- is item count
- unsigned long size
- is item width
- int(*)() compar
- is a callback returning <0, 0, or >0
- int
heapsort_r
Sorts array w/ optional callback argument.
- void* vbase
- is base of array
- unsigned long nmemb
- is item count
- unsigned long size
- is item width
- int(*)() compar
- is a callback returning <0, 0, or >0
- void* z
- will optionally be passed as the third argument to cmp
- int
hexpcpy
Turns data into lowercase hex.
This routine always writes a nul terminator, even if n
is zero.
There's no failure condition for this function.
- char* s
- must have
n*2+1
bytes - void* p
- must have
n
bytes - unsigned long n
- is byte length of p
- char*
- pointer to nul byte in
s
HighwayHash64
Computes Highway Hash.
highwayhash64 n=0 121 nanoseconds highwayhash64 n=8 16 ns/byte 59,865 kb/s highwayhash64 n=31 4 ns/byte 222 mb/s highwayhash64 n=32 3 ns/byte 248 mb/s highwayhash64 n=63 2 ns/byte 387 mb/s highwayhash64 n=64 2 ns/byte 422 mb/s highwayhash64 n=128 1 ns/byte 644 mb/s highwayhash64 n=256 1 ns/byte 875 mb/s highwayhash64 n=22851 721 ps/byte 1,354 mb/s
- void* data
- unsigned long size
- const unsigned long* key
- unsigned long size
- unsigned long
hilbert
Generates Hilbert space-filling curve.
- long n
- long y
- long x
- long y
- long
iconv
- void* cd
- char** in
- unsigned long* inb
- char** out
- unsigned long* outb
- char** in
- unsigned long
IndentLines
Inserts spaces before lines.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- unsigned long j
- is number of spaces to use
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
inet_addr
Converts dotted IPv4 address string to network order binary.
- const char* s
- unsigned int
inet_aton
Converts dotted IPv4 address string to network order binary.
- const char* s0
- ANONYMOUS-STRUCT* dest
- int
inet_ntop
Formats internet address to string.
- int af
- can be AF_INET or AF_INET6
- void* src
- is the binary-encoded address, e.g. &addr->sin_addr
- char* dst
- is the output string buffer
- unsigned int size
- needs to be 16+ for IPv4 and 46+ for IPv6
- const char*
- dst on success or NULL w/ errno
inet_pton
Converts internet address string to binary.
- int af
- can be AF_INET or AF_INET6
- const char* src
- is the ASCII-encoded address
- void* dst
- is where the binary-encoded net-order address goes
- int
- 1 on success, 0 on src malformed, or -1 w/ errno
__inflate
Decompresses raw deflate data.
This uses puff by default since it has a 2kb footprint. If zlib proper is linked, then we favor that instead, since it's faster.
- void* out
- unsigned long outsize
- needs to be known ahead of time by some other means
- void* in
- unsigned long insize
- int
- 0 on success or nonzero on failure
inflateBackInit
Initialize internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized before the call. If zalloc and zfree are Z_NULL, then the default library- derived memory allocation routines are used. windowBits is the base two logarithm of the window size, in the range 8..15. window is a caller supplied buffer of that size. Except for special applications where it is assured that deflate was used with small window sizes, windowBits must be 15 and a 32K byte window must be supplied to be able to decompress general deflate streams.
See inflateBack() for the usage of these routines.
- int
- Z_OK on success, Z_STREAM_ERROR if any of the parameters are invalid, or Z_MEM_ERROR if the internal state could not be allocated.
_init
Decentralized function for process initialization.
Modules may inject cheap data structure initialization code into this function using the .init.start and .init.end macros. That code can use the LODS and STOS instructions to initialize memory that's restricted to read-only after initialization by PIRO.
This is fast, since the linker is able to roll-up initialization for large codebases comprised of many modules, into a perfectly linear order. It also enables a common pattern we use, which we call “Referencing Is Initialization” (RII).
C/C++ code should favor using ordinary constructors, since under normal circumstances the compiler will clobber RDI and RSI which are granted special meanings within this function.
- r12
- is argc (still callee saved)
- r13
- is argv (still callee saved)
- r14
- is envp (still callee saved)
- r15
- is envp (still callee saved)
__init_bss_start
Decentralized section for unpacked data structures.
Data in this section becomes read-only after initialization.
__init_rodata_start
Decentralized section for packed data structures & initializers.
initstate
- unsigned int seed
- char* state
- unsigned long size
- char* state
- char*
_intsort
Tiny and reasonably fast sorting for ints.
- int* A
- unsigned long n
- void
IsAcceptableHost
Returns true if host seems legit.
This function may be called after ParseUrl() or ParseHost() has already handled things like percent encoding. There's currently no support for IPv6 and IPv7.
Here's examples of permitted inputs:
- ""
- 1.2.3.4
- 1.2.3.4.arpa
- localservice
- hello.example
- _hello.example
- -hello.example
- hi-there.example
- ::1
- 1.2.3
- 1.2.3.4.5
- .hi.example
- hi..example
- const char* s
- unsigned long n
- if -1 implies strlen
- _Bool
IsAcceptablePath
Returns true if path seems legit.
- The substring "//" is disallowed.
- We won't serve hidden files (segment starts with '.').
The only exception is
/.well-known/
. - We won't serve paths with segments equal to "." or "..".
- const char* data
- unsigned long size
- if -1 implies strlen
- _Bool
IsAcceptablePort
Returns true if port seems legit.
Here's examples of permitted inputs:
- ""
- 0
- 65535
- -1
- 65536
- https
- const char* s
- unsigned long n
- if -1 implies strlen
- _Bool
isalnum
Returns nonzero if c is lower, alpha, or digit.
- int c
- int
IsAnonymousIp
Returns true if IPv4 address is anonymous proxy provider.
- unsigned int x
- _Bool
IsApeLoadable
Returns true if executable image is supported by APE Loader.
- char* buf
- _Bool
IsApnicIp
Returns true if IPv4 address is managed by APNIC.
- unsigned int x
- _Bool
IsArinIp
Returns true if IPv4 address is managed by ARIN.
- unsigned int x
- _Bool
isatty
Tells if file descriptor is a terminal.
- int fd
- is file descriptor
- int
- 1 if is terminal, otherwise 0 w/ errno
ischardev
Returns true if file descriptor is backed by character i/o.
This function is equivalent to:
struct stat st; return stat(path, &st) != -1 && S_ISCHR(st.st_mode);Except faster and with fewer dependencies.
- int fd
- int
IsCloudflareIp
Returns true if x
is Cloudflare IPv4 address.
- unsigned int x
- _Bool
iscntrl
Returns nonzero if c is C0 ASCII control code or DEL.
- int c
- int
IsDodIp
Returns true if IP is owned by the U.S. Department of Defense.
- unsigned int x
- _Bool
IsElf64Binary
Returns true if elf
is a 64-bit elf executable.
- struct Elf64_Ehdr* elf
- points to the start of the executable image
- unsigned long mapsize
- is the number of bytes past
elf
we can access
- int
- true if elf header looks legit
isexecutable
Returns true if file exists and is executable.
- const char* path
- int
isgraph
Returns nonzero if c is printable ascii that isn't space.
- int c
- int
islower
Returns nonzero if c is lowercase alpha ascii character.
- int c
- int
IsMimeType
Returns true if content-type 𝑡 has mime-type 𝑠.
- const char* t
- unsigned long n
- const char* s
- unsigned long n
- _Bool
IsMulticastIp
Returns true if IPv4 address is used for multicast.
- unsigned int x
- _Bool
isprint
Returns nonzero if c is printable ascii including space.
- int c
- int
IsPrivateIp
Returns true if IPv4 address is intended for private networks.
- unsigned int x
- _Bool
IsPublicIp
Returns true if IPv4 address is Globally Reachable.
We intentionally omit TEST-NET here which can be used to simulate public Internet traffic using non-Internet IPs.
- unsigned int x
- _Bool
- true 92.4499% of the time
ispunct
Returns nonzero if c ∈ !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
- int c
- int
IsQemuUser
Returns true if process is running under qemu-x86_64 or qemu-aarch64.
- int
IsReasonablePath
Returns true if path doesn't contain "." or ".." segments.
- const char* data
- unsigned long size
- if -1 implies strlen
- _Bool
IsRipeIp
Returns true if IPv4 address is managed by RIPE NCC.
- unsigned int x
- _Bool
issetugid
Determines if process is tainted.
This function returns 1 if process was launched as a result of an execve() call on a binary that had the setuid or setgid bits set. FreeBSD defines tainted as including processes that changed their effective user / group ids at some point.
- int
- always successful, 1 if yes, 0 if no
isspace
Returns nonzero if c is space, \t, \r, \n, \f, or \v.
- int c
- int
IsTestnetIp
Returns true if IPv4 address is intended for documentation.
- unsigned int x
- _Bool
istext
Returns true if buffer is most likely plaintext.
- void* data
- unsigned long size
- int
isupper
Returns nonzero if c is uppercase alpha ascii character.
- int c
- int
isutf8
Returns true if text is utf-8.
isutf8 n=0 1 nanoseconds isutf8 n=5 661 ps/byte 1,476 mb/s isutf8 ascii n=22851 26 ps/byte 35 GB/s isutf8 unicode n=3193 543 ps/byte 1,795 mb/sThis function considers all ASCII characters including NUL to be valid UTF-8. The conditions for something not being valid are:
- Incorrect sequencing of 0300 (FIRST) and 0200 (CONT) chars
- Thompson-Pike varint sequence not encodable as UTF-16
- Overlong UTF-8 encoding
- void* data
- unsigned long size
- if -1 implies strlen
- int
IsValidCookieValue
Returns true if string is a valid cookie value (any ASCII excluding control char, whitespace, double quotes, comma, semicolon, and backslash).
- const char* s
- unsigned long n
- if -1 implies strlen
- _Bool
IsValidHttpToken
Returns true if string is ASCII without delimiters.
- const char* s
- unsigned long n
- if -1 implies strlen
- _Bool
iswblank
Returns nonzero if c is space or tab.
- unsigned int c
- int
iswcntrl
Returns nonzero if c
is control code.
This includes C0 or C1 control codes, in addition to the "LINE SEPARATOR" and "PARAGRAPH SEPARATOR" characters.
- unsigned int c
- int
iswctype
Returns nonzero if c has property.
- unsigned int c
- unsigned int t
- is number returned by wctype
- int
iswdigit
Returns nonzero if c is decimal digit.
- unsigned int c
- int
iswgraph
Returns nonzero if c is printable and not a space.
- unsigned int c
- int
__isworker
Indicates if current execution context is a worker task.
Setting this to true on things like the forked process of a web server is a good idea since it'll ask the C runtime to not pull magical stunts like attaching GDB to the process on crash.
- int
iswprint
Returns nonzero if c is printable.
- unsigned int c
- int
iswspace
Returns nonzero if c is space character.
We define this as invisible characters which move the cursor. That
means \t\r\n\f\v
and unicodes whose category begins with Z
but
not ogham since it's not invisible and non-breaking spaces neither
since they're not invisible to emacs users.
- unsigned int c
- int
iswxdigit
Returns nonzero if c is ascii hex digit.
- unsigned int c
- int
IsZipEocd32
Determines if ZIP EOCD record seems legit.
- const unsigned char* p
- unsigned long n
- unsigned long i
- unsigned long n
- int
IsZipEocd64
Returns kZipOk if zip64 end of central directory header seems legit.
- const unsigned char* p
- unsigned long n
- unsigned long i
- unsigned long n
- int
__join_paths
Joins paths, e.g.
0 + 0 → 0 "" + "" → "" "a" + 0 → "a" "a" + "" → "a/" 0 + "b" → "b" "" + "b" → "b" "." + "b" → "./b" "b" + "." → "b/." "a" + "b" → "a/b" "a/" + "b" → "a/b" "a" + "b/" → "a/b/" "a" + "/b" → "/b"
- char* buf
- unsigned long size
- const char* path
- const char* other
- unsigned long size
- char*
- joined path, which may be
buf
,path
, orother
, or null if (1)buf
didn't have enough space, or (2) bothpath
andother
were null
kappendf
Appends formatted string to buffer w/ kprintf, e.g.
char *b = 0; kappendf(&b, "hello %d\n", 123); free(b);
- char** b
- const char* fmt
- ...
- const char* fmt
- long
- bytes appended or -1 if
ENOMEM
kCp437
ibm cp437 unicode table w/ string literal safety
░▄██▒▄█ ▐██ ░░░ ▀▀████▒▀█▄ ▐███▓██░ ██▌ ▀████▄■█▄ ▐█▓███▀█░██▀ ░ ░▀█████▓▄ ▐█▓██▀▄█▒██▀ ▄▄░ ▄▄▄ ░░░ ░▀████▒▄ ▐████▀▄█■█▀ ▀▀ ░█████░ ▐█▓█▀████▀ ░ ▐▓███▒ █░███▀▀ ░░░ ▄█ ░░░ █████ ▐█▓█░▀▀ ░░▄█▄▄▄▄▄ ▀▄ ▌▄▄▄░▄▄▄▄▄ ▐████░ ▐███▌ ▄▀█████████▄ ▌▐▄████████▄ ▐▓███░ ▐███░░░▀▄█▀▄▄████▄▀░ ▐████████▒ ▀ ░███░ ░████░ ▓▀ ▄███████▀▌ ▀▄■████▀▀█▀ ██▀█ ▓███░ ░▄▀▀░░░ ▀ ░░▌ ▄▀▀▄░░▀░▄▀▄ ▐██▀▄ ░███░ ▄▓▓▄▄░▀▀█▀█ ▌░░ ▀█▀█▀▀ ▐██▀ █▀▄▐██ ▀░░ ▄▀ ▐ █ ▀ ▄▄▄░ ░▀▄█▄▀█ ▌▄ █▓ ▒ ░ █▄█▄▀▄▄▄███▄▀▄ ░░ ░ ▀ █▌ █▌▄░▌ ░░░▄▀█▀███████▄▀▄▀▄▀▀▄▄▄ █▀█░▐ ██▄ ░░░▄█▄▀██▄█■██████▄█▄█▄■▀█░ ▐░▐ ▀██░ ░▄██████████████████▄█▄█ ░█ ░ ▄▀ ▀▓█▄▓░░ ▒█▀█████████████████████▒ ██▀ ▀███ ▓▒ ██████████████▀▀▀▀█▄▀ ░▄█▒ ▀███ ▀█▄▀▄█████▀▀ ▓▓▓▄░ ▐ ░▄██ ▀██ ▄███████▄████████▀░░ ░▄██ ▄██▀▀▄ █▄▀▄██▒▒███████████▀▀▀▄░ ░███░ ▄██▀▄▄░░▀▐▄████▄ █████▀▄░░█▀▄▀░░ ▄██░ █████▄▄▄███▀░█▌██▄▀▀█████▄▄░░░▄▄███▀██▄ ▄▀▀▀▄▄ ▀██████▀■▄█▄▄ ░▀███████████████▓▓░░▄██▀▄████▄▄▀▄ █▀█ █ █▀█ █▀█ █▄▀ ▐▀█▀▌█▀█ █▀█ █▄ █ ▀█▀ █▀█ █▀▀ █▀▄ █ █ █ █ █ ▀▄ █ █▀▄ █ █ █ ▀█ █ █ ▀▀█ █▄█ █▄▌█▄█ █▄█ █ █ █ █ █ █▄█ █ █ ▄█▄ █▄█ █▄█ THERE WILL BE BLOCKS march 01 2017
kCpuids
Globally precomputed CPUID.
This module lets us check CPUID in 0.06ns rather than 51.00ns. If every piece of native software linked this module, then the world would be a much better place; since all the alternatives are quite toilsome.
kHttpRepeatable
Set of standard comma-separate HTTP headers that may span lines.
These headers may specified on multiple lines, e.g.
Allow: GET Allow: POSTIs the same as:
Allow: GET, POSTStandard headers that aren't part of this set will be overwritten in the event that they're specified multiple times. For example,
Content-Type: application/octet-stream Content-Type: text/plain; charset=utf-8Is the same as:
Content-Type: text/plain; charset=utf-8This set exists to optimize header lookups and parsing. The existence of standard headers that aren't in this set is an O(1) operation. The repeatable headers in this list require an O(1) operation if they are not present, otherwise the extended headers list needs to be crawled.
Please note non-standard headers exist, e.g. Cookie, that may span multiple lines, even though they're not comma-delimited. For those headers we simply don't add them to the perfect hash table.
- _Bool[93]
grep '[A-Z][a-z]*".*":"' rfc2616
grep ':.*#' rfc2616
kill
Sends signal to process.
The impact of this action can be terminating the process, or interrupting it to request something happen.
On Windows, signals are delivered between processes using shared memory files stored in C:\ProgramData\cosmo\sig\x\y.pid which hold the process signal mask. Any process that can access these files can signal a cosmo process. The targeting process will then notice that a signal has been added and delivers to any thread as soon as possible.
On Windows, the concept of a process group isn't fully implemented.
Saying kill(0, sig)
will deliver sig
to all direct descendent
processes. Saying kill(-pid, sig)
will be the same as saying
kill(pid, sig)
.
- int pid
- can be: >0 signals one process by id =0 signals all processes in current process group -1 signals all processes possible (except init) <-1 signals all processes in -pid process group
- int sig
- can be: >0 can be SIGINT, SIGTERM, SIGKILL, SIGUSR1, etc. =0 checks both if pid exists and we can signal it
- int
- 0 if something was accomplished, or -1 w/ errno
pid
couldn't be found
proc
promised
sig
is invalid or unsupported
kNtSystemDirectory
RII constant holding 'C:/WINDOWS/SYSTEM32' directory.
kNtWindowsDirectory
RII constant holding 'C:/WINDOWS' directory.
kStartTsc
Timestamp of process start.
- unsigned long
kXedChipFeatures
Mapping of enum XedChip -> bitset<enum XedIsaSet>.
See related APIs, e.g. xed_isa_set_is_valid_for_chip().
This information can be reproduced by building Xed and running the C preprocessor on xed-chip-features-table.c (see xed-chips.txt) which turns several thousand lines of non-evolving code into fifty. For example, 0x2800000ul was calculated as: 1UL<<(XED_ISA_SET_I86-64) | 1UL<<(XED_ISA_SET_LAHF-64).
- const unsigned long[3][53]
l64a
Converts 32-bit integer to base64, the posix way.
- long x
- char*
landlock_add_rule
Adds new rule to Landlock ruleset.
- int fd
- enum rule_type rule_type
- void* rule_attr
- unsigned int flags
- enum rule_type rule_type
- int
fd
is not a file descriptor for current thread, or
member of rule_attr
is not a file descriptor as expected
fd
is not a ruleset file descriptor, or a member
of rule_attr
is not the expected file descriptor type
fd
has no write access to the underlying ruleset
rule_attr
inconsistency
landlock_create_ruleset
Create new Landlock filesystem sandboxing ruleset.
You may also use this function to query the current ABI version:
landlock_create_ruleset(0, 0, LANDLOCK_CREATE_RULESET_VERSION);
- struct landlock_ruleset_attr* attr
- unsigned long size
- unsigned int flags
- unsigned long size
- int
- close exec file descriptor for new ruleset
landlock_restrict_self
Enforces Landlock ruleset on calling thread.
- int fd
- unsigned int flags
- int
fd
isn't file descriptor for the current thread
fd
is not a ruleset file descriptor
fd
has no read access to underlying ruleset, or
current thread is not running with no_new_privs, or it doesn’t
have CAP_SYS_ADMIN in its namespace
lchmod
Changes mode of pathname, w/o dereferencing symlinks.
- const char* pathname
- unsigned int mode
- int
- 0 on success, or -1 w/ errno
lchown
Changes owner and/or group of pathname, w/o dereferencing symlinks.
- const char* pathname
- unsigned int uid
- is user id, or -1u to not change
- unsigned int gid
- is group id, or -1u to not change
- int
- 0 on success, or -1 w/ errno
ldiv
Divides integers yielding numerator and denominator.
- long num
- long den
- struct retval
LengthInt64
Returns len(str(x))
where x is a signed 64-bit integer.
- long x
- unsigned int
LengthInt64Thousands
Returns decimal string length of int64 w/ thousands separators.
- long x
- unsigned int
LengthUint64
Returns len(str(x))
where x is an unsigned 64-bit integer.
- unsigned long x
- unsigned int
LengthUint64Thousands
Returns decimal string length of uint64 w/ thousands separators.
- unsigned long x
- unsigned int
levenshtein
Computes similarity between two strings.
- const char* s0
- const char* s1
- double
lfind
- void* key
- void* base
- unsigned long* nelp
- unsigned long width
- int(*)() compar
- void* base
- void*
lgamma_r
Returns natural logarithm of absolute value of Gamma function.
- double x
- int* signgamp
- double
lgammaf_r
Returns natural logarithm of absolute value of Gamma function.
- float x
- int* signgamp
- float
link
Creates hard filesystem link.
This allows two names to point to the same file data on disk. They can only be differentiated by examining the inode number.
- const char* existingpath
- const char* newpath
- int
- 0 on success, or -1 w/ errno
linkat
Creates hard filesystem link.
This allows two names to point to the same file data on disk. They can only be differentiated by examining the inode number.
- int olddirfd
- const char* oldpath
- int newdirfd
- const char* newpath
- int flags
- const char* oldpath
- can have AT_EMPTY_PATH or AT_SYMLINK_NOFOLLOW
- int
- 0 on success, or -1 w/ errno
listen
Asks system to accept incoming connections on socket.
The socket() and bind() functions need to be called beforehand. Once this function is called, accept() is used to wait for connections. Using this on connectionless sockets will allow it to receive packets on a designated address.
- int fd
- int backlog
- <= SOMAXCONN
- int
- 0 on success or -1 w/ errno
longjmp
Loads previously saved processor state.
- rdi
- points to the jmp_buf
- esi
- is returned by setjmp() invocation (coerced nonzero)
_longsort
Sorting algorithm for longs that doesn't take long.
"What disorder is this? Give me my long sort!" -Lord Capulet
- long* A
- unsigned long n
- void
lrint
Rounds to integer in current rounding mode.
The floating-point exception FE_INEXACT
is raised if the result is
different from the input.
- double x
- long
lrintf
Rounds to integer in current rounding mode.
The floating-point exception FE_INEXACT
is raised if the result is
different from the input.
- float x
- long
lrintl
Rounds to integer in current rounding mode.
The floating-point exception FE_INEXACT
is raised if the result is
different from the input.
- long double x
- long
lsearch
- void* key
- void* base
- unsigned long* nelp
- unsigned long width
- int(*)() compar
- void* base
- void*
lseek
Changes current position of file descriptor, e.g.
int fd = open("hello.bin", O_RDONLY); lseek(fd, 100, SEEK_SET); // set position to 100th byte read(fd, buf, 8); // read bytes 100 through 107This function may be used to inspect the current position:
int64_t pos = lseek(fd, 0, SEEK_CUR);You may seek past the end of file. If a write happens afterwards then the gap leading up to it will be filled with zeroes. Please note that lseek() by itself will not extend the physical medium.
If dup() is used then the current position will be shared across multiple file descriptors. If you seek in one it will implicitly seek the other too.
The current position of a file descriptor is shared between both processes and threads. For example, if an fd is inherited across fork(), and both the child and parent want to read from it, then changes made by one are observable to the other.
The pread() and pwrite() functions obfuscate the need for having global shared file position state. Consider using them, since it helps avoid the gotchas of this interface described above.
This function is supported by all OSes within our support vector and our unit tests demonstrate the behaviors described above are consistent across platforms.
- int fd
- is a number returned by open()
- long offset
- is 0-indexed byte count w.r.t.
whence
- int whence
- can be one of:
SEEK_SET
: Sets the file position tooffset
[default]SEEK_CUR
: Sets the file position toposition + offset
SEEK_END
: Sets the file position tofilesize + offset
- long
- new position relative to beginning, or -1 w/ errno
fd
is a pipe, socket, or fifo
fd
isn't an open file descriptor
whence
isn't valid
lstat
Returns information about file, w/o traversing symlinks.
- const char* pathname
- struct stat* st
- int
lutimes
Changes file timestamps, the legacy way.
- const char* filename
- struct timeval* tv
- int
lz4decode
Decompresses LZ4 file.
We assume (1) the file is mmap()'d or was copied into into memory beforehand; and (2) folks handling untrustworthy data shall place 64kb of guard pages on the ends of each buffer, see mapanon(). We don't intend to support XXHASH; we recommend folks needing checks against data corruption consider crc32c(), or gzip since it's the best at file recovery. Dictionaries are supported; by convention, they are passed in the ≤64kb bytes preceding src.
- void* dest
- void* src
- void*
- pointer to end of decoded data, similar to mempcpy()
lz4len
Returns the uncompressed content size for a compressed LZ4 block, without actually decompressing it.
- void* blockdata
- unsigned long blocksize
- unsigned long
__magicu_get
Precomputes magic numbers for unsigned division by constant.
The returned divisor may be passed to __magic_div() to perform unsigned integer division way faster than normal division e.g.
assert(77 / 7 == __magicu_div(77, __magicu_get(7)));
- unsigned int d
- is intended divisor, which must not be zero
- struct magu
- magic divisor (never zero)
makecontext
Creates coroutine gadget, e.g.
ucontext_t uc; getcontext(&uc); uc.uc_link = 0; uc.uc_stack.ss_sp = NewCosmoStack(); uc.uc_stack.ss_size = GetStackSize(); makecontext(&uc, exit, 1, 42); setcontext(&uc);Is equivalent to:
exit(42);The safest way to allocate stack memory is to use NewCosmoStack() and GetStackSize(), which will mmap() a fresh region of memory per a link time configuration, mprotect() some guard pages at the bottom, poison them if ASAN is in play, and then tell the OS that it's stack memory. If that's overkill for your use case, then you could potentially pass stacks as small as 1024 bytes; however they need to come from a stack allocation Cosmo granted to your main process and threads. It needn't be aligned, since this function takes care of that automatically. The address selected shall be
uc_stack.ss_ip + uc_stack.ss_size
and all
the action happens beneath that address.
On AMD64 and ARM64 you may pass up to six long
integer args, and up
to six vectors (e.g. double, floats, __m128i, uint8x16_t). Thou shall
not call code created by Microsoft compilers, even though this should
work perfectly fine on Windows, as it is written in the System V ABI,
which specifies your parameters are always being passed in registers.
- struct ucontext_t* uc
- stores processor state; the caller must have:
- initialized it using
getcontext(uc)
- allocated new values for
uc->uc_stack
- specified a successor context in
uc->uc_link
- initialized it using
- void* func
- is the function to call when
uc
is activated; whenfunc
returns, control is passed touc->uc_link
, which if null will result in pthread_exit() being called - int argc
- is effectively ignored (see notes above)
- ...
- void
makedirs
Creates directory and parent components.
This function is similar to mkdir() except it iteratively creates parent directories and it won't fail if the directory already exists.
- const char* path
- is a UTF-8 string, preferably relative w/ forward slashes
- unsigned int mode
- can be, for example, 0755
- int
- 0 on success or -1 w/ errno
path
existed as non-directory
path
length exceeds PATH_MAX
path
exists longer than NAME_MAX
path
path
is an empty string
path
malloc
Allocates uninitialized memory.
Returns a pointer to a newly allocated chunk of at least n bytes, or null if no space is available, in which case errno is set to ENOMEM on ANSI C systems.
If n is zero, malloc returns a minimum-sized chunk. (The minimum size
is 32 bytes on 64bit systems.) It should be assumed that zero bytes
are possible access, since that'll be enforced by MODE=asan
.
Note that size_t is an unsigned type, so calls with arguments that would be negative if signed are interpreted as requests for huge amounts of space, which will often fail. The maximum supported value of n differs across systems, but is in all cases less than the maximum representable value of a size_t.
- unsigned long n
- void*
- new memory, or NULL w/ errno
malloc_trim
Releases freed memory back to system.
- unsigned long n
- specifies bytes of memory to leave available
- int
- 1 if it actually released any memory, else 0
malloc_usable_size
Returns the number of bytes you can actually use in an allocated chunk, which may be more than you requested (although often not) due to alignment and minimum size constraints.
You can use this many bytes without worrying about overwriting other allocated objects. This is not a particularly great programming practice. malloc_usable_size can be more useful in debugging and assertions, for example:
p = malloc(n) assert(malloc_usable_size(p) >= 256)
- void* p
- is address of allocation
- unsigned long
- total number of bytes
MapViewOfFile3
- AllocationType
- kNtMemReserve
- kNtMemReplacePlaceholder
- kNtMemLargePages
- void*
MeasureEntropy
Returns Shannon entropy of array.
This gives you an idea of the density of information. Cryptographic random should be in the ballpark of 7.9 whereas plaintext will be more like 4.5.
- const char* p
- is treated as binary octets
- unsigned long n
- should be at least 1000
- double
- number between 0 and 8
memalign
Allocates aligned memory.
Returns a pointer to a newly allocated chunk of n bytes, aligned in accord with the alignment argument. The alignment argument shall be rounded up to the nearest two power and higher 2 powers may be used if the allocator imposes a minimum alignment requirement.
- unsigned long align
- is alignment in bytes, coerced to 1+ w/ 2-power roundup
- unsigned long bytes
- is number of bytes needed, coerced to 1+
- void*
- rax is memory address, or NULL w/ errno
memcasecmp
Compares memory case-insensitively.
memcasecmp n=0 992 picoseconds memcasecmp n=1 1 ns/byte 590 mb/s memcasecmp n=2 1 ns/byte 843 mb/s memcasecmp n=3 1 ns/byte 885 mb/s memcasecmp n=4 1 ns/byte 843 mb/s memcasecmp n=5 1 ns/byte 820 mb/s memcasecmp n=6 1 ns/byte 770 mb/s memcasecmp n=7 1 ns/byte 765 mb/s memcasecmp n=8 206 ps/byte 4,724 mb/s memcasecmp n=9 220 ps/byte 4,428 mb/s memcasecmp n=15 617 ps/byte 1,581 mb/s memcasecmp n=16 124 ps/byte 7,873 mb/s memcasecmp n=17 155 ps/byte 6,274 mb/s memcasecmp n=31 341 ps/byte 2,860 mb/s memcasecmp n=32 82 ps/byte 11,810 mb/s memcasecmp n=33 100 ps/byte 9,743 mb/s memcasecmp n=80 53 ps/byte 18,169 mb/s memcasecmp n=128 49 ps/byte 19,890 mb/s memcasecmp n=256 45 ps/byte 21,595 mb/s memcasecmp n=16384 42 ps/byte 22,721 mb/s memcasecmp n=32768 40 ps/byte 24,266 mb/s memcasecmp n=131072 40 ps/byte 24,337 mb/s
- void* p
- void* q
- unsigned long n
- void* q
- int
- is <0, 0, or >0 based on uint8_t comparison
memccpy
Copies at most N bytes from SRC to DST until 𝑐 is encountered.
This is little-known C Standard Library approach, dating back to the Fourth Edition of System Five, for copying a C strings to fixed-width buffers, with added generality.
For example, strictly:
char buf[16]; CHECK_NOTNULL(memccpy(buf, s, '\0', sizeof(buf)));Or unstrictly:
if (!memccpy(buf, s, '\0', sizeof(buf))) strcpy(buf, "?");Are usually more sensible than the following:
char cstrbuf[16]; snprintf(cstrbuf, sizeof(cstrbuf), "%s", CSTR);
- void* dst
- void* src
- int c
- void* src
- is search character and is masked with 255
- unsigned long n
- void*
- DST + idx(c) + 1, or NULL if 𝑐 ∉ 𝑠₀․․ₙ₋₁
memchr
Returns pointer to first instance of character.
- void* s
- is memory to search
- int c
- is search byte which is masked with 255
- unsigned long n
- is byte length of p
- void*
- is pointer to first instance of c or NULL if not found
memchr16
Returns pointer to first instance of character in range.
- void* s
- int c
- unsigned long n
- int c
- void*
memcmp
Compares memory byte by byte.
memcmp n=0 2 nanoseconds memcmp n=1 2 ns/byte 357 mb/s memcmp n=2 1 ns/byte 530 mb/s memcmp n=3 1 ns/byte 631 mb/s 𝗺𝗲𝗺𝗰𝗺𝗽 n=4 1 ns/byte 849 mb/s memcmp n=5 816 ps/byte 1,195 mb/s memcmp n=6 888 ps/byte 1,098 mb/s memcmp n=7 829 ps/byte 1,176 mb/s 𝗺𝗲𝗺𝗰𝗺𝗽 n=8 773 ps/byte 1,261 mb/s memcmp n=9 629 ps/byte 1,551 mb/s memcmp n=15 540 ps/byte 1,805 mb/s 𝗺𝗲𝗺𝗰𝗺𝗽 n=16 211 ps/byte 4,623 mb/s memcmp n=17 268 ps/byte 3,633 mb/s memcmp n=31 277 ps/byte 3,524 mb/s memcmp n=32 153 ps/byte 6,351 mb/s memcmp n=33 179 ps/byte 5,431 mb/s memcmp n=79 148 ps/byte 6,576 mb/s 𝗺𝗲𝗺𝗰𝗺𝗽 n=80 81 ps/byte 11 GB/s memcmp n=128 76 ps/byte 12 GB/s memcmp n=256 60 ps/byte 15 GB/s memcmp n=16384 51 ps/byte 18 GB/s memcmp n=32768 51 ps/byte 18 GB/s memcmp n=131072 52 ps/byte 18 GB/s
- void* a
- void* b
- unsigned long n
- void* b
- int
- an integer that's (1) equal to zero if
a
is equal tob
, (2) less than zero ifa
is less thanb
, or (3) greater than zero ifa
is greater thanb
memfd_create
Creates anonymous file.
- const char* name
- is used for the
/proc/self/fd/FD
symlink - unsigned int flags
- can have
MFD_CLOEXEC
,MFD_ALLOW_SEALING
- int
memfrob
Memfrob implements a crypto algorithm proven to be unbreakable, without meeting its requirements concerning secrecy or length.
- void* buf
- unsigned long size
- void*
memmove
Copies memory.
memmove n=0 661 picoseconds memmove n=1 661 ps/byte 1,476 mb/s memmove n=2 330 ps/byte 2,952 mb/s memmove n=3 330 ps/byte 2,952 mb/s memmove n=4 165 ps/byte 5,904 mb/s memmove n=7 141 ps/byte 6,888 mb/s memmove n=8 82 ps/byte 11 GB/s memmove n=15 44 ps/byte 21 GB/s memmove n=16 41 ps/byte 23 GB/s memmove n=31 32 ps/byte 29 GB/s memmove n=32 31 ps/byte 30 GB/s memmove n=63 21 ps/byte 45 GB/s memmove n=64 15 ps/byte 61 GB/s memmove n=127 13 ps/byte 73 GB/s memmove n=128 31 ps/byte 30 GB/s memmove n=255 20 ps/byte 45 GB/s memmove n=256 19 ps/byte 49 GB/s memmove n=511 16 ps/byte 56 GB/s memmove n=512 17 ps/byte 54 GB/s memmove n=1023 18 ps/byte 52 GB/s memmove n=1024 13 ps/byte 72 GB/s memmove n=2047 9 ps/byte 96 GB/s memmove n=2048 9 ps/byte 98 GB/s memmove n=4095 8 ps/byte 112 GB/s memmove n=4096 8 ps/byte 109 GB/s memmove n=8191 7 ps/byte 124 GB/s memmove n=8192 7 ps/byte 125 GB/s memmove n=16383 7 ps/byte 134 GB/s memmove n=16384 7 ps/byte 134 GB/s memmove n=32767 13 ps/byte 72 GB/s memmove n=32768 13 ps/byte 72 GB/s memmove n=65535 13 ps/byte 68 GB/s memmove n=65536 14 ps/byte 67 GB/s memmove n=131071 14 ps/byte 65 GB/s memmove n=131072 14 ps/byte 64 GB/s memmove n=262143 15 ps/byte 63 GB/s memmove n=262144 15 ps/byte 63 GB/s memmove n=524287 15 ps/byte 61 GB/s memmove n=524288 15 ps/byte 61 GB/s memmove n=1048575 15 ps/byte 61 GB/s memmove n=1048576 15 ps/byte 61 GB/s memmove n=2097151 19 ps/byte 48 GB/s memmove n=2097152 27 ps/byte 35 GB/s memmove n=4194303 28 ps/byte 33 GB/s memmove n=4194304 28 ps/byte 33 GB/s memmove n=8388607 28 ps/byte 33 GB/s memmove n=8388608 28 ps/byte 33 GB/sDST and SRC may overlap.
- void* dst
- is destination
- void* src
- is memory to copy
- unsigned long n
- is number of bytes to copy
- void*
- dst
memrchr
Returns pointer to first instance of character.
- void* s
- is memory to search
- int c
- is search byte which is masked with 255
- unsigned long n
- is byte length of p
- void*
- is pointer to first instance of c or NULL if not found
memrchr16
Returns pointer to first instance of character.
- void* s
- is memory to search
- int c
- is search byte which is masked with 65535
- unsigned long n
- is number of char16_t elements in
s
- void*
- is pointer to first instance of c or NULL if not found
memset
Sets memory.
memset n=0 992 picoseconds memset n=1 992 ps/byte 984 mb/s memset n=2 330 ps/byte 2,952 mb/s memset n=3 330 ps/byte 2,952 mb/s memset n=4 165 ps/byte 5,904 mb/s memset n=7 94 ps/byte 10,333 mb/s memset n=8 124 ps/byte 7,872 mb/s memset n=15 66 ps/byte 14,761 mb/s memset n=16 62 ps/byte 15,745 mb/s memset n=31 32 ps/byte 30,506 mb/s memset n=32 20 ps/byte 47,236 mb/s memset n=63 26 ps/byte 37,198 mb/s memset n=64 20 ps/byte 47,236 mb/s memset n=127 23 ps/byte 41,660 mb/s memset n=128 12 ps/byte 75,578 mb/s memset n=255 18 ps/byte 53,773 mb/s memset n=256 12 ps/byte 75,578 mb/s memset n=511 17 ps/byte 55,874 mb/s memset n=512 12 ps/byte 75,578 mb/s memset n=1023 16 ps/byte 58,080 mb/s memset n=1024 11 ps/byte 86,375 mb/s memset n=2047 9 ps/byte 101 gb/s memset n=2048 8 ps/byte 107 gb/s memset n=4095 8 ps/byte 113 gb/s memset n=4096 8 ps/byte 114 gb/s memset n=8191 7 ps/byte 126 gb/s memset n=8192 7 ps/byte 126 gb/s memset n=16383 7 ps/byte 133 gb/s memset n=16384 7 ps/byte 131 gb/s memset n=32767 14 ps/byte 69,246 mb/s memset n=32768 6 ps/byte 138 gb/s memset n=65535 15 ps/byte 62,756 mb/s memset n=65536 15 ps/byte 62,982 mb/s memset n=131071 18 ps/byte 52,834 mb/s memset n=131072 15 ps/byte 62,023 mb/s memset n=262143 15 ps/byte 61,169 mb/s memset n=262144 16 ps/byte 61,011 mb/s memset n=524287 16 ps/byte 60,633 mb/s memset n=524288 16 ps/byte 57,902 mb/s memset n=1048575 16 ps/byte 60,405 mb/s memset n=1048576 16 ps/byte 58,754 mb/s memset n=2097151 16 ps/byte 59,329 mb/s memset n=2097152 16 ps/byte 58,729 mb/s memset n=4194303 16 ps/byte 59,329 mb/s memset n=4194304 16 ps/byte 59,262 mb/s memset n=8388607 16 ps/byte 59,530 mb/s memset n=8388608 16 ps/byte 60,205 mb/s
- void* p
- is memory address
- int c
- is masked with 255 and used as repeated byte
- unsigned long n
- is byte length
- void*
- p
memset16
Sets wide memory.
- unsigned short* p
- unsigned short c
- unsigned long n
- unsigned short c
- unsigned short*
mergesort
Sorts array.
- void* base
- unsigned long nmemb
- is item count
- unsigned long size
- is item width
- int(*)() cmp
- is a callback returning <0, 0, or >0
- int
mergesort_r
Sorts array w/ optional callback argument.
- void* base
- is base of array
- unsigned long nmemb
- is item count
- unsigned long size
- is item width
- int(*)() cmp
- is a callback returning <0, 0, or >0
- void* z
- will optionally be passed as the third argument to cmp
- int
mincore
Tells you which pages are resident in memory.
- void* addr
- unsigned long length
- unsigned char* vec
- unsigned long length
- int
mkdir
Creates directory a.k.a. folder.
mkdir o → 0 mkdir o/yo/yo/yo → -1 w/ ENOENT if o/yo is file → -1 w/ ENOTDIR if o/yo/yo/yo is dir → -1 w/ EEXIST if o/yo/yo/yo is file → -1 w/ EEXIST
- const char* path
- is a UTF-8 string, preferably relative w/ forward slashes
- unsigned int mode
- can be, for example, 0755
- int
- 0 on success or -1 w/ errno
path
existed as non-directory
path
length exceeds PATH_MAX
path
exists longer than NAME_MAX
path
path
didn't exist
path
is an empty string
path
mkdirat
Creates directory a.k.a. folder.
- int dirfd
- is normally
AT_FDCWD
but if it's an open directory and path is relative, then path becomes relative to dirfd - const char* path
- is a UTF-8 string, preferably relative w/ forward slashes
- unsigned int mode
- is permissions bits, which is usually 0755
- int
- 0 on success, or -1 w/ errno
path
is relative and dirfd
isn't AT_FDCWD
or valid
path
existed as non-directory
path
length exceeds PATH_MAX
path
exists longer than NAME_MAX
path
path
didn't exist
path
is an empty string
path
mkdtemp
Creates temporary directory, e.g.
char path[] = "/tmp/foo.XXXXXX"; mkdtemp(path); rmdir(path);
- char* template
- must end with XXXXXX which will be replaced with random text on success (and not modified on error)
- char*
- pointer to template on success, or NULL w/ errno
mknod
Creates filesystem inode.
- const char* path
- unsigned int mode
- is octal mode, e.g. 0600; needs to be or'd with one of: S_IFDIR: directory S_IFIFO: named pipe S_IFREG: regular file S_IFSOCK: named socket S_IFBLK: block device (root has authorization) S_IFCHR: character device (root has authorization)
- unsigned long dev
- it's complicated
- int
- 0 on success, or -1 w/ errno
mkostemp
Creates temporary file name and file descriptor, e.g.
char path[] = "/tmp/foo.XXXXXX"; int fd = mkostemp(path, O_CLOEXEC); printf("%s is opened as %d\n", path, fd);
- char* template
- is mutated to replace last six X's with rng
- unsigned int flags
- int
- open file descriptor r + w exclusive or -1 w/ errno
template
didn't end with XXXXXX
mkostemps
Creates temporary file name and file descriptor, e.g.
char path[] = "/tmp/foo.XXXXXX"; int fd = mkostemp(path, O_CLOEXEC); printf("%s is opened as %d\n", path, fd);
- char* template
- is mutated to replace last six X's with rng
- int suffixlen
- unsigned int flags
- int
- open file descriptor r + w exclusive or -1 w/ errno
template
didn't end with XXXXXX
mkstemp
Creates temporary file name and file descriptor, e.g.
char path[] = "/tmp/foo.XXXXXX"; int fd = mkstemp(path); printf("%s is opened as %d\n", path, fd);
- char* template
- is mutated to replace last six X's with rng
- int
- open file descriptor r + w exclusive or -1 w/ errno
template
didn't end with XXXXXX
O_CLOEXEC
, O_APPEND
, etc.
mkstemps
Creates temporary file name and file descriptor, e.g.
char path[] = "/tmp/foo.XXXXXX.txt"; int fd = mkstemps(path, 4); printf("%s is opened as %d\n", path, fd);
- char* template
- is mutated to replace last six X's with rng
- int suffixlen
- may be nonzero to permit characters after the "XXXXXX"
- int
- open file descriptor r + w exclusive or -1 w/ errno
template
(less the suffixlen
region) didn't
end with the string "XXXXXXX"
O_CLOEXEC
, O_APPEND
, etc.
suffixlen
_mktls
Allocates thread-local storage memory for new thread.
- struct CosmoTib** out_tib
- char*
- buffer that must be released with free()
modf
Returns fractional part of 𝑥.
- double x
- double* iptr
- double
mount
Mounts file system.
The following flags may be specified:
MS_RDONLY
(mount read-only)MS_NOSUID
(don't honor S_ISUID bit)MS_NODEV
(disallow special files)MS_NOEXEC
(disallow program execution)MS_SYNCHRONOUS
(writes are synced at once)MS_NOATIME
(do not update access times)MS_REMOUNT
(tune existing mounting)
MNT_ASYNC
(xnu, freebsd, openbsd, netbsd)MNT_RELOAD
(xnu, freebsd, openbsd, netbsd)MS_STRICTATIME
(linux, xnu)MS_RELATIME
(linux, netbsd)MNT_SNAPSHOT
(xnu, freebsd)MS_MANDLOCK
(linux)MS_DIRSYNC
(linux)MS_NODIRATIME
(linux)MS_BIND
(linux)MS_MOVE
(linux)MS_REC
(linux)MS_SILENT
(linux)MS_POSIXACL
(linux)MS_UNBINDABLE
(linux)MS_PRIVATE
(linux)MS_SLAVE
(linux)MS_SHARED
(linux)MS_KERNMOUNT
(linux)MS_I_VERSION
(linux)MS_LAZYTIME
(linux)MS_ACTIVE
(linux)MS_NOUSER
(linux)MS_RMT
_MASK (linux)MNT_SUIDDIR
(freebsd)MNT_NOCLUSTERR
(freebsd)MNT_NOCLUSTERW
(freebsd)
type
parameter:
"nfs"
"vfat"
"tmpfs"
"iso8601"
- const char* source
- const char* target
- const char* type
- unsigned long flags
- void* data
- const char* target
- int
msync
Synchronize memory mapping changes to disk.
Without this, there's no guarantee memory is written back to disk. Particularly on RHEL5, OpenBSD, and Windows NT.
- void* addr
- needs to be 4096-byte page aligned
- unsigned long size
- int flags
- needs MS_ASYNC or MS_SYNC and can have MS_INVALIDATE
- int
- 0 on success or -1 w/ errno
MS_SYNC
and MS_ASYNC
were both specified
flags
were passed
_mt19937
Generates random integer on [0, 2^64)-interval.
This uses the Mersenne Twister pseudorandom number generator.
- unsigned long
Mul4x4Adx
Computes 512-bit product of 256-bit and 256-bit numbers.
Instructions: 88 Total Cycles: 36 Total uOps: 120 uOps Per Cycle: 3.33 IPC: 2.44 Block RThroughput: 20.0
- rdi
- receives 8 quadword result
- rsi
- is left hand side which must have 4 quadwords
- rdx
- is right hand side which must have 4 quadwords
Mul6x6Adx
Computes 768-bit product of 384-bit and 384-bit numbers.
Instructions: 152 Total Cycles: 65 Total uOps: 260 uOps Per Cycle: 4.00 IPC: 2.34 Block RThroughput: 43.3
- rdi
- receives 8 quadword result
- rsi
- is left hand side which must have 4 quadwords
- rdx
- is right hand side which must have 4 quadwords
Mul8x8Adx
Computes 1024-bit product of 512-bit and 512-bit numbers.
Instructions: 260 Total Cycles: 98 Total uOps: 452 uOps Per Cycle: 4.61 IPC: 2.65 Block RThroughput: 75.3
- rdi
- receives 16 quadword result
- rsi
- is left hand side which must have 8 quadwords
- rdx
- is right hand side which must have 8 quadwords
nanosleep
Sleeps for relative amount of time.
- struct timespec* req
- is the duration of time we should sleep
- struct timespec* rem
- if non-null will be updated with the remainder of unslept
time when -1 w/
EINTR
is returned otherwiserem
is undefined
- int
- 0 on success, or -1 w/ errno
req->tv_nsec ∉ [0,1000000000)
rem
is updated
req
is NULL or req
/ rem
is a bad pointer
nftw
Walks file tree.
- const char* dirpath
- int(*)() fn
- int fd_limit
- int flags
- int(*)() fn
- int
- 0 on success, -1 on error, or non-zero
fn
result
nice
Changes process priority.
- int delta
- is added to current priority w/ clamping
- int
- new priority, or -1 w/ errno
__nosync
Tunes sync system call availability.
If this value is set to 0x5453455454534146, then the system calls sync(), fsync(), and fdatasync() system calls will do nothing and return success. This is intended to be used for things like making things like Python unit tests go faster because fsync is extremely slow and using tmpfs requires root privileges.
- unsigned long
ns_name_uncompress
- const unsigned char* msg
- const unsigned char* eom
- const unsigned char* src
- char* dst
- unsigned long dstsiz
- const unsigned char* eom
- int
ns_skiprr
- const unsigned char* ptr
- const unsigned char* eom
- enum section section
- int count
- const unsigned char* eom
- int
__nt2sysv
Translates function call from code built w/ MS-style compiler.
This wraps WinMain() and callback functions passed to Win32 API. Please note an intermediary jump slot is needed to set %rax.
- %rax
- is function address
- %rax,%xmm0
__on_arithmetic_overflow
Arithmetic overflow handler.
This function is provided weakly, so that programs which depend on
this library may define it themselves. This default implementation
will print a message to standard error and raise SIGTRAP. A custom
implementation may return from this function, in which case the op
shall have -fwrapv
i.e. signed two's complement behavior.
- void
open
Opens file.
This is equivalent to saying:
int fd = openat(AT_FDCWD, file, flags, ...);
- const char* file
- specifies filesystem path to open
- int flags
- ...
- int
- file descriptor, or -1 w/ errno
openatemp
Opens unique temporary file with maximum generality.
This function is similar to mkstemp() in that it does two things:
- Generate a unique filename by mutating
template
- Return a newly opened file descriptor to the name
/tmp
is being used on a
UNIX system like Super Dimensional Fortress or CPanel where multiple
hostile adverserial users may exist on a single multi-tenant system.
The substring XXXXXX is replaced with 30 bits of base32 entropy and a hundred retries are attempted in the event of collisions. The XXXXXXX pattern must be present at the end of the supplied template string.
If the generated filename needs to have a file extension (rather than
ending with random junk) then this API has the helpful suffixlen
to
specify exactly how long that suffix in the template actually is. For
example if the template is "/tmp/notes.XXXXXX.txt"
then suffixlen
should be 4
.
The flags O_RDWR | O_CREAT | O_EXCL
are always set and don't need
to be specified by the caller. It's a good idea to pass O_CLOEXEC
and some applications may want O_APPEND
. Cosmopolitan also offers
O_UNLINK
which will ensure the created file will delete itself on
close similar to calling unlink() after this function on template
which is mutated on success, except O_UNLINK
will work right when
running on Windows and it's polyfilled automatically on UNIX.
The mode
parameter should usually be 0600
to ensure owner-only
read/write access. However it may be useful to set this to 0700
when creating executable files. Please note that sometimes /tmp
is
mounted by system administrators as noexec
. It's also permissible
to pass 0
here, since the 0600
bits are always set implicitly.
### Examples
Here's an example of how to replicate the functionality of tmpfile() which creates an unnamed temporary file as an stdio handle, which is guaranteed to either not have a name (unlinked on UNIX), or shall be deleted once closed (will perform kNtFileFlagDeleteOnClose on WIN32)
char path[] = "/tmp/XXXXXX"; int fd = openatemp(AT_FDCWD, path, 0, O_UNLINK, 0); FILE *tmp = fdopen(fd, "w+");Here's an example of how to do mktemp() does, where a temporary file name is generated with pretty good POSIX and security best practices
char path[PATH_MAX+1]; const char *tmpdir = getenv("TMPDIR"); strlcpy(path, tmpdir ? tmpdir : "/tmp", sizeof(path)); strlcat(path, "/notes.XXXXXX.txt", sizeof(path)); close(openatemp(AT_FDCWD, path, 4, O_UNLINK, 0)); printf("you can use %s to store your notes\n", path);
- int dirfd
- is open directory file descriptor, which is ignored if
template
is an absolute path; orAT_FDCWD
to specify getcwd - char* template
- is a pathname relative to current directory by default, that needs to have "XXXXXX" at the end of the string; this memory must be mutable and should be owned by the calling thread; it will be modified (only on success) to return the generated filename
- int suffixlen
- may be nonzero to permit characters after the "XXXXXX"
- int flags
- could have O_APPEND, O_CLOEXEC, O_UNLINK, O_SYNC, etc.
- int mode
- is conventionally 0600, for owner-only non-exec access
- int
- exclusive open file descriptor for file at the generated path
stored to
template
, or -1 w/ errno
template
(less the suffixlen
region) didn't
end with the string "XXXXXXX"
suffixlen
was negative or too large
openpty
Opens new pseudo teletypewriter.
- int* mfd
- receives controlling tty rw fd on success
- int* sfd
- receives subordinate tty rw fd on success
- char* name
- struct linux* tio
- may be passed to tune a century of legacy behaviors
- struct winsize* wsz
- may be passed to set terminal display dimensions
- int
- 0 on success, or -1 w/ errno
ParseCidr
Parse IPv4 network address.
For example, a router address might be 10.10.10.1/24
in which case
the IP address word 0x0a0a0a01
would be returned, whose CIDR would
be 24. That means your IP address is on a network with 24 bits which
converts to a netmask 0xffffff00
by using 1u << (32 - res.cidr)
.
You may specify the IP address portion as an integer. As an example,
the value 168430081/1
would be the same as 10.10.10.1/1
- const char* s
- unsigned long n
- if -1 implies strlen
- struct c
- ip is uint32 IPv4 address, or -1 on failure
- cidr is number of bits in network, on interval [1,32]; it defaults to 32; if the return ip is -1 then cidr is undefined
ParseContentLength
Parses Content-Length header.
- const char* s
- unsigned long n
- long
- -1 on invalid or overflow, otherwise >=0 value
ParseForwarded
Parses X-Forwarded-For.
This header is used by reverse proxies. For example:
X-Forwarded-For: 203.0.110.2, 203.0.113.42:31337The port is optional and will be set to zero if absent.
- const char* s
- is input data
- unsigned long n
- if -1 implies strlen
- unsigned int* ip
- receives last/right ip on success if not NULL
- unsigned short* port
- receives port on success if not NULL
- int
- 0 on success or -1 on failure
ParseHost
Parses HTTP Host header.
The input is ISO-8859-1 which is transcoded to UTF-8. Therefore we assume percent-encoded bytes are expressed as UTF-8. Returned values might contain things like NUL characters, C0, and C1 control codes. UTF-8 isn't checked for validity and may contain overlong values. Absent can be discerned from empty by checking if the pointer is set.
This function turns an HTTP header HOST[:PORT] into two strings, one for host and the other for port. You may then call IsAcceptableHost() and IsAcceptablePort() to see if they are valid values. After that a function like sscanf() can be used to do the thing you likely thought this function would do.
This function doesn't initialize h since it's assumed this will be called conditionally after ParseRequestUri() if the host is absent. Fields unrelated to authority won't be impacted by this function.
- const char* s
- is value like
127.0.0.1
orfoo.example:80
- unsigned long n
- is byte length and -1 implies strlen
- struct Url* h
- is needs to be initialized by caller
- char*
- memory backing UrlView needing free
ParseHttpMethod
Converts HTTP method to word encoding.
For example, ParseHttpMethod("GET", -1)
will return kHttpGet
.
- const char* str
- unsigned long len
- if -1 implies strlen
- unsigned long
- word encoded method, or 0 if invalid
ParseHttpRange
Parses HTTP Range request header.
Here are some example values:
Range: bytes=0- (everything) Range: bytes=0-499 (first 500 bytes) Range: bytes=500-999 (second 500 bytes) Range: bytes=-500 (final 500 bytes) Range: bytes=0-0,-1 (first and last and always) Range: bytes=500-600,601-999 (overlong but legal)
- const char* p
- unsigned long n
- long resourcelength
- long* out_start
- long* out_length
- unsigned long n
- _Bool
ParseIp
Parse IPv4 host address.
- const char* s
- unsigned long n
- if -1 implies strlen
- long
- -1 on failure, otherwise 32-bit host-order unsigned integer
ParseParams
Parses HTTP POST key-value params.
These are similar to the parameters found in a Request-URI, except
usually submitted via an HTTP POST request. We translate +
into
space. The mime type is application/x-www-form-urlencoded.
This parser is charset agnostic. Returned values might contain things like NUL characters, NUL, control codes, and non-canonical encodings. Absent can be discerned from empty by checking if the pointer is set.
There's no failure condition for this routine. This is a permissive parser that doesn't impose character restrictions beyond what is necessary for parsing.
- const char* s
- is value like
foo=bar&x=y&z
- unsigned long n
- is byte length and -1 implies strlen
- struct params* h
- must be zeroed by caller and this appends if reused
- char*
- UrlView memory with same n needing free (h.p needs free too)
ParsePromises
Parses the arguments to pledge() into a bitmask.
- const char* promises
- unsigned long* out
- receives the integral promises mask, which zero is defined
as the set of all promises, and -1 is defined as the empty set of
promises, which is equivalent to
promises
being an empty string - unsigned long current
- int
- 0 on success, or -1 if invalid
ParseUrl
Parses URL.
This parser is charset agnostic. Percent encoded bytes are decoded for all fields (with the exception of scheme). Returned values might contain things like NUL characters, spaces, control codes, and non-canonical encodings. Absent can be discerned from empty by checking if the pointer is set.
There's no failure condition for this routine. This is a permissive
parser. This doesn't normalize path segments like .
or ..
so use
IsAcceptablePath() to check for those. No restrictions are imposed
beyond that which is strictly necessary for parsing. All the s
that is provided will be consumed to the one of the fields. Strict
conformance is enforced on some fields more than others, like scheme,
since it's the most non-deterministically defined field of them all.
Please note this is a URL parser, not a URI parser. Which means we support everything the URI spec says we should do except for the things we won't do, like tokenizing path segments into an array and then nesting another array beneath each of those for storing semicolon parameters. So this parser won't make SIP easy. What it can do is parse HTTP URLs and most URIs like s:opaque, better in fact than most things which claim to be URI parsers.
- const char* s
- is value like
/hi?x=y&z
orhttp://a.example/hi#x
- unsigned long n
- is byte length and -1 implies strlen
- struct Url* h
- is assumed to be uninitialized
- int f
- is flags which may have:
FLAGS_PLUS
to turn+
into space in query paramsFLAGS_LATIN1
to transcode ISO-8859-1 input into UTF-8
- char*
- memory backing UrlView needing free (and h.params.p too)
pclose
Closes stream created by popen().
This function may be interrupted or cancelled, however it won't actually return until the child process has terminated. Thus we always release the resource, and errors are purely advisory.
- struct FILE* f
- int
- termination status of subprocess, or -1 w/ ECHILD
perror
Writes error messages to standard error.
- const char* thing
- void
pipe
Creates file-less file descriptors for interprocess communication.
- int* pipefd
- int
- 0 on success or -1 w/ errno
pipe2
Creates file-less file descriptors for interprocess communication.
This function offers atomic operation on all supported platforms except for XNU and RHEL5 where it's polyfilled.
- int* pipefd
- is used to return (reader, writer) file descriptors
- int flags
- can have O_CLOEXEC or O_DIRECT or O_NONBLOCK
- int
- 0 on success, or -1 w/ errno and pipefd isn't modified
O_CLOEXEC
, O_NONBLOCK
, or the non-POSIX
packet mode flag O_DIRECT
, which is EINVAL
on MacOS / OpenBSD
pipefd
doesn't point to valid memory
RLIMIT_NOFILE
has been reached
pivot_root
Changes root mount.
- const char* new_root
- const char* put_old
- int
poll
Checks status on multiple file descriptors at once.
Servers that need to handle an unbounded number of client connections should just create a separate thread for each client. poll() isn't a scalable i/o solution on any platform.
One of the use cases for poll() is to quickly check if a number of file descriptors are valid. The canonical way to do this is to set events to 0 which prevents blocking and causes only the invalid, hangup, and error statuses to be checked.
On XNU, the POLLHUP and POLLERR statuses aren't checked unless either POLLIN, POLLOUT, or POLLPRI are specified in the events field. Cosmo will however polyfill the checking of POLLNVAL on XNU with the events doesn't specify any of the above i/o events.
When XNU and BSD OSes report POLLHUP, they will always set POLLIN too when POLLIN is requested, even in cases when there isn't unread data.
Your poll() function will check the status of all file descriptors before returning. This function won't block unless none of the fds had had any reportable status.
The impact shutdown() will have on poll() is a dice roll across OSes.
- struct pollfd* fds
- unsigned long nfds
- int timeout_ms
- unsigned long nfds
- if 0 means don't wait and negative waits forever
- int
- number of
fds
whose revents field has been set to a nonzero number, 0 if the timeout elapsed without events, or -1 w/ errno- fds[𝑖].revents is always zero initializaed and then will be populated with POLL{IN,OUT,PRI,HUP,ERR,NVAL} if something was determined about the file descriptor
nfds
exceeded RLIMIT_NOFILE
popcnt
Returns number of bits set in integer.
- unsigned long x
- unsigned long
posix_madvise
Advises kernel about memory intentions, the POSIX way.
- void* addr
- unsigned long len
- int advice
- unsigned long len
- int
- 0 on success, or errno on error
advice
isn't valid or supported by system
getpagesize()
posix_memalign
Allocates aligned memory, the POSIX way.
Allocates a chunk of n bytes, aligned in accord with the alignment argument. Differs from memalign() only in that it:
- Assigns the allocated memory to *pp rather than returning it
- Fails and returns EINVAL if the alignment is not a power of two
- Fails and returns ENOMEM if memory cannot be allocated
- void** pp
- receives pointer, only on success
- unsigned long alignment
- must be 2-power multiple of sizeof(void *)
- unsigned long bytes
- is number of bytes to allocate
- int
- return 0 or EINVAL or ENOMEM w/o setting errno
posix_openpt
Opens new pseudo teletypewriter.
- int flags
- int
- fd of master pty, or -1 w/ errno
- file descriptor, or -1 w/ errno
posix_spawn_file_actions_addchdir_np
Add chdir() action to spawn.
- ANONYMOUS-STRUCT** file_actions
- was initialized by posix_spawn_file_actions_init()
- const char* path
- will be safely copied
- int
- 0 on success, or errno on error
posix_spawn_file_actions_addclose
Add a close action to object.
- ANONYMOUS-STRUCT** file_actions
- was initialized by posix_spawn_file_actions_init()
- int fildes
- int
- 0 on success, or errno on error
fildes
is negative
posix_spawn_file_actions_adddup2
Add a dup2 action to object.
- ANONYMOUS-STRUCT** file_actions
- was initialized by posix_spawn_file_actions_init()
- int fildes
- int newfildes
- int
- 0 on success, or errno on error
newfildes
is negative
posix_spawn_file_actions_addfchdir_np
Add fchdir() action to spawn.
- ANONYMOUS-STRUCT** file_actions
- int fildes
- int
- 0 on success, or errno on error
fildes
is negative
posix_spawn_file_actions_addopen
Add an open action to object.
- ANONYMOUS-STRUCT** file_actions
- was initialized by posix_spawn_file_actions_init()
- int fildes
- is what open() result gets duplicated to
- const char* path
- will be safely copied
- int oflag
- unsigned int mode
- int
- 0 on success, or errno on error
fildes
is negative
posix_spawn_file_actions_destroy
Destroys posix_spawn() file actions list.
This function is safe to call multiple times.
- ANONYMOUS-STRUCT** file_actions
- was initialized by posix_spawn_file_actions_init()
- int
- 0 on success, or errno on error
posix_spawn_file_actions_init
Initializes posix_spawn() file actions list.
File actions get applied in the same order as they're registered.
- ANONYMOUS-STRUCT** file_actions
- will need posix_spawn_file_actions_destroy()
- int
- 0 on success, or errno on error
posix_spawnattr_destroy
Destroys posix_spawn() attributes object.
This function is safe to call multiple times.
- ANONYMOUS-STRUCT** attr
- was initialized by posix_spawnattr_init()
- int
- 0 on success, or errno on error
posix_spawnattr_getflags
Gets posix_spawn() flags.
- struct _posix_spawna** attr
- was initialized by posix_spawnattr_init()
- short* flags
- int
- 0 on success, or errno on error
posix_spawnattr_getpgroup
Gets process group id associated with attributes.
- struct _posix_spawna** attr
- was initialized by posix_spawnattr_init()
- int* pgroup
- receives the result on success
- int
- 0 on success, or errno on error
posix_spawnattr_getrlimit_np
Gets resource limit for spawned process.
- struct _posix_spawna** attr
- int resource
- struct rlimit* rlim
- int resource
- int
- 0 on success, or errno on error
resource
is invalid or unsupported by host
resource
is absent
posix_spawnattr_getschedparam
Gets scheduler parameter.
- struct _posix_spawna** attr
- was initialized by posix_spawnattr_init()
- struct schedparam* schedparam
- receives the result
- int
- 0 on success, or errno on error
posix_spawnattr_getschedpolicy
Gets scheduler policy that'll be used for spawned process.
- struct _posix_spawna** attr
- was initialized by posix_spawnattr_init()
- int* schedpolicy
- receives the result
- int
- 0 on success, or errno on error
posix_spawnattr_getsigdefault
Retrieves which signals will be restored to SIG_DFL
.
- struct _posix_spawna** attr
- unsigned long* sigdefault
- int
- 0 on success, or errno on error
posix_spawnattr_getsigmask
Gets signal mask for sigprocmask() in child process.
The signal mask is applied to the child process in such a way that signal handlers from the parent process can't get triggered in the child process.
- struct _posix_spawna** attr
- unsigned long* sigmask
- int
- 0 on success, or errno on error
posix_spawnattr_init
Initialize posix_spawn() attributes object with default values.
- struct _posix_spawna** attr
- needs to be passed to posix_spawnattr_destroy() later
- int
- 0 on success, or errno on error
posix_spawnattr_setflags
Sets posix_spawn() flags.
- struct _posix_spawna** attr
- was initialized by posix_spawnattr_init()
- short flags
- may have any of the following
POSIX_SPAWN_USEFORK
POSIX_SPAWN_USEVFORK
POSIX_SPAWN_RESETIDS
POSIX_SPAWN_SETPGROUP
POSIX_SPAWN_SETSIGDEF
POSIX_SPAWN_SETSIGMASK
POSIX_SPAWN_SETSCHEDPARAM
POSIX_SPAWN_SETSCHEDULER
POSIX_SPAWN_SETSID
POSIX_SPAWN_SETRLIMIT_NP
- int
- 0 on success, or errno on error
flags
has invalid bits
posix_spawnattr_setpgroup
Specifies process group into which child process is placed.
Setting pgroup
to zero will ensure newly created processes are
placed within their own brand new process group.
You also need to pass POSIX_SPAWN_SETPGROUP
to
posix_spawnattr_setflags() for it to take effect.
- struct _posix_spawna** attr
- was initialized by posix_spawnattr_init()
- int pgroup
- is the process group id, or 0 for self
- int
- 0 on success, or errno on error
posix_spawnattr_setrlimit_np
Sets resource limit on spawned process.
You also need to pass POSIX_SPAWN_SETRLIMIT_NP
to
posix_spawnattr_setflags() for it to take effect.
- struct _posix_spawna** attr
- int resource
- struct rlimit* rlim
- int resource
- int
- 0 on success, or errno on error
posix_spawnattr_setschedparam
Specifies scheduler parameter override for spawned process.
You also need to pass POSIX_SPAWN_SETSCHEDPARAM
to
posix_spawnattr_setflags() for it to take effect.
- struct _posix_spawna** attr
- was initialized by posix_spawnattr_init()
- struct schedparam* schedparam
- receives the result
- int
- 0 on success, or errno on error
posix_spawnattr_setschedpolicy
Specifies scheduler policy override for spawned process.
You also need to pass POSIX_SPAWN_SETSCHEDULER
to
posix_spawnattr_setflags() for it to take effect.
- struct _posix_spawna** attr
- was initialized by posix_spawnattr_init()
- int schedpolicy
- int
- 0 on success, or errno on error
posix_spawnattr_setsigdefault
Specifies which signals should be restored to SIG_DFL
.
This routine isn't necessary in most cases, since posix_spawn() by
default will try to avoid vfork() race conditions by tracking what
signals have a handler function and then resets them automatically
within the child process, before applying the child's signal mask.
This function may be used to ensure the SIG_IGN
disposition will
not propagate across execve in cases where this process explicitly
set the signals to SIG_IGN
earlier (since posix_spawn() will not
issue O(128) system calls just to be totally pedantic about that).
You also need to pass POSIX_SPAWN_SETSIGDEF
to
posix_spawnattr_setflags() for it to take effect.
- struct _posix_spawna** attr
- const unsigned long* sigdefault
- int
- 0 on success, or errno on error
posix_spawnattr_setsigmask
Specifies signal mask for sigprocmask() in child process.
You also need to pass POSIX_SPAWN_SETSIGMASK
to
posix_spawnattr_setflags() for it to take effect.
- struct _posix_spawna** attr
- const unsigned long* sigmask
- int
- 0 on success, or errno on error
posix_spawnp
Spawns process the POSIX way w/ PATH search.
- int* pid
- is non-NULL and will be set to child pid in parent
- const char* path
- of executable is PATH searched unless it contains a slash
- ANONYMOUS-STRUCT** file_actions
- ANONYMOUS-STRUCT** attrp
- char** argv
- char** envp
- ANONYMOUS-STRUCT** attrp
- int
- 0 on success or error number on failure
ppoll
Checks status on multiple file descriptors at once.
This function is the same as saying:
sigset_t old; sigprocmask(SIG_SETMASK, sigmask, &old); poll(fds, nfds, timeout); sigprocmask(SIG_SETMASK, old, 0);Except it happens atomically when the kernel supports doing that. On kernels such as XNU and NetBSD which don't, this wrapper will fall back to using the example above. If you need ironclad assurances of signal mask atomicity, then consider using pselect() which Cosmo Libc guarantees to be atomic on all supported platforms.
Servers that need to handle an unbounded number of client connections should just create a separate thread for each client. poll(), ppoll() and select() aren't scalable i/o solutions on any platform.
On Windows it's only possible to poll 64 file descriptors at a time; it's a limitation imposed by WSAPoll(). Cosmopolitan Libc's ppoll() polyfill can go higher in some cases; for example, It's possible to poll 64 sockets and 64 pipes/terminals at the same time. Furthermore, elements whose fd field is set to a negative number are ignored and will not count against this limit.
One of the use cases for poll() is to quickly check if a number of file descriptors are valid. The canonical way to do this is to set events to 0 which prevents blocking and causes only the invalid, hangup, and error statuses to be checked.
On XNU, the POLLHUP and POLLERR statuses aren't checked unless either POLLIN, POLLOUT, or POLLPRI are specified in the events field. Cosmo will however polyfill the checking of POLLNVAL on XNU with the events doesn't specify any of the above i/o events.
When XNU and BSD OSes report POLLHUP, they will always set POLLIN too when POLLIN is requested, even in cases when there isn't unread data.
- struct pollfd* fds
- unsigned long nfds
- struct ts* timeout
- unsigned long nfds
- if null will block indefinitely
- const unsigned long* sigmask
- may be null in which case no mask change happens
- int
- number of
fds
whose revents field has been set to a nonzero number, 0 if the timeout elapsed without events, or -1 w/ errno- fds[𝑖].revents is always zero initializaed and then will be populated with POLL{IN,OUT,PRI,HUP,ERR,NVAL} if something was determined about the file descriptor
nfds
exceeded RLIMIT_NOFILE
*timeout
is invalid
pread
Reads from file at offset.
This function never changes the current position of fd
.
- int fd
- is something open()'d earlier, noting pipes might not work
- void* buf
- is copied into, cf. copy_file_range(), sendfile(), etc.
- unsigned long size
- is always saturated to 0x7ffff000 automatically
- long offset
- is bytes from start of file at which read begins
- long
- [1..size] bytes on success, 0 on EOF, or -1 w/ errno; with exception of size==0, in which case return zero means no error
fd
isn't seekable
offset
is negative
fd
isn't an open file descriptor
printf
Formats and writes text to stdout.
Cosmopolitan supports most of the standard formatting behaviors
described by man 3 printf
, in addition to the following
%jjd
,%jjx
, etc. are {,u}int128_t (cosmopolitan only)%'d
or%,d
may be used to insert thousands separators. The prior is consistent with C; the latter is consistent with Python.%m
inserts strerror(errno) into the formatted output. This is consistent with glibc, musl, and uclibc.%hs
converts UTF-16/UCS-2 → UTF-8, which can be helpful on Windows. Formatting (e.g. %-10hs) will use monospace display width rather than string length or codepoint count.%ls
(or%Ls
) converts UTF-32 → UTF-8. Formatting (e.g. %-10ls) will use monospace display width rather than string length.- The
%#s
and%#c
alternate forms display values using the standard IBM standard 256-letter alphabet. Using%#.*s
to specify length will allow true binary (i.e. with NULs) to be formatted. - The
%'s
and%'c
alternate forms are Cosmopolitan extensions for escaping string literals for C/C++ and Python. The outer quotation marks can be added automatically using%`s
. If constexpr format strings are used, we can avoid linking cescapec() too. - The backtick modifier (
%`s
and%`c
) and repr() directive (%r
) both ask the formatting machine to represent values as real code rather than using arbitrary traditions for displaying values. This means it implies the quoting modifier, wraps the value with {,u,L}['"] quotes, displays NULL as "NULL" rather than "(null)".
- const char* fmt
- ...
- int
PrintWindowsMemory
Prints to stderr all memory mappings that exist according to WIN32.
The high
and size
parameters may optionally be specified so that
memory mappings which overlap [high,high+size)
will get printed in
ANSI bold red text.
- const char* high
- unsigned long size
- void
program_invocation_name
Supplies argv[0] the GNU way.
If argv[0] isn't supplied, this value will be null.
pselect
Checks status on multiple file descriptors at once.
This function is the same as saying:
sigset_t old; sigprocmask(SIG_SETMASK, sigmask, &old); select(nfds, readfds, writefds, exceptfds, timeout); sigprocmask(SIG_SETMASK, old, 0);Except it happens atomically. Unlike ppoll() Cosmo guarantees this is atomic on all supported platforms.
- int nfds
- is the number of the highest file descriptor set in these
bitsets by the caller, plus one; this value can't be greater than
FD_SETSIZE
which Cosmopolitan currently defines as 1024 becausefd_set
has a static size - struct old_exceptfds* readfds
- may be used to be notified when you can call read() on a file descriptor without it blocking; this includes when data is is available to be read as well as eof and error conditions
- struct old_exceptfds* writefds
- may be used to be notified when write() may be called on a file descriptor without it blocking
- struct old_exceptfds* exceptfds
- may be used to be notified of exceptional conditions such as out-of-band data on a socket; it is equivalent to POLLPRI in the revents of poll()
- struct timespec* timeout
- if null will block indefinitely
- const unsigned long* sigmask
- may be null in which case no mask change happens
- int
pthread_atfork
Registers fork() handlers.
Parent and child functions are called in the same order they're registered. Prepare functions are called in reverse order.
Here's an example of how pthread_atfork() can be used:
static struct { pthread_once_t once; pthread_mutex_t lock; // data structures... } g_lib; static void lib_wipe(void) { pthread_mutex_init(&g_lib.lock, 0); } static void lib_lock(void) { pthread_mutex_lock(&g_lib.lock); } static void lib_unlock(void) { pthread_mutex_unlock(&g_lib.lock); } static void lib_setup(void) { lib_wipe(); pthread_atfork(lib_lock, lib_unlock, lib_wipe); } static void lib_init(void) { pthread_once(&g_lib.once, lib_setup); } void lib(void) { lib_init(); lib_lock(); // do stuff... lib_unlock(); }
- void(*)() prepare
- is run by fork() before forking happens
- void(*)() parent
- is run by fork() after forking happens in parent process
- void(*)() child
- is run by fork() after forking happens in childe process
- int
- 0 on success, or errno on error
pthread_attr_destroy
Destroys pthread attributes.
- struct pthread_attr_t* attr
- int
- 0 on success, or errno on error
pthread_attr_getdetachstate
Gets thread detachable attribute.
- struct pthread_attr_t* attr
- int* detachstate
- is set to one of the following
PTHREAD_CREATE_JOINABLE
(default)PTHREAD_CREATE_DETACHED
- int
- 0 on success, or error on failure
pthread_attr_getguardsize
Returns size of protected region at bottom of thread stack.
- struct pthread_attr_t* attr
- unsigned long* guardsize
- will be set to guard size in bytes
- int
- 0 on success, or errno on error
pthread_attr_getinheritsched
Returns thread inherit schedule attribute.
- struct pthread_attr_t* attr
- int* inheritsched
- int
pthread_attr_getschedparam
Gets thread scheduler parameter attribute.
- struct pthread_attr_t* attr
- struct sched_param* param
- int
pthread_attr_getschedpolicy
Gets thread scheduler policy attribute
- struct pthread_attr_t* attr
- int* policy
- int
pthread_attr_getscope
Gets contention scope attribute.
- struct pthread_attr_t* attr
- int* contentionscope
- int
- 0 on success, or errno on error
pthread_attr_getsigaltstack_np
Returns configuration for thread signal stack.
- struct pthread_attr_t* attr
- void** stackaddr
- will be set to signal stack address
- unsigned long* stacksize
- int
- 0 on success, or errno on error
pthread_attr_getsigaltstacksize_np
Returns size of thread signal stack.
This defaults to zero, which means that cosmo won't allocate a managed signal stack for newly created threads.
- struct pthread_attr_t* a
- unsigned long* stacksize
- int
- 0 on success, or errno on error
pthread_attr_getsigmask_np
Gets signal mask on thread attributes object.
- struct pthread_attr_t* attr
- is the thread attributes object
- unsigned long* sigmask
- will receive the output signal mask on success, or null if a simple presence check is desired
- int
- 0 on success, errno on error, or
PTHREAD_ATTR_NO_SIGMASK_NP
if there wasn't any signal mask present inattr
pthread_attr_getstack
Returns configuration for thread stack.
This is a getter for a configuration attribute. By default, zeros are returned. If pthread_attr_setstack() was called earlier, then this'll return those earlier supplied values.
- struct pthread_attr_t* attr
- void** stackaddr
- will be set to stack address in bytes
- unsigned long* stacksize
- int
- 0 on success, or errno on error
pthread_attr_getstacksize
Returns size of thread stack.
This defaults to GetStackSize().
- struct pthread_attr_t* a
- unsigned long* x
- will be set to stack size in bytes
- int
- 0 on success, or errno on error
pthread_attr_setdetachstate
Sets thread detachable attribute, e.g.
pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(0, &attr, func, 0); pthread_attr_destroy(&attr);
- struct pthread_attr_t* attr
- int detachstate
- can be one of
PTHREAD_CREATE_JOINABLE
(default)PTHREAD_CREATE_DETACHED
- int
- 0 on success, or error on failure
detachstate
is invalid
pthread_attr_setguardsize
Sets size of protected region at bottom of thread stack.
Cosmopolitan sets this value to sysconf(_SC_PAGESIZE)
by default.
You may set guardsize
to disable the stack guard feature and gain a
slight performance advantage by avoiding mprotect() calls. Note that
it could make your code more prone to silent unreported corruption.
- struct pthread_attr_t* attr
- unsigned long guardsize
- contains guard size in bytes, which is implicitly
rounded up to
sysconf(_SC_PAGESIZE)
, or zero to disable
- int
- 0 on success, or errno on error
pthread_attr_setinheritsched
Sets thread scheduler inheritance attribute, e.g.
pthread_t id; pthread_attr_t attr; pthread_attr_init(&attr); struct sched_param pri = {sched_get_priority_min(SCHED_OTHER)}; pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(&attr, SCHED_OTHER); pthread_attr_setschedparam(&attr, &pri); pthread_create(&id, &attr, func, 0); pthread_attr_destroy(&attr); pthread_join(id, 0);
- struct pthread_attr_t* attr
- int inheritsched
- may be one of:
PTHREAD_INHERIT_SCHED
the defaultPTHREAD_EXPLICIT_SCHED
to enable rescheduling
- int
- 0 on success, or errno on error
pthread_attr_setschedparam
Sets thread scheduler parameter attribute, e.g.
pthread_t id; pthread_attr_t attr; pthread_attr_init(&attr); struct sched_param pri = {sched_get_priority_min(SCHED_OTHER)}; pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(&attr, SCHED_OTHER); pthread_attr_setschedparam(&attr, &pri); pthread_create(&id, &attr, func, 0); pthread_attr_destroy(&attr); pthread_join(id, 0);
- struct pthread_attr_t* attr
- struct sched_param* param
- specifies priority on scheduling policies that need it
- int
pthread_attr_setschedpolicy
Sets thread scheduler policy attribute, e.g.
pthread_t id; pthread_attr_t attr; pthread_attr_init(&attr); struct sched_param pri = {sched_get_priority_min(SCHED_OTHER)}; pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(&attr, SCHED_OTHER); pthread_attr_setschedparam(&attr, &pri); pthread_create(&id, &attr, func, 0); pthread_attr_destroy(&attr); pthread_join(id, 0);
- struct pthread_attr_t* attr
- int policy
- may be one of:
SCHED_OTHER
the default policySCHED_FIFO
for real-time scheduling (usually needs root)SCHED_RR
for round-robin scheduling (usually needs root)SCHED_IDLE
for lowest effort (Linux and FreeBSD only)SCHED_BATCH
for "batch" style execution of processes if supported (Linux), otherwise it's treated asSCHED_OTHER
- int
pthread_attr_setscope
Sets contention scope attribute.
- struct pthread_attr_t* attr
- int contentionscope
- may be one of:
PTHREAD_SCOPE_SYSTEM
to fight the system for resourcesPTHREAD_SCOPE_PROCESS
to fight familiar threads for resources
- int
- 0 on success, or errno on error
contentionscope
isn't supported on host OS
contentionscope
was invalid
pthread_attr_setsigaltstack_np
Defines user-owned signal stack for thread.
- struct pthread_attr_t* attr
- void* stackaddr
- unsigned long stacksize
- void* stackaddr
- int
pthread_attr_setsigaltstacksize_np
Defines size of cosmo-owned signal stack for thread.
The sigaltstack() function is useful for writing robust programs that can recover from the occasional thread having a stack overflow rather than having the entire process crash. To use it normally, sigaltstack needs to be called at the start of each thread with a unique piece of memory. However this is challenging to do *correctly* without support from the POSIX threads runtime, since canceled or crashed threads may need to execute on the signal stack during pthread_exit() which would prevent a thread-local storage key destructor from free()'ing it.
By default pthread_create() will not install a sigaltstack() on newly created threads. If this function is called, on the attributes object that gets passed to pthread_create(), then it'll use malloc() to make a stack for the thread using the size you specify here. The threading runtime will also free that memory safely after complete termination.
pthread_t id; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setguardsize(&attr, getpagesize()); pthread_attr_setsigaltstacksize_np(&attr, stacksize); pthread_create(&id, &attr, func, 0); pthread_attr_destroy(&attr); pthread_join(id, 0);Try using a size of
sysconf(_SC_SIGSTKSZ)
. If you want the smallest
size possible, then sysconf(_SC_MINSIGSTKSZ) + 2048
is probably the
smallest value that can reasonably expected to work with pthread_exit
struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO | SA_ONSTACK; sa.sa_sigaction = on_crash_signal; sigaction(SIGSEGV, &sa, 0);Please note that in order for this to work, your handlers for signals such as SIGSEGV and SIGBUS need to use SA_ONSTACK in your sa_flags.
- struct pthread_attr_t* a
- unsigned long stacksize
- contains stack size in bytes, or 0 to disable
- int
- 0 on success, or errno on error
stacksize
is less than sysconf(_SC_MINSIGSTKSZ)
pthread_attr_setsigmask_np
Sets signal mask on thread attributes object.
For example, to spawn a thread that won't interfere with signals:
pthread_t id; sigset_t mask; pthread_attr_t attr; sigfillset(&mask); pthread_attr_init(&attr); pthread_attr_setsigmask_np(&attr, &mask); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&id, &attr, Worker, 0); pthread_attr_destroy(&attr);
- struct pthread_attr_t* attr
- is the thread attributes object
- const unsigned long* sigmask
- will be copied into attributes, or if it's null, then the existing signal mask presence on the object will be cleared
- int
- 0 on success, or errno on error
pthread_attr_setstack
Configures custom allocated stack for thread, e.g.
pthread_t id; pthread_attr_t attr; char *stk = NewCosmoStack(); pthread_attr_init(&attr); pthread_attr_setstack(&attr, stk, GetStackSize()); pthread_create(&id, &attr, func, 0); pthread_attr_destroy(&attr); pthread_join(id, 0); FreeCosmoStack(stk);Your stack must have at least
PTHREAD_STACK_MIN
bytes, which
Cosmpolitan Libc defines as GetStackSize()
. It's a link-time
constant used by Actually Portable Executable that's 128 kb by
default. See libc/runtime/stack.h for docs on your stack limit
since the APE ELF phdrs are the one true source of truth here.
Cosmpolitan Libc runtime magic (e.g. ftrace) and memory safety
(e.g. kprintf) assumes that stack sizes are two-powers and are
aligned to that two-power. Conformance isn't required since we
say caveat emptor to those who don't maintain these invariants
please consider using NewCosmoStack(), which is always perfect
or use mmap(0, GetStackSize() << 1, ...)
for a bigger stack.
Unlike pthread_attr_setstacksize(), this function permits just about any parameters and will change the values and allocation as needed to conform to the mandatory requirements of the host operating system even if it doesn't meet the stricter needs of Cosmopolitan Libc userspace libraries. For example with malloc allocations, things like page size alignment, shall be handled automatically for compatibility with existing codebases.
The same stack shouldn't be used for two separate threads. Use fresh stacks for each thread so that ASAN can be much happier.
- struct pthread_attr_t* attr
- void* stackaddr
- is address of stack allocated by caller, and may be NULL in which case default behavior is restored
- unsigned long stacksize
- is size of caller allocated stack
- int
- 0 on success, or errno on error
pthread_attr_setstacksize
Defines minimum stack size for thread.
- struct pthread_attr_t* a
- unsigned long stacksize
- contains stack size in bytes
- int
- 0 on success, or errno on error
stacksize
is less than PTHREAD_STACK_MIN
pthread_barrier_destroy
Destroys barrier.
- struct pthread_barrier_t* barrier
- int
- 0 on success, or error on failure
pthread_barrier_init
Initializes barrier.
- struct pthread_barrier_t* barrier
- const char* attr
- may be null
- unsigned int count
- is how many threads need to call pthread_barrier_wait() before the barrier is released, which must be greater than zero
- int
- 0 on success, or error number on failure
count
isn't greater than zero
pthread_barrier_wait
Waits for all threads to arrive at barrier.
When the barrier is broken, the state becomes reset to what it was when pthread_barrier_init() was called, so that the barrior may be used again in the same way.
Unlike pthread_cond_timedwait() this function is not a cancelation point. It is not needed to have cleanup handlers on block cancels.
- struct pthread_barrier_t* barrier
- int
- 0 on success,
PTHREAD_BARRIER_SERIAL_THREAD
to one lucky thread which was the last arrival, or an errno on error
pthread_barrierattr_destroy
Destroys barrier attributes.
- char* attr
- int
- 0 on success, or error on failure
pthread_barrierattr_init
Initializes barrier attributes.
- char* attr
- int
- 0 on success, or error on failure
pthread_cleanup_push
- struct _pthread_cleanup_buffer* cb
- void(*)() routine
- void* arg
- void(*)() routine
- void
pthread_cond_broadcast
Wakes all threads waiting on condition, e.g.
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // ... pthread_mutex_lock(&lock); pthread_cond_broadcast(&cond); pthread_mutex_unlock(&lock);This function has no effect if there aren't any threads currently waiting on the condition.
- struct pthread_cond_t* cond
- int
- 0 on success, or errno on error
pthread_cond_destroy
Destroys condition.
- struct pthread_cond_t* cond
- int
- 0 on success, or error number on failure
pthread_cond_init
Initializes condition variable.
- struct pthread_cond_t* cond
- struct pthread_condattr_t* attr
- may be null
- int
- 0 on success, or error number on failure
pthread_cond_signal
Wakes at least one thread waiting on condition, e.g.
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // ... pthread_mutex_lock(&lock); pthread_cond_signal(&cond); pthread_mutex_unlock(&lock);This function has no effect if there aren't any threads currently waiting on the condition.
- struct pthread_cond_t* cond
- int
- 0 on success, or errno on error
pthread_cond_wait
Waits for condition, e.g.
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // ... pthread_mutex_lock(&lock); pthread_cond_wait(&cond, &lock); pthread_mutex_unlock(&lock);
- struct pthread_cond_t* cond
- struct pthread_mutex_t* mutex
- needs to be held by thread when calling this function
- int
- 0 on success, or errno on error
mutex
is PTHREAD_MUTEX_ERRORCHECK
and the lock
isn't owned by the current thread
pthread_condattr_destroy
Destroys condition attributes.
- struct pthread_condattr_t* attr
- int
- 0 on success, or error on failure
pthread_condattr_getclock
Gets clock on condition variable attributes.
- struct pthread_condattr_t* attr
- int* clock
- will be set to one of
CLOCK_REALTIME
(default)CLOCK_MONOTONIC
CLOCK_REALTIME_COARSE
CLOCK_MONOTONIC_COARSE
- int
- 0 on success, or error on failure
pthread_condattr_init
Initializes condition attributes.
- struct pthread_condattr_t* attr
- int
- 0 on success, or error on failure
pthread_condattr_setclock
Sets clock for condition variable.
- struct pthread_condattr_t* attr
- int clock
- can be one of
CLOCK_REALTIME
(default)CLOCK_MONOTONIC
CLOCK_REALTIME_COARSE
CLOCK_MONOTONIC_COARSE
- int
- 0 on success, or error on failure
clock
is invalid
pthread_decimate_np
Garbage collects POSIX threads runtime.
Let's say you want to run a memory leak detector. You can say:
while (!pthread_orphan_np()) pthread_decimate_np();To wait until all threads have exited.
- int
- 0 on success, or errno on error
pthread_delay_np
Delays execution for brief moment.
- void* symbol
- may be used to strace names of static locks
- int backoff
- should start at zero and be feed back in
- int
- new value for backoff
pthread_equal
Compares thread ids;
- unsigned long t1
- unsigned long t2
- int
- nonzero if equal, otherwise zero
pthread_getname_np
Gets name of thread registered with system, e.g.
char name[64]; pthread_getname_np(thread, name, sizeof(name));If the thread doesn't have a name, then empty string is returned. This implementation guarantees
buf
is always modified, even on
error, and will always be nul-terminated. If size
is 0 then this
function returns 0. Your buf
is also chomped to remove newlines.
- unsigned long thread
- char* name
- unsigned long size
- char* name
- int
- 0 on success, or errno on error
size
wasn't large enough, in which case your
result will still be returned truncated if possible
pthread_getschedparam
Gets most recently set scheduling of thread.
- unsigned long thread
- int* policy
- struct sched_param* param
- int* policy
- int
pthread_getunique_np
Returns system thread id of POSIX thread.
- unsigned long thread
- int* out_tid
- int
- 0 on success, or errno on error
pthread_join
Waits for thread to terminate.
Multiple threads joining the same thread is undefined behavior. If a deferred or masked cancelation happens to the calling thread either before or during the waiting process then the target thread will not be joined. Calling pthread_join() on a non-joinable thread, e.g. one that's been detached, is undefined behavior. If a thread attempts to join itself, then the behavior is undefined.
- unsigned long thread
- void** value_ptr
- if non-null will receive pthread_exit() argument
if the thread called pthread_exit(), or
PTHREAD_CANCELED
if pthread_cancel() destroyed the thread instead
- int
- 0 on success, or errno on error
pthread_key_create
Allocates TLS slot.
This function creates a thread-local storage registration, that will
apply to all threads. The new identifier is written to key
, and it
can be passed to the pthread_setspecific() and pthread_getspecific()
functions to set and get its associated value. Each thread will have
its key value initialized to zero upon creation. It is also possible
to use pthread_key_delete() to unregister a key.
If dtor
is non-null, then it'll be called upon pthread_exit() when
the key's value is nonzero. The key's value is set to zero before it
is called. The ordering of multiple destructor calls is unspecified.
The same key can be destroyed PTHREAD_DESTRUCTOR_ITERATIONS
times,
in cases where it gets set again by a destructor.
- unsigned int* key
- is set to the allocated key on success
- void(*)() dtor
- specifies an optional destructor callback
- int
- 0 on success, or errno on error
PTHREAD_KEYS_MAX
keys exist
pthread_key_delete
Deletes TLS slot.
This function should only be called if all threads have finished
using the key registration. If a key is used after being deleted
then the behavior is undefined. If k
was not registered by the
pthread_key_create() function then the behavior is undefined.
- unsigned int k
- int
- 0 on success, or errno on error
key
is invalid
pthread_kill
Sends signal to thread.
- unsigned long thread
- int sig
- int
- 0 on success, or errno on error
tid
was valid but no such thread existed
RLIMIT_SIGPENDING
was exceeded
sig
wasn't a legal signal
pthread_mutex_destroy
Destroys mutex.
Destroying a mutex that's currently locked or being waited upon, will result in undefined behavior.
- struct pthread_mutex_t* mutex
- int
- 0 on success, or error number on failure
pthread_mutex_init
Initializes mutex, e.g.
pthread_mutex_t lock; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); pthread_mutex_init(&lock, &attr); pthread_mutexattr_destroy(&attr); // ... pthread_mutex_destroy(&lock);
- struct pthread_mutex_t* mutex
- struct pthread_mutexattr_t* attr
- may be null
- int
- 0 on success, or error number on failure
pthread_mutex_lock
Locks mutex.
Here's an example of using a normal mutex:
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&lock); // do work... pthread_mutex_unlock(&lock); pthread_mutex_destroy(&lock);Cosmopolitan permits succinct notation for normal mutexes:
pthread_mutex_t lock = {0}; pthread_mutex_lock(&lock); // do work... pthread_mutex_unlock(&lock);Here's an example of the proper way to do recursive mutexes:
pthread_mutex_t lock; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&lock, &attr); pthread_mutexattr_destroy(&attr); pthread_mutex_lock(&lock); // do work... pthread_mutex_unlock(&lock); pthread_mutex_destroy(&lock);This function does nothing in vfork() children.
You can debug locks the acquisition of locks by building your program
with cosmocc -mdbg
and passing the --strace
flag to your program.
This will cause a line to be logged each time a mutex or spin lock is
locked or unlocked. When locking, this is printed after the lock gets
acquired. The entry to the lock operation will be logged too but only
if the lock couldn't be immediately acquired. Lock logging works best
when mutex
refers to a static variable, in which case its name will
be printed in the log.
- struct __fds_lock_obj* mutex
- int
- 0 on success, or error number on failure
pthread_mutex_trylock
Attempts acquiring lock.
Unlike pthread_mutex_lock() this function won't block and instead returns an error immediately if the lock couldn't be acquired.
- struct pthread_mutex_t* mutex
- int
- 0 if lock was acquired, otherwise an errno
mutex
doesn't refer to an initialized lock
mutex
is PTHREAD_MUTEX_ERRORCHECK
and the
current thread already holds this mutex
pthread_mutex_unlock
Releases mutex.
This function does nothing in vfork() children.
- struct __fds_lock_obj* mutex
- int
- 0 on success or error number on failure
pthread_mutexattr_destroy
Destroys mutex attr.
- struct pthread_mutexattr_t* attr
- int
- 0 on success, or error number on failure
pthread_mutexattr_gettype
Gets mutex type.
- struct pthread_mutexattr_t* attr
- int* type
- will be set to one of these on success
PTHREAD_MUTEX_NORMAL
PTHREAD_MUTEX_RECURSIVE
PTHREAD_MUTEX_ERRORCHECK
- int
- 0 on success, or error on failure
pthread_mutexattr_init
Initializes mutex attr.
- struct pthread_mutexattr_t* attr
- int
- 0 on success, or error number on failure
pthread_mutexattr_settype
Sets mutex type.
- struct pthread_mutexattr_t* attr
- int type
- can be one of
PTHREAD_MUTEX_NORMAL
PTHREAD_MUTEX_RECURSIVE
PTHREAD_MUTEX_ERRORCHECK
- int
- 0 on success, or error on failure
type
is invalid
pthread_once
Ensures initialization function is called exactly once, e.g.
static void *g_factory; static void InitFactory(void) { g_factory = expensive(); } void *GetFactory(void) { static pthread_once_t once = PTHREAD_ONCE_INIT; pthread_once(&once, InitFactory); return g_factory; }If multiple threads try to initialize at the same time, then only a single one will call
init
and the other threads will block until
the winner has returned from the init
function.
- struct pthread_once_t* once
- void(*)() init
- int
- 0 on success, or errno on error
pthread_rwlock_destroy
Destroys read-write lock.
- struct pthread_rwlock_t* rwlock
- int
- 0 on success, or error number on failure
pthread_rwlock_init
Initializes read-write lock.
- struct pthread_rwlock_t* rwlock
- const char* attr
- may be null
- int
- 0 on success, or error number on failure
pthread_rwlock_rdlock
Acquires read lock on read-write lock.
- struct pthread_rwlock_t* rwlock
- int
- 0 on success, or errno on error
pthread_rwlock_tryrdlock
Attempts acquiring read lock on read-write lock.
- struct pthread_rwlock_t* rwlock
- int
- 0 if lock was acquired, otherwise an errno
rwlock
doesn't refer to an initialized r/w lock
pthread_rwlock_trywrlock
Attempts acquiring write lock on read-write lock.
- struct pthread_rwlock_t* rwlock
- int
- 0 if lock was acquired, otherwise an errno
rwlock
doesn't refer to an initialized r/w lock
pthread_rwlock_unlock
Unlocks read-write lock.
- struct pthread_rwlock_t* rwlock
- int
- 0 on success, or errno on error
pthread_rwlock_wrlock
Acquires write lock on read-write lock.
- struct pthread_rwlock_t* rwlock
- int
- 0 on success, or errno on error
pthread_rwlockattr_destroy
Destroys read-write lock attributes.
- char* attr
- int
- 0 on success, or error on failure
pthread_rwlockattr_init
Initializes read-write lock attributes.
- char* attr
- int
- 0 on success, or error on failure
pthread_setcanceltype
Sets cancelation strategy.
- int type
- may be one of:
PTHREAD_CANCEL_DEFERRED
(default)PTHREAD_CANCEL_ASYNCHRONOUS
- int* oldtype
- optionally receives old value
- int
- 0 on success, or errno on error
type
has bad value
pthread_setname_np
Registers custom name of thread with system, e.g.
void *worker(void *arg) { pthread_setname_np(pthread_self(), "justine"); pause(); return 0; } int main(int argc, char *argv[]) { pthread_t id; pthread_create(&id, 0, worker, 0); pthread_join(id, 0); }ProTip: The
htop
software is good at displaying thread names.
- unsigned long thread
- const char* name
- int
- 0 on success, or errno on error
name
exceeded system limit, in which
case the name may have still been set with os using truncation
pthread_setschedparam
Changes scheduling of thread, e.g.
struct sched_param p = {sched_get_priority_min(SCHED_OTHER)}; pthread_setschedparam(thread, SCHED_OTHER, &p);
- unsigned long thread
- int policy
- may be one of:
SCHED_OTHER
the default policySCHED_FIFO
for real-time scheduling (usually needs root)SCHED_RR
for round-robin scheduling (usually needs root)SCHED_IDLE
for lowest effort (Linux and FreeBSD only)SCHED_BATCH
for "batch" style execution of processes if supported (Linux), otherwise it's treated asSCHED_OTHER
- struct sched_param* param
- int
pthread_setschedprio
Sets scheduler parameter on thread.
- unsigned long thread
- int prio
- int
pthread_sigmask
Examines and/or changes blocked signals on current thread.
- int how
- const unsigned long* set
- unsigned long* old
- const unsigned long* set
- int
- 0 on success, or errno on error
pthread_spin_destroy
Destroys spin lock.
- struct pthread_spinlock_t* spin
- int
- 0 on success, or errno on error
pthread_spin_init
Initializes spin lock.
- struct pthread_spinlock_t* spin
- int pshared
- is ignored, since this implementation always permits multiple processes to operate on the same spin locks
- int
- 0 on success, or errno on error
pthread_spin_lock
Acquires spin lock, e.g.
pthread_spinlock_t lock; pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE); pthread_spin_lock(&lock); // do work... pthread_spin_unlock(&lock); pthread_spin_destroy(&lock);This function has undefined behavior when
spin
wasn't intialized or
was destroyed, and if the lock is already held by the calling thread.
You can debug locks the acquisition of locks by building your program
with cosmocc -mdbg
and passing the --strace
flag to your program.
This will cause a line to be logged each time a mutex or spin lock is
locked or unlocked. When locking, this is printed after the lock gets
acquired. The entry to the lock operation will be logged too but only
if the lock couldn't be immediately acquired. Lock logging works best
when mutex
refers to a static variable, in which case its name will
be printed in the log.
- struct pthread_spinlock_t* spin
- int
- 0 on success, or errno on error
pthread_spin_trylock
Acquires spin lock if available.
This function has undefined behavior when spin
wasn't intialized,
was destroyed, or if the lock's already held by the calling thread.
- struct pthread_spinlock_t* spin
- int
- 0 on success, or errno on error
pthread_spin_unlock
Releases spin lock.
Calling this function when the lock isn't held by the calling thread has undefined behavior.
- struct pthread_spinlock_t* spin
- int
- 0 on success, or errno on error
pthread_yield_np
Yields current thread's remaining timeslice to operating system.
- int
- 0 on success, or error number on failure
ptrace
Traces process.
This API is terrible. Consider using sys_ptrace().
- int request
- can be PTRACE_xxx
- ...
- long
ptsname
Gets name subordinate pseudoteletypewriter.
- int fd
- char*
- static string path on success, or NULL w/ errno
ptsname_r
Gets name subordinate pseudoteletypewriter.
- int fd
- char* buf
- unsigned long size
- char* buf
- int
- 0 on success, or errno on error
putchar
Writes byte to stdout.
- int c
- int
- c (as unsigned char) if written or -1 w/ errno
putchar_unlocked
Writes byte to stdout.
- int c
- int
- c (as unsigned char) if written or -1 w/ errno
puts
Writes string w/ trailing newline to stdout.
- const char* s
- int
- non-negative number on success, or
EOF
on error witherrno
set and theferror(stdout)
state is updated
puts_unlocked
Writes string w/ trailing newline to stdout.
- const char* s
- int
- non-negative number on success, or
EOF
on error witherrno
set and theferror(stdout)
state is updated
putwc_unlocked
Writes wide character to stream.
- int wc
- struct FILE* f
- unsigned int
- wc if written or -1 w/ errno
putwchar
Writes wide character to stdout.
- int wc
- unsigned int
- wc if written or -1 w/ errno
putwchar_unlocked
Writes wide character to stdout.
- int wc
- unsigned int
- wc if written or -1 w/ errno
pwrite
Writes to file at offset.
This function never changes the current position of fd
.
- int fd
- is something open()'d earlier, noting pipes might not work
- void* buf
- is copied from, cf. copy_file_range(), sendfile(), etc.
- unsigned long size
- is always saturated to 0x7ffff000 automatically
- long offset
- is bytes from start of file at which write begins, which can exceed or overlap the end of file, in which case your file will be extended
- long
- [1..size] bytes on success, or -1 w/ errno; noting zero is impossible unless size was passed as zero to do an error check
qsort
Sorts array.
This implementation uses the Quicksort routine from Bentley & McIlroy's "Engineering a Sort Function", 1992, Bell Labs.
This version differs from Bentley & McIlroy in the following ways:
- The partition value is swapped into a[0] instead of being stored out of line.
- The swap function can swap 32-bit aligned elements on 64-bit platforms instead of swapping them as byte-aligned.
- It uses David Musser's introsort algorithm to fall back to heapsort(3) when the recursion depth reaches 2*lg(n + 1). This avoids quicksort's quadratic behavior for pathological input without appreciably changing the average run time.
- Tail recursion is eliminated when sorting the larger of two subpartitions to save stack space.
- void* a
- is base of array
- unsigned long n
- is item count
- unsigned long es
- is item width
- int(*)() cmp
- is a callback returning <0, 0, or >0
- void
qsort_r
Sorts array w/ optional callback parameter.
- void* a
- is base of array
- unsigned long n
- is item count
- unsigned long es
- is item width
- int(*)() cmp
- is a callback returning <0, 0, or >0
- void* arg
- is passed to callback
- void
raise
Sends signal to self.
This is basically the same as:
pthread_kill(pthread_self(), sig);Note
SIG_DFL
still results in process death for most signals.
POSIX defines raise() errors as returning non-zero and makes setting
errno
optional. Every platform we've tested in our support vector
returns -1 with errno
on error (like a normal system call).
- int sig
- can be SIGALRM, SIGINT, SIGTERM, SIGKILL, etc.
- int
- 0 on success, or -1 w/ errno
sig
is invalid
rand
Returns 31-bit linear congruential pseudorandom number, e.g.
int x = rand(); assert(x >= 0);This function always returns a positive number. If srand() isn't called, then it'll return the same sequence each time your program runs. Faster and more modern alternatives exist to this function.
This function is not thread safe in the sense that multiple threads might simultaneously generate the same random values.
- int
rawmemchr
Returns pointer to first instance of character.
- void* s
- int c
- is search byte which is masked with 255
- void*
- is pointer to first instance of c
rawmemchr16
Returns pointer to first instance of character in range.
- void* s
- int c
- void*
rdrand
Retrieves 64-bits of hardware random data from RDRAND instruction.
If RDRAND isn't available (we check CPUID and we also disable it automatically for microarchitectures where it's slow or buggy) then we try getrandom(), ProcessPrng(), or sysctl(KERN_ARND). If those aren't available then we try /dev/urandom and if that fails, we try getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid().
- unsigned long
rdseed
Retrieves 64-bits of true random data from RDSEED instruction.
If RDSEED isn't available, we'll try RDRAND (which we automatically disable for microarchitectures where it's known to be slow or buggy). If RDRAND isn't available then we try getrandom(), ProcessPrng(), or sysctl(KERN_ARND). If those aren't available then we try /dev/urandom and if that fails, we use RDTSC and getpid().
- unsigned long
read
Reads data from file descriptor.
This function changes the current file position. For documentation on file position behaviors and gotchas, see the lseek() function. This function may be used on socket file descriptors, including on Windows.
- int fd
- is something open()'d earlier
- void* buf
- is copied into, cf. copy_file_range(), sendfile(), etc.
- unsigned long size
- is always saturated to 0x7ffff000 automatically
- long
- [1..size] bytes on success, 0 on EOF, or -1 w/ errno; with exception of size==0, in which case return zero means no error
fd
is negative or not an open file descriptor
fd
is open in O_WRONLY
mode
size
is nonzero and buf
points to bad memory
fd
is a socket and it isn't connected
O_NONBLOCK
is in play and read needs to block,
or SO_RCVTIMEO
is in play and the time interval elapsed
readansi
Reads single keystroke or control sequence from character device.
When reading ANSI UTF-8 text streams, characters and control codes are oftentimes encoded as multi-byte sequences. This function knows how long each sequence is, so that each read consumes a single thing from the underlying file descriptor, e.g.
"a" ALFA "\316\261" ALPHA "\e[38;5;202m" ORANGERED "\e[A" UP "\e\e[A" ALT-UP "\001" CTRL-ALFA "\e\001" ALT-CTRL-ALFA "\eOP" PF1 "\000" NUL "\e]rm -rf /\e\\" OSC "\302\233A" UP "\300\200" NULThis routine generalizes to ascii, utf-8, chorded modifier keys, function keys, color codes, c0/c1 control codes, cursor movement, mouse movement, etc.
Userspace buffering isn't required, since ANSI escape sequences and UTF-8 are decoded without peeking. Noncanonical overlong encodings can cause the stream to go out of sync. This function recovers such events by ignoring continuation bytes at the beginning of each read.
- int fd
- char* p
- is guaranteed to receive a NUL terminator if n>0
- unsigned long n
- long
- number of bytes read (helps differentiate "\0" vs. "")
readlink
Reads symbolic link.
- const char* path
- must be a symbolic link pathname
- char* buf
- will receive symbolic link contents, and won't be modified unless the function succeeds (with the exception of no-malloc nt) and this buffer will *not* be nul-terminated
- unsigned long bufsiz
- long
- number of bytes written to buf, or -1 w/ errno; if the return is equal to bufsiz then truncation may have occurred
readlinkat
Reads symbolic link.
This does *not* nul-terminate the buffer.
- int dirfd
- is normally AT_FDCWD but if it's an open directory and file is a relative path, then file is opened relative to dirfd
- const char* path
- must be a symbolic link pathname
- char* buf
- will receive symbolic link contents, and won't be modified unless the function succeeds (with the exception of no-malloc nt) and this buffer will *not* be nul-terminated
- unsigned long bufsiz
- long
- number of bytes written to buf, or -1 w/ errno; if the return is equal to bufsiz then truncation may have occurred
path
didn't exist
path
length exceeds PATH_MAX
path
exists longer than NAME_MAX
path
when dirfd
isn't open or AT_FDCWD
readv
Reads data to multiple buffers.
This is the same thing as read() except it has multiple buffers. This yields a performance boost in situations where it'd be expensive to stitch data together using memcpy() or issuing multiple syscalls. This wrapper is implemented so that readv() calls where iovlen<2 may be passed to the kernel as read() instead. This yields a 100 cycle performance boost in the case of a single small iovec.
It's possible for file write request to be partially completed. For
example, if the sum of iov
lengths exceeds 0x7ffff000 then bytes
beyond that will be ignored. This is a Linux behavior that Cosmo
polyfills across platforms.
- int fd
- struct iovec* iov
- int iovlen
- struct iovec* iov
- long
- number of bytes actually read, or -1 w/ errno
_real1
Generates number on [0,1]-real-interval, e.g.
double x = _real1(lemur64())
- unsigned long x
- double
_real2
Generates number on [0,1)-real-interval, e.g.
double x = _real2(lemur64())
- unsigned long x
- double
_real3
Generates number on (0,1)-real-interval, e.g.
double x = _real3(lemur64())
- unsigned long x
- double
realloc
Allocates / resizes / frees memory, e.g.
Returns a pointer to a chunk of size n that contains the same data as does chunk p up to the minimum of (n, p's size) bytes, or null if no space is available.
If p is NULL, then realloc() is equivalent to malloc().
If p is not NULL and n is 0, then realloc() shrinks the allocation to
zero bytes. The allocation isn't freed and still continues to be a
uniquely allocated piece of memory. However it should be assumed that
zero bytes can be accessed, since that's enforced by MODE=asan
.
The returned pointer may or may not be the same as p. The algorithm prefers extending p in most cases when possible, otherwise it employs the equivalent of a malloc-copy-free sequence.
Please note that p is NOT free()'d should realloc() fail, thus:
if ((p2 = realloc(p, n2))) { p = p2; ... } else { ... }if n is for fewer bytes than already held by p, the newly unused space is lopped off and freed if possible.
The old unix realloc convention of allowing the last-free'd chunk to be used as an argument to realloc is not supported.
- void* p
- is address of current allocation or NULL
- unsigned long n
- is number of bytes needed
- void*
- rax is result, or NULL w/ errno w/o free(p)
realloc_in_place
Resizes the space allocated for p to size n, only if this can be done without moving p (i.e., only if there is adjacent space available if n is greater than p's current allocated size, or n is less than or equal to p's size). This may be used instead of plain realloc if an alternative allocation strategy is needed upon failure to expand space, for example, reallocation of a buffer that must be memory-aligned or cleared. You can use realloc_in_place to trigger these alternatives only when needed.
- void* p
- is address of current allocation
- unsigned long n
- is number of bytes needed
- void*
- rax is result, or NULL w/ errno
reallocarray
Manages array memory, the BSD way.
- void* ptr
- may be NULL for malloc() behavior
- unsigned long nmemb
- may be 0 for free() behavior; shrinking is promised too
- unsigned long itemsize
- void*
- new address or NULL w/ errno and ptr is NOT free()'d
realpath
Returns absolute pathname.
This function removes /./
and /../
components. If any individual
path component is a symbolic link, then it'll be resolved. Any slash
characters that repeat (e.g. //
) will collapse into one (i.e. /
)
This implementation is consistent with glibc, in that "//"
becomes
"/"
unlike Musl Libc, which considers that special (not sure why?)
This is the only change Cosmopolitan Libc made vs. Musl's realpath()
aside from also being permissive about backslashes, to help Windows.
- const char* filename
- is the path that needs to be resolved
- char* resolved
- needs PATH_MAX bytes, or NULL to use malloc()
- char*
- resolved path, or NULL w/ errno
filename
is NULL
filename
is an empty string
resolved
is NULL and malloc() failed
filename
didn't exist
PATH_MAX
reboot
Reboots system.
The howto
argument may be one of the following:
RB_AUTOBOOT
RB_POWER_OFF
RB_HALT_SYSTEM
RB_SW_SUSPEND
(linux and windows only)RB_KEXEC
(linux only)RB_ENABLE_CAD
(linux only)RB_DISABLE_CAD
(linux only)
sync()
operation before the reboot happens.
This can be prevented by or'ing howto
with RB_NOSYNC
. Setting
this option will also prevent apps on Windows from having time to
close themselves.
- int howto
- int
recv
Receives data from network socket.
Calling recv(fd, p, n, 0)
is equivalent to read(fd, p, n)
.
Unlike files where the OS tries very hard to fulfill the entire
requested size
before returning, read operations on sockets aim to
return as quickly as possible. For example, if 10 bytes are requested
and a packet comes in with only 5 bytes, then recv() will most likely
return those 5 bytes before waiting longer. The MSG_WAITALL
flag
may be passed when waiting longer is desired. In that case, short
reads should only be possible when the connection status changes or
the receive operation is interrupted by a signal.
- int fd
- is the file descriptor returned by socket()
- void* buf
- is where received network data gets copied
- unsigned long size
- is the byte capacity of buf
- int flags
- can have
MSG_OOB
,MSG_PEEK
,MSG_DONTWAIT
,MSG_WAITALL
- long
- number of bytes received, 0 on remote close, or -1 w/ errno
flags
MSG_WAITALL
and MSG_PEEK
were both passed
fd
is an invalid file descriptor
MSG_DONTWAIT
was passed and no data was available
O_NONBLOCK
is in play and no data was available
recvfrom
Receives data from network.
This function blocks unless MSG_DONTWAIT is passed. In that case, the non-error EWOULDBLOCK might be returned. It basically means we didn't wait around to learn an amount of bytes were written that we know in advance are guaranteed to be atomic.
- int fd
- is the file descriptor returned by socket()
- void* buf
- is where received network data gets copied
- unsigned long size
- is the byte capacity of buf
- int flags
- can have
MSG_OOB
,MSG_PEEK
, andMSG_DONTWAIT
- struct sa* opt_out_srcaddr
- receives the binary ip:port of the data's origin
- unsigned int* opt_inout_srcaddrsize
- is srcaddr capacity which gets updated
- long
- number of bytes received, 0 on remote close, or -1 w/ errno
recvmsg
Sends a message from a socket.
Note: Ancillary data currently isn't polyfilled across platforms.
- int fd
- is the file descriptor returned by socket()
- struct msg2* msg
- is a pointer to a struct msghdr containing all the allocated
buffers where to store incoming data.
- int flags
- MSG_OOB, MSG_DONTROUTE, MSG_PARTIAL, MSG_NOSIGNAL, etc.
- long
- number of bytes received, or -1 w/ errno
remainderl
Returns remainder of dividing 𝑥 by 𝑦.
- long double x
- long double y
- long double
remove
Deletes "file" or empty directory associtaed with name.
- const char* name
- int
- 0 on success or -1 w/ errno
remquol
Computes remainder and part of quotient.
- long double x
- long double y
- int* quo
- long double y
- long double
rename
Moves file the Unix way.
This is generally an atomic operation with the file system, since all
it's doing is changing a name associated with an inode. However, that
means rename() doesn't permit your oldpathname
and newpathname
to
be on separate file systems, in which case this returns EXDEV. That's
also the case on Windows.
- const char* oldpathname
- const char* newpathname
- int
- 0 on success or -1 w/ errno
renameat
Renames files relative to directories.
This is generally an atomic operation with the file system, since all
it's doing is changing a name associated with an inode. However, that
means rename() doesn't permit your oldpathname
and newpathname
to
be on separate file systems, in which case this returns EXDEV. That's
also the case on Windows.
- int olddirfd
- is normally AT_FDCWD but if it's an open directory and oldpath is relative, then oldpath become relative to dirfd
- const char* oldpath
- int newdirfd
- is normally AT_FDCWD but if it's an open directory and newpath is relative, then newpath become relative to dirfd
- const char* newpath
- int
- 0 on success, or -1 w/ errno
ReplenishTokens
Atomically increments all signed bytes in array, without overflowing.
Under the token bucket model, operations are denied by default unless tokens exist to allow them. This function must be called periodically from a single background thread to replenish the buckets with tokens. For example, this function may be called once per second which allows one operation per second on average with bursts up to 127 per second. This policy needn't be applied uniformly. For example, you might find out that a large corporation funnels all their traffic through one ip address, so you could replenish their tokens multiple times a second.
- _Atomic unsigned long* w
- is word array that aliases byte token array
- unsigned long n
- is number of 64-bit words in
w
array
- void
res_querydomain
- const char* name
- const char* domain
- int class
- int type
- unsigned char* dest
- int len
- const char* domain
- int
rewind
Moves standard i/o stream to beginning of file.
Like fseek(), this function can be used to restore a stream from the EOF state, without reopening it.
- struct FILE* f
- void
rint
Rounds to integer in current rounding mode.
The floating-point exception FE_INEXACT
is raised if the result is
different from the input.
- double x
- double
rintf
Rounds to integer in current rounding mode.
The floating-point exception FE_INEXACT
is raised if the result is
different from the input.
- float x
- float
rldecode
Thirteen byte decompressor.
- di
- points to output buffer
- si
- points to uint8_t {len₁,byte₁}, ..., {0,0}
_rlinit_vesa
Routine to activate additional VESA functionality if the user holds down a magic key, when booting from bare metal.
- CF = 0 if we decided to set a new video mode, CF = 1 otherwise
rmdir
Deletes empty directory.
- const char* path
- int
- 0 on success, or -1 w/ errno
rmrf
Recursively removes file or directory.
- const char* path
- int
- 0 on success, or -1 w/ errno
rngset
Fills memory with random bytes, e.g.
char buf[512]; rngset(buf, sizeof(buf), 0, 0);If reseed is zero then the internal PRNG is disabled and bytes are simply copied in little-endian order from the seed function. If seed is NULL then the reseed parameter is used as the seed value for the internal PRNG. If seed!=NULL and reseed>8 then reseed is the number of bytes after which the seed() function should be called again, to freshen up the PRNG.
The main advantage of this generator is that it produces data at 13 gigabytes per second since Vigna's Algorithm vectorizes better than alternatives, going even faster than xorshift.
- void* b
- unsigned long n
- unsigned long(*)() seed
- unsigned long reseed
- unsigned long n
- void*
- original buf
rt_end
- double* r_ent
- double* r_chisq
- double* r_mean
- double* r_montepicalc
- double* r_scc
- double* r_chisq
- void
rusage_add
Accumulates resource statistics in y
to x
.
- struct rusage* x
- struct rusage* y
- void
scandir
- const char* path
- struct dirent*** res
- int(*)() sel
- int(*)() cmp
- struct dirent*** res
- int
scanf
Standard input decoder.
- const char* fmt
- ...
- int
sched_get_priority_max
Returns maximum sched_param::sched_priority
for policy
.
- int policy
- int
- priority, or -1 w/ errno
policy
is invalid
sched_get_priority_min
Returns minimum sched_param::sched_priority
for policy
.
- int policy
- int
- priority, or -1 w/ errno
policy
is invalid
sched_getcpu
Returns ID of CPU on which thread is currently scheduled.
This function is supported on the following platforms:
- x86-64 - Linux: rdtsc - FreeBSD: rdtsc - Windows: win32 - OpenBSD: unsupported - NetBSD: unsupported - MacOS: unsupported
- aarch64 - Linux: syscall - FreeBSD: syscall - MacOS: supported
- int
- cpu number on success, or -1 w/ errno
sched_getparam
Gets scheduler policy parameter.
- int pid
- struct p* param
- int
- 0 on success, or -1 w/ errno
sched_getscheduler
Gets scheduler policy for pid
.
- int pid
- is the id of the process whose scheduling policy should be
queried. Setting
pid
to zero means the same thing as getpid(). This applies to all threads associated with the process. Linux is special; the kernel treats this as a thread id (noting thatgetpid() == gettid()
is always the case on Linux for the main thread) and will only take effect for the specified tid.
- int
- scheduler policy, or -1 w/ errno
pid
not found
pid
is negative on Linux
sched_rr_get_interval
Returns round-robin SCHED_RR
quantum for pid
.
- int pid
- is id of process (where 0 is same as getpid())
- struct timespec* tp
- receives output interval
- int
- 0 on success, or -1 w/ errno
tp
memory is invalid
pid
pid
sched_setparam
Sets scheduler policy parameter.
- int pid
- struct sched_param* param
- int
- 0 on success, or -1 w/ errno
sched_setscheduler
Sets scheduling policy of process, e.g.
struct sched_param p = {sched_get_priority_max(SCHED_OTHER)}; LOGIFNEG1(sched_setscheduler(0, SCHED_OTHER, &p));Processes with numerically higher priority values are scheduled before processes with numerically lower priority values.
- int pid
- is the id of the process whose scheduling policy should be
changed. Setting
pid
to zero means the same thing as getpid(). This applies to all threads associated with the process. Linux is special; the kernel treats this as a thread id (noting thatgetpid() == gettid()
is always the case on Linux for the main thread) and will only take effect for the specified tid. - int policy
- specifies the kernel's timesharing strategy.
The
policy
must have one of:SCHED_OTHER
(orSCHED_NORMAL
) for the default policySCHED_RR
for real-time round-robin schedulingSCHED_FIFO
for real-time first-in first-out schedulingSCHED_BATCH
for "batch" style execution of processes if supported (Linux), otherwise it's treated asSCHED_OTHER
SCHED_IDLE
for running very low priority background jobs if it's supported (Linux), otherwise this isSCHED_OTHER
. Pledging away scheduling privilege is permanent for your process; if a subsequent attempt is made to restore theSCHED_OTHER
policy then this system call willEPERM
(but on older kernels like RHEL7 this isn't the case). This policy isn't available on old Linux kernels like RHEL5, where it'll raiseEINVAL
.
policy
may optionally bitwise-or any one of:SCHED_RESET_ON_FORK
will cause the scheduling policy to be automatically reset toSCHED_NORMAL
upon fork() if supported; otherwise this flag is polyfilled as zero, so that it may be safely used (without having to check if the o/s is Linux).
- struct sched_param* param
- must be set to the scheduler parameter, which should be
greater than or equal to sched_get_priority_min(policy) and less
than or equal to sched_get_priority_max(policy). Linux allows the
static priority range 1 to 99 for the
SCHED_FIFO
andSCHED_RR
policies, and the priority 0 is used for the remaining policies. You should still consider calling the function, because on NetBSD the correct priority might be -1.
- int
- the former scheduling policy of the specified process. If this function fails, then the scheduling policy is not changed, and -1 w/ errno is returned.
param
is NULL
policy
is invalid
param
has value out of ranges defined by policy
seccomp
Tunes Linux security policy.
This system call was first introduced in Linux 3.17. We polyfill automatically features like SECCOMP_SET_MODE_STRICT, for kernels dating back to 2.6.23, whenever possible.
- unsigned int operation
- unsigned int flags
- void* args
- unsigned int flags
- int
secure_getenv
Returns environment variable, securely.
This is the same as getenv() except it'll return null if current process is a setuid / setgid program.
- const char* name
- is environment variable key name, which may not be null
- char*
select
Checks status on multiple file descriptors at once.
- int nfds
- struct fd_set* readfds
- may be used to be notified when you can call read() on a file descriptor without it blocking; this includes when data is is available to be read as well as eof and error conditions
- struct fd_set* writefds
- may be used to be notified when write() may be called on a file descriptor without it blocking
- struct fd_set* exceptfds
- may be used to be notified of exceptional conditions such as out-of-band data on a socket; it is equivalent to POLLPRI in the revents of poll()
- struct timeval* timeout
- may be null which means to block indefinitely; cosmo's implementation of select() never modifies this parameter which is how most platforms except Linux work which modifies it to reflect elapsed time, noting that POSIX permits either behavior therefore portable code should assume that timeout memory becomes undefined
- int
sem_close
Closes named semaphore.
Calling sem_close() on a semaphore not created by sem_open() has
undefined behavior. Using sem
after calling sem_close() from either
the current process or forked processes sharing the same address is
also undefined behavior. If any threads in this process or forked
children are currently blocked on sem
then calling sem_close() has
undefined behavior.
- struct sem_t* sem
- was created with sem_open()
- int
- 0 on success, or -1 w/ errno
sem_getvalue
Returns semaphore value.
- struct sem_t* sem
- was created by sem_init()
- int* sval
- receives output value
- int
- 0 on success, or -1 w/ errno
sem_init
Initializes unnamed semaphore.
Calling sem_init() on an already initialized semaphore is undefined.
- struct sem_t* sem
- should make its way to sem_destroy() if this succeeds
- int pshared
- if semaphore may be shared between processes, provided
sem
is backed bymmap(MAP_ANONYMOUS | MAP_SHARED)
memory - unsigned int value
- is initial count of semaphore
- int
- 0 on success, or -1 w/ errno
value
exceeds SEM_VALUE_MAX
sem_open
Initializes and opens named semaphore.
This function tracks open semaphore objects within a process. When a process calls sem_open() multiple times with the same name, then the same shared memory address will be returned, unless it was unlinked.
- const char* name
- is arbitrary string that begins with a slash character
- int oflag
- can have any of:
O_CREAT
to create the named semaphore if it doesn't exist, in which case two additional arguments must be suppliedO_EXCL
to raiseEEXIST
if semaphore already exists
- ...
- struct sem_t*
- semaphore object which needs sem_close(), or SEM_FAILED w/ errno
name
would be O_CREAT
ed
oflag
has bits other than O_CREAT | O_EXCL
value
is negative or exceeds SEM_VALUE_MAX
O_CREAT|O_EXCL
is used and semaphore exists
RLIMIT_NOFILE
has been reached
sem_unlink
Removes named semaphore.
This causes the file resource to be deleted. If processes have this semaphore currently opened, then on platforms like Windows deletion may be postponed until the last process calls sem_close().
- const char* name
- can be absolute path or should be component w/o slashes
- int
- 0 on success, or -1 w/ errno
cpath
promise
sem_wait
Locks semaphore.
- struct sem_t* sem
- int
- 0 on success, or -1 w/ errno
sem
is invalid
send
Sends data to network socket.
Calling send(fd, p, n, 0)
is equivalent to write(fd, p, n)
.
On Windows, calling send() or write() on a socket in O_NONBLOCK
mode will block. This is done for many reasons. First, most UNIX OSes
have a similar behavior, due to how little code checks the return
status of write(). Secondly, WIN32 has bugs that prevent us from
canceling an overlapped WSASend() operation safely. Programs that
want to avoid send() blocking should call poll() beforehand with the
POLLOUT flag to test when the socket can safely be written without
blocking. It's also possible to pass MSG_DONTWAIT
via flags
in
which case send() will do this for you automatically.
- int fd
- is the file descriptor returned by socket()
- void* buf
- is the data to send, which we'll copy if necessary
- unsigned long size
- is the byte-length of buf
- int flags
- can have
MSG_OOB
,MSG_DONTROUTE
, andMSG_DONTWAIT
- long
- number of bytes transmitted, or -1 w/ errno
sendmsg
Sends a message on a socket.
- int fd
- is the file descriptor returned by socket()
- struct msghdr* msg
- is a pointer to a struct msghdr containing all the required
parameters (the destination address, buffers, ...)
- int flags
- MSG_OOB, MSG_DONTROUTE, MSG_PARTIAL, MSG_NOSIGNAL, etc.
- long
- number of bytes transmitted, or -1 w/ errno
sendto
Sends data over network.
This function blocks unless MSG_DONTWAIT is passed. In that case, the non-error EWOULDBLOCK might be returned. It basically means we didn't wait around to learn an amount of bytes were written that we know in advance are guaranteed to be atomic.
- int fd
- is the file descriptor returned by socket()
- void* buf
- is the data to send, which we'll copy if necessary
- unsigned long size
- is the byte-length of buf
- int flags
- can have
MSG_OOB
,MSG_DONTROUTE
, andMSG_DONTWAIT
- struct sa* opt_addr
- is a binary ip:port destination override, which is mandatory for UDP if connect() wasn't called
- unsigned int addrsize
- is the byte-length of addr's true polymorphic form
- long
- number of bytes transmitted, or -1 w/ errno
setbuf
Sets buffer on stdio stream.
- struct FILE* f
- char* buf
- void
setbuffer
Sets buffer on stdio stream.
- struct FILE* f
- char* buf
- may optionally be non-NULL to set the stream's underlying buffer, which the stream will own, but won't free
- unsigned long size
- is ignored if buf is NULL
- void
setcontext
Sets machine context.
- struct ucontext_t* uc
- int
- -1 on error w/ errno, otherwise won't return unless sent back
setegid
Sets effective group ID.
- unsigned int egid
- int
- 0 on success, or -1 w/ errno
setenv
Copies variable to environment.
- const char* name
- const char* value
- int overwrite
- const char* value
- int
- 0 on success, or -1 w/ errno and environment is unchanged
name
is empty or contains '='
seteuid
Sets effective user ID.
- unsigned int euid
- int
- 0 on success, or -1 w/ errno
setfsgid
Sets user id of current process for file system ops.
- unsigned int gid
- int
- previous filesystem gid
setfsuid
Sets user id of current process for file system ops.
- unsigned int uid
- int
- previous filesystem uid
setgid
Sets group id of current process.
- unsigned int gid
- int
- 0 on success, or -1 w/ errno
setgroups
Sets list of supplementary group IDs.
On recent versions of Linux only, it's possible to say:
setgroups(0, NULL);Which will cause subsequent calls to
EPERM
.
- unsigned long size
- number of items in list
- const unsigned int* list
- input set of gid_t to set
- int
- -1 w/ EFAULT
setitimer
Schedules delivery of one-shot or intermittent interrupt signal, e.g.
Raise SIGALRM every 1.5s:
sigaction(SIGALRM, &(struct sigaction){.sa_handler = OnSigalrm}, NULL); setitimer(ITIMER_REAL, &(const struct itimerval){{1, 500000}, {1, 500000}}, NULL);Single-shot alarm to interrupt connect() after 50ms:
sigaction(SIGALRM, &(struct sigaction){.sa_handler = OnSigalrm, .sa_flags = SA_RESETHAND}, NULL); setitimer(ITIMER_REAL, &(const struct itimerval){{0, 0}, {0, 50000}}, NULL); if (connect(...) == -1 && errno == EINTR) { ... }Disarm existing timer:
setitimer(ITIMER_REAL, &(const struct itimerval){0}, NULL);If the goal is to use alarms to interrupt blocking i/o routines, e.g. read(), connect(), etc. then it's important to install the signal handler using sigaction() rather than signal(), because the latter sets the
SA_RESTART
flag.
Timers are not inherited across fork.
- int which
- can be ITIMER_REAL, ITIMER_VIRTUAL, etc.
- struct itimerval* newvalue
- specifies the interval ({0,0} means one-shot) and duration ({0,0} means disarm) in microseconds ∈ [0,999999] and if this parameter is NULL, we'll polyfill getitimer() behavior
- struct itimerval* oldvalue
- int
- 0 on success or -1 w/ errno
setjmp
Saves cpu state.
- rdi
- points to jmp_buf
- rax 0 when set and !0 when longjmp'd
setpgid
Changes process group for process.
- int pid
- is process id (may be zero for current process)
- int pgid
- is process group id (may be zero for current process)
- int
- 0 on success, or -1 w/ errno
setpriority
Sets nice value of thing.
On Windows, there's only six priority classes. We define them as -16 (realtime), -10 (high), -5 (above), 0 (normal), 5 (below), 15 (idle) which are the only values that'll roundtrip getpriority/setpriority.
- int which
- can be one of:
PRIO_PROCESS
is supported universallyPRIO_PGRP
is supported on unixPRIO_USER
is supported on unix
- unsigned int who
- is the pid, pgid, or uid, 0 meaning current
- int value
- ∈ [-NZERO,NZERO) which is clamped automatically
- int
- 0 on success, or -1 w/ errno
which
was invalid or unsupported
value
lower that RLIMIT_NICE
CAP_SYS_NICE
setregid
Sets real and/or effective group ids.
- unsigned int rgid
- is real group id or -1 to leave it unchanged
- unsigned int egid
- is effective group id or -1 to leave it unchanged
- int
- 0 on success or -1 w/ errno
setresgid
Sets real, effective, and "saved" group ids.
- unsigned int real
- sets real group id or -1 to do nothing
- unsigned int effective
- sets effective group id or -1 to do nothing
- unsigned int saved
- sets saved group id or -1 to do nothing
- int
setresuid
Sets real, effective, and "saved" user ids.
- unsigned int real
- sets real user id or -1 to do nothing
- unsigned int effective
- sets effective user id or -1 to do nothing
- unsigned int saved
- sets saved user id or -1 to do nothing
- int
setreuid
Sets real and/or effective user ids.
- unsigned int ruid
- is real user id or -1 to leave it unchanged
- unsigned int euid
- is effective user id or -1 to leave it unchanged
- int
- 0 on success or -1 w/ errno
setsid
Creates session and sets the process group id.
- int
- new session id, or -1 w/ errno
setsockopt
Modifies socket settings.
Basic usage:
int yes = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
- int fd
- int level
- can be SOL_SOCKET, SOL_IP, SOL_TCP, etc.
- int optname
- can be SO_{REUSE{PORT,ADDR},KEEPALIVE,etc.} etc.
- void* optval
- unsigned int optlen
- int
- 0 on success, or -1 w/ errno
optlen
is invalid somehow
fd
is valid but not a socket
fd
isn't valid
setuid
Sets user id of current process.
- unsigned int uid
- int
- 0 on success, or -1 w/ errno
RLIMIT_NPROC
to be exceeded
setvbuf
Tunes buffering settings for an stdio stream.
- struct FILE* f
- char* buf
- may optionally be non-NULL to set the stream's underlying buffer which the caller still owns and won't free, otherwise the existing buffer is used
- int mode
- may be _IOFBF, _IOLBF, or _IONBF
- unsigned long size
- is ignored if buf is NULL
- int
- 0 on success or -1 on error
sha1_transform_avx2
Performs Intel® AVX2™ optimized SHA-1 update.
This implementation is based on the previous SSSE3 release: Visit http://software.intel.com/en-us/articles/ and refer to improving-the-performance-of-the-secure-hash-algorithm-1/
Updates 20-byte SHA-1 record at start of 'state', from 'input', for even number of 'blocks' consecutive 64-byte blocks.
void sha1_transform_avx2(struct sha1_state *state, const uint8_t *input, int blocks);
- %rdi
- points to output digest
- %rsi
- points to input data
- %rdx
- is number of 64-byte blocks to process
sha1_transform_ni
Performs Intel® SHA-NI™ optimized SHA-1 update.
The function takes a pointer to the current hash values, a pointer to the input data, and a number of 64 byte blocks to process. Once all blocks have been processed, the digest pointer is updated with the resulting hash value. The function only processes complete blocks, there is no functionality to store partial blocks. All message padding and hash value initialization must be done outside the update function.
The indented lines in the loop are instructions related to rounds processing. The non-indented lines are instructions related to the message schedule.
void sha1_transform_ni(uint32_t digest[static 5], const void *data, uint32_t numBlocks);
- %rdi
- points to output digest
- %rsi
- points to input data
- %rdx
- is number of 64-byte blocks to process
sha256_transform_ni
Performs Intel® SHA-NI™ optimized SHA-256 update.
The function takes a pointer to the current hash values, a pointer to the input data, and a number of 64 byte blocks to process. Once all blocks have been processed, the digest pointer is updated with the resulting hash value. The function only processes complete blocks, there is no functionality to store partial blocks. All message padding and hash value initialization must be done outside the update function.
The indented lines in the loop are instructions related to rounds processing. The non-indented lines are instructions related to the message schedule.
void sha256_transform_ni(uint32_t digest[static 8], const void *data, int32_t numBlocks);
- %rdi
- points to output digest
- %rsi
- points to input data
- %rdx
- is number of blocks to process
shm_open
Opens POSIX named memory object.
- const char* name
- should begin with a
/
and shouldn't contain subsequent slash characters, and furthermore shouldn't exceed NAME_MAX, for maximum portability; POSIX defines it as opening a multi-process object and leaves all other names implementation defined; and we choose (in this implementation) to define those names as meaning the same thing while not imposing any length limit; cosmo always feeds your name through BLAKE2B to create a.sem
file existing under/dev/shm
if available, otherwise it will go under/tmp
- int oflag
- unsigned int mode
- int
- open file descriptor, or -1 w/ errno
shm_path_np
Returns filesystem pathname of named semaphore.
- const char* name
- is
name
of semaphore which should begin with slash - char* buf
- is temporary storage with at least 78 bytes
- void
- pointer to file system path
size
shutdown
Disables sends or receives on a socket, without closing.
- int fd
- is the open file descriptor for the socket
- int how
- can be SHUT_RD, SHUT_WR, or SHUT_RDWR
- int
- 0 on success or -1 on error
__sig_restore
Restores thread to state before signal.
- rdi points
- to ucontext_t with machine state
sigaction
Installs handler for kernel interrupt to thread, e.g.:
void GotCtrlC(int sig, siginfo_t *si, void *arg) { ucontext_t *ctx = arg; } struct sigaction sa = {.sa_sigaction = GotCtrlC, .sa_flags = SA_RESETHAND|SA_RESTART|SA_SIGINFO}; CHECK_NE(-1, sigaction(SIGINT, &sa, NULL));The following flags are supported across platforms:
SA_SIGINFO
: Causes thesiginfo_t
anducontext_t
parameters to be passed.void *ctx
actually refers tostruct ucontext *
. This not only gives you more information about the signal, but also allows your signal handler to change the CPU registers. That's useful for recovering from crashes. If you don't use this attribute, then signal delivery will go a little faster.SA_RESTART
: Enables BSD signal handling semantics. Normally i/o entrypoints check for pending signals to deliver. If one gets delivered during an i/o call, the normal behavior is to cancel the i/o operation and return -1 with EINTR in errno. If you use theSA_RESTART
flag then that behavior changes, so that any function that's been annotated with @restartable will not returnEINTR
and will instead resume the i/o operation. This makes coding easier but it can be an anti-pattern if not used carefully, since poor usage can easily result in latency issues. It also requires one to do more work in signal handlers, so special care needs to be given to which C library functions are @asyncsignalsafe.SA_RESETHAND
: Causes signal handler to be single-shot. This means that, upon entry of delivery to a signal handler, it's reset to theSIG_DFL
handler automatically. You may use the aliasSA_ONESHOT
for this flag, which means the same thing.SA_NODEFER
: Disables the reentrancy safety check on your signal handler. Normally that's a good thing, since for instance if yourSIGSEGV
signal handler happens to segfault, you're going to want your process to just crash rather than looping endlessly. But in some cases it's desirable to useSA_NODEFER
instead, such as at times when you wish tolongjmp()
out of your signal handler and back into your program. This is only safe to do across platforms for non-crashing signals such asSIGCHLD
andSIGINT
. Crash handlers should use Xed instead to recover execution, because on Windows aSIGSEGV
orSIGTRAP
crash handler might happen on a separate stack and/or a separate thread. You may use the aliasSA_NOMASK
for this flag, which means the same thing.SA_NOCLDWAIT
: ChangesSIGCHLD
so the zombie is gone and you can't callwait()
anymore; similar but may still deliver the SIGCHLD.SA_NOCLDSTOP
: Lets you setSIGCHLD
handler that's only notified on exit/termination and not notified onSIGSTOP
,SIGTSTP
,SIGTTIN
,SIGTTOU
, orSIGCONT
.
static volatile bool gotctrlc; void OnCtrlC(int sig) { gotctrlc = true; } int main() { size_t got; ssize_t rc; char buf[1]; struct sigaction oldint; struct sigaction saint = {.sa_handler = GotCtrlC}; if (sigaction(SIGINT, &saint, &oldint) == -1) { perror("sigaction"); exit(1); } for (;;) { rc = read(0, buf, sizeof(buf)); if (rc == -1) { if (errno == EINTR) { if (gotctrlc) { break; } } else { perror("read"); exit(2); } } if (!(got = rc)) { break; } for (;;) { rc = write(1, buf, got); if (rc != -1) { assert(rc == 1); break; } else if (errno != EINTR) { perror("write"); exit(3); } } } sigaction(SIGINT, &oldint, 0); }Please note that you can't do the above if you use SA_RESTART. Since the purpose of SA_RESTART is to restart i/o operations whose docs say that they're @restartable and read() is one such function. Here's some even better news: if you don't install any signal handlers at all, then your i/o calls will never be interrupted!
Here's an example of the most professional way to recover from
SIGSEGV
, SIGFPE
, and SIGILL
.
void ContinueOnCrash(void); void SkipOverFaultingInstruction(struct ucontext *ctx) { struct XedDecodedInst xedd; xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64); xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15); ctx->uc_mcontext.rip += xedd.length; } void OnCrash(int sig, siginfo_t *si, void *vctx) { struct ucontext *ctx = vctx; SkipOverFaultingInstruction(ctx); ContinueOnCrash(); // reinstall here in case *rip faults } void ContinueOnCrash(void) { struct sigaction sa = {.sa_handler = OnSigSegv, .sa_flags = SA_SIGINFO | SA_RESETHAND}; sigaction(SIGSEGV, &sa, 0); sigaction(SIGFPE, &sa, 0); sigaction(SIGILL, &sa, 0); } int main() { ContinueOnCrash(); // ... }You may also edit any other CPU registers during the handler. For example, you can use the above technique so that division by zero becomes defined to a specific value of your choosing!
Please note that Xed isn't needed to recover from SIGTRAP
which can
be raised at any time by embedding DebugBreak()
or asm("int3")
in
your program code. Your signal handler will automatically skip over
the interrupt instruction, assuming your signal handler returns.
The important signals supported across all platforms are:
SIGINT
: When you press Ctrl-C this signal gets broadcasted to your process session group. This is the normal way to terminate console applications.SIGQUIT
: When you press CTRL-\ this signal gets broadcasted to your process session group. This is the irregular way to kill an application in cases where maybe yourSIGINT
handler is broken although, Cosmopolitan Libc ShowCrashReports() should program it such as to attach a debugger to the process if possible, or else show a crash report. Also note that in New Technology you should press CTRL+BREAK rather than CTRL+\ to get this signal.SIGHUP
: This gets sent to your non-daemon processes when you close your terminal session.SIGTERM
is what thekill
command sends by default. It's the choice signal for terminating daemons.SIGUSR1
andSIGUSR2
can be anything you want. Their default action is to kill the process. By conventionSIGUSR1
is usually used by daemons to reload the config file.SIGCHLD
is sent when a process terminates and it takes a certain degree of UNIX mastery to address sanely.SIGALRM
is invoked bysetitimer()
andalarm()
. It can be useful for interrupting i/o operations likeconnect()
.SIGTRAP
: This happens when an INT3 instruction is encountered.SIGILL
happens on illegal instructions, e.g.UD2
.SIGABRT
happens when you callabort()
.SIGFPE
happens when you divide ints by zero, among other things.SIGSEGV
andSIGBUS
indicate memory access errors and they have inconsistent semantics across platforms like FreeBSD.SIGWINCH
is sent when your terminal window is resized.SIGXCPU
andSIGXFSZ
may be raised if you run out of resources, which can happen if your process, or the parent process that spawned your process, happened to callsetrlimit()
. Doing this is a wonderful idea.
errno
because most signals are asynchronous, i.e. the signal handler might
be called at any assembly instruction. If something like a SIGCHLD
handler doesn't save / restore the errno
global when calling wait,
then any i/o logic in the main program that checks errno
will most
likely break. This is rare in practice, since systems usually design
signals to favor delivery from cancelation points before they block
however that's not guaranteed.
- int sig
- struct copy* act
- struct copy* oldact
- struct copy* act
- int
- 0 on success or -1 w/ errno
sigaddset
Adds signal to set.
- unsigned long* set
- int sig
- int
- 0 on success, or -1 w/ errno
1 ≤ sig ≤ NSIG
isn't the case
sigandset
Bitwise ANDs two signal sets.
- unsigned long* set
- const unsigned long* x
- const unsigned long* y
- const unsigned long* x
- int
- 0 on success, or -1 w/ errno
sigcountset
Returns population count of signal set.
- const unsigned long* set
- int
- value greater than or equal to zero
sigdelset
Removes signal from set.
- unsigned long* set
- int sig
- int
- 0 on success, or -1 w/ errno
1 ≤ sig ≤ NSIG
isn't the case
sigemptyset
Removes all signals from set.
- unsigned long* set
- int
- 0 on success, or -1 w/ errno
sigfillset
Fills up signal set.
- unsigned long* set
- int
- 0 on success, or -1 w/ errno
siginterrupt
Tunes whether signal can interrupt restartable system calls.
- int sig
- int flag
- int
sigisemptyset
Determines if signal set is empty.
- const unsigned long* set
- int
- 1 if empty, 0 if non-empty, or -1 w/ errno
sigismember
Returns true if signal is member of set.
- const unsigned long* set
- int sig
- int
- 1 if set, 0 if not set, or -1 w/ errno
1 ≤ sig ≤ NSIG
isn't the case
siglongjmp
Loads previously saved processor state.
- rdi
- points to the jmp_buf
- esi
- is returned by setjmp() invocation (coerced nonzero)
signal
Installs kernel interrupt handler, e.g.
void GotCtrlC(int sig) { ... } CHECK_NE(SIG_ERR, signal(SIGINT, GotCtrlC));
- int sig
- void(*)() func
- void(*)()
- old signal handler on success or SIG_ERR w/ errno
sigorset
Bitwise ORs two signal sets.
- unsigned long* set
- const unsigned long* x
- const unsigned long* y
- const unsigned long* x
- int
- 0 on success, or -1 w/ errno
sigpending
Determines the blocked pending signals
- unsigned long* pending
- is where the bitset of pending signals is returned, which may not be null
- int
- 0 on success, or -1 w/ errno
pending
points to invalid memory
sigprocmask
Changes signal blocking state of calling thread, e.g.:
sigset_t neu,old; sigfillset(&neu); sigprocmask(SIG_BLOCK, &neu, &old); sigprocmask(SIG_SETMASK, &old, NULL);
- int how
- can be SIG_BLOCK (U), SIG_UNBLOCK (/), SIG_SETMASK (=)
- const unsigned long* opt_set
- unsigned long* opt_out_oldset
- int
- 0 on success, or -1 w/ errno
set
or oldset
is bad memory
how
is invalid
sigqueue
Sends signal to process, with data.
The impact of this action can be terminating the process, or interrupting it to request something happen.
- int pid
- can be: >0 signals one process by id =0 signals all processes in current process group -1 signals all processes possible (except init) <-1 signals all processes in -pid process group
- int sig
- can be: >0 can be SIGINT, SIGTERM, SIGKILL, SIGUSR1, etc. =0 checks both if pid exists and we can signal it
- union value value
- int
- 0 if something was accomplished, or -1 w/ errno
sigsetjmp
Saves caller CPU state and signal mask.
- rdi
- points to jmp_buf
- esi
- if non-zero will cause mask to be saved
- eax 0 when set and !0 when longjmp'd
sigtimedwait
Waits for signal synchronously, w/ timeout.
This function does not change the thread signal mask. Signals that
aren't masked, which aren't in set
, will be handled normally, in
which case this function will raise EINTR
.
This function silently ignores attempts to synchronously wait for SIGTHR which is used internally by the POSIX threads implementation.
- const unsigned long* set
- is signals for which we'll be waiting
- struct linux* opt_info
- if not null shall receive info about signal
- struct timespec* opt_timeout
- is relative deadline and null means wait forever
- int
- signal number on success, or -1 w/ errno
sigwait
Waits for signal synchronously.
See sigtimedwait() for further details.
- const unsigned long* mask
- int* out_sig
- shall receive signal number
- int
- 0 on success, or -1 w/ errno
sigwaitinfo
Waits for signal synchronously.
See sigtimedwait() for further details.
- const unsigned long* mask
- struct siginfo_t* si
- int
- signal number on success, or -1 w/ errno
sin
Returns sine of 𝑥.
- double x
- double
sincos
Returns sine and cosine of 𝑥.
- double x
- double* sin
- double* cos
- double* sin
- void
sincosf
Returns sine and cosine of y.
This is a fast sincosf implementation. Worst-case ULP is 0.5607, maximum relative error is 0.5303 * 2^-23. A single-step range reduction is used for small values. Large inputs have their range reduced using fast integer arithmetic.
- float y
- float* sinp
- float* cosp
- float* sinp
- void
sincosl
Returns sine and cosine of 𝑥.
- long double x
- long double* sin
- long double* cos
- long double* sin
- void
sinf
Returns sine of y.
This is a fast sinf implementation. The worst-case ULP is 0.5607 and the maximum relative error is 0.5303 * 2^-23. A single-step range reduction is used for small values. Large inputs have their range reduced using fast integer arithmetic.
- float y
- float
sinhf
Returns hyperbolic sine of 𝑥.
sinh(x) = (exp(x) - 1/exp(x))/2 = (exp(x)-1 + (exp(x)-1)/exp(x))/2 = x + x^3/6 + o(x^5)
- float x
- float
sizefmt
Represents size as readable string.
- char* p
- is output buffer
- unsigned long x
- unsigned long b
- should be 1024 or 1000
- char*
- pointer to nul byte
sizetol
Converts size string to long.
The following unit suffixes may be used
k
orK
for kilo (multiply by 𝑏¹)m
orM
for mega (multiply by 𝑏²)g
orG
for giga (multiply by 𝑏³)t
orT
for tera (multiply by 𝑏⁴)p
orP
for peta (multiply by 𝑏⁵)e
orE
for exa (multiply by 𝑏⁶)
Negative numbers are permissible, as well as a leading +
sign. To
tell the difference between an error return and -1
you must clear
errno
before calling and test whether it changed.
- const char* s
- is non-null nul-terminated input string
- long b
- is multiplier which should be 1000 or 1024
- long
- size greater than or equal 0 or -1 on error
sleb64
Encodes signed integer to array.
uleb64 INT64_MAX l: 10𝑐 3𝑛𝑠 zleb64 INT64_MAX l: 13𝑐 4𝑛𝑠 sleb64 INT64_MAX l: 16𝑐 5𝑛𝑠 uleb128 INT64_MAX l: 18𝑐 6𝑛𝑠 zleb128 INT64_MAX l: 18𝑐 6𝑛𝑠 sleb128 INT64_MAX l: 24𝑐 8𝑛𝑠 zleb64 INT64_MIN l: 13𝑐 4𝑛𝑠 sleb64 INT64_MIN l: 16𝑐 5𝑛𝑠 zleb128 INT64_MIN l: 19𝑐 6𝑛𝑠 sleb128 INT64_MIN l: 24𝑐 8𝑛𝑠
- char* p
- is output array
- long x
- is number
- char*
- p + i
smoothsort
Sorts array.
- void* base
- points to an array to sort in-place
- unsigned long count
- is the item count
- unsigned long width
- is the size of each item
- int(*)() cmp
- is a callback returning <0, 0, or >0
- void
smoothsort_r
Sorts array.
- void* base
- points to an array to sort in-place
- unsigned long count
- is the item count
- unsigned long width
- is the size of each item
- int(*)() cmp
- is a callback returning <0, 0, or >0
- void* arg
- will optionally be passed as the third argument to cmp
- void
_smt19937
Initializes mt[NN] with small seed value.
- unsigned long seed
- void
_Smt19937
Initializes mt[NN] with array.
- unsigned long* K
- is the array for initializing keys
- unsigned long n
- is its length
- void
snprintf
Formats string to buffer.
- char* buf
- unsigned long count
- const char* fmt
- ...
- unsigned long count
- int
- number of bytes written, excluding the NUL terminator; or, if the output buffer wasn't passed, or was too short, then the number of characters that *would* have been written is returned
sockaddr2bsd
Converts sockaddr (Linux/Windows) → sockaddr_bsd (XNU/BSD).
- void* addr
- unsigned int addrsize
- union sockaddr_storage_bsd* out_addr
- unsigned int* out_addrsize
- unsigned int addrsize
- int
sockaddr2linux
Converts sockaddr_bsd (XNU/BSD) → sockaddr (Linux/Windows).
- union sockaddr_storage_bsd* addr
- unsigned int addrsize
- union sockaddr_storage_linux* out_addr
- unsigned int* inout_addrsize
- unsigned int addrsize
- void
socket
Creates new system resource for network communication, e.g.
int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- int family
- can be AF_UNIX, AF_INET, AF_INET6, etc.
- int type
- can be SOCK_STREAM (for TCP), SOCK_DGRAM (e.g. UDP), or SOCK_RAW (IP) so long as IP_HDRINCL was passed to setsockopt(); and additionally, may be or'd with SOCK_NONBLOCK, SOCK_CLOEXEC
- int protocol
- can be IPPROTO_TCP, IPPROTO_UDP, or IPPROTO_ICMP
- int
- socket file descriptor or -1 w/ errno
family
isn't supported by system or platform
socketpair
Creates bidirectional pipe, e.g.
int sv[2]; socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
- int family
- should be AF_UNIX or synonymously AF_LOCAL
- int type
- can be SOCK_STREAM or SOCK_DGRAM and additionally, may be or'd with SOCK_NONBLOCK, SOCK_CLOEXEC
- int protocol
- int* sv
- a vector of 2 integers to store the created sockets
- int
- 0 if success, -1 in case of error
splice
Transfers data to/from pipe.
- int infd
- long* opt_in_out_inoffset
- may be specified if
infd
isn't a pipe and is used as both an input and output parameter for pread() behavior - int outfd
- long* opt_in_out_outoffset
- may be specified if
outfd
isn't a pipe and is used as both an input and output parameter for pwrite() behavior - unsigned long uptobytes
- unsigned int flags
- can have SPLICE_F_{MOVE,NONBLOCK,MORE,GIFT}
- long
- number of bytes transferred, 0 on input end, or -1 w/ errno
infd
or outfd
aren't open files or append-only
infd
or outfd
is a zip file descriptor
flags
is invalid
sprintf
Formats string to buffer that's hopefully large enough.
- char* buf
- const char* fmt
- ...
- const char* fmt
- int
srand
Seeds random number generator that's used by rand().
- unsigned int seed
- void
sscanf
String decoder.
- const char* str
- const char* fmt
- ...
- const char* fmt
- int
__stack_call
Calls function on different stack.
- %rdi
- is arg1
- %rsi
- is arg2
- %rdx
- is arg3
- %rcx
- is arg4
- %r8
- is func
- %r9
- is stack
- %rax is res
__stack_chk_guard
Canary for -fstack-protector.
This global is referenced by synthetic code generated by GCC. The -mstack-protector-guard=global flag might need to be passed.
__start_fatal
Prints initial part of fatal message.
- const char* file
- int line
- void
startswith
Returns true if s has prefix.
- const char* s
- is a NUL-terminated string
- const char* prefix
- is also NUL-terminated
- int
startswith16
Returns true if s has prefix.
- const unsigned short* s
- is a NUL-terminated string
- const unsigned short* prefix
- is also NUL-terminated
- int
startswithi
Checks if string starts with prefix, case insensitively.
- const char* s
- const char* prefix
- int
stat
Returns information about file.
This function is equivalent to:
struct stat st; fstatat(AT_FDCWD, path, &st, 0);
- const char* path
- struct stat* st
- int
statvfs
Returns information about filesystem.
- const char* path
- struct statvfs* sv
- int
- 0 on success, or -1 w/ errno
stpcpy
Copies bytes from 𝑠 to 𝑑 until a NUL is encountered.
- char* d
- const char* s
- char*
- pointer to nul byte
stpncpy
Prepares static search buffer.
- If SRC is too long, it's truncated and *not* NUL-terminated.
- If SRC is too short, the remainder is zero-filled.
- char* dst
- is output buffer
- const char* src
- is a nul-terminated string
- unsigned long dstlen
- is size of
dst
buffer
- char*
- pointer to first nul-terminator, otherwise dest + stride
__strace
System call logging enabled state.
If Cosmopolitan was compiled with the SYSDEBUG
macro (this is the
default behavior, except in tiny and release modes) then __strace
shall control whether or not system calls are logged to fd 2. If it's
greater than zero, syscalls are logged. Otherwise, they're aren't.
By convention, functions wishing to disable syscall tracing for a short time period should say:
void foo() { strace_enabled(-1); bar(); strace_enabled(+1); }This way you still have some flexibility to force syscall tracing, by setting
__strace
to a higher number like 2
or 200
. Even though
under normal circumstances, __strace
should only be either zero or
one.
- int
strcasecmp
Compares NUL-terminated strings ascii case-insensitively.
- const char* a
- is first non-null nul-terminated string pointer
- const char* b
- is second non-null nul-terminated string pointer
- int
- is <0, 0, or >0 based on tolower(uint8_t) comparison
strcasecmp16
Compares NUL-terminated UCS-2 strings case-insensitively.
- const unsigned short* l
- const unsigned short* r
- int
- is <0, 0, or >0 based on uint16_t comparison
strcasestr
Searches for substring case-insensitively.
- const char* haystack
- is the search area, as a NUL-terminated string
- const char* needle
- is the desired substring, also NUL-terminated
- char*
- pointer to first substring within haystack, or NULL
strcat
Appends 𝑠 to 𝑑.
- char* d
- const char* s
- char*
- 𝑑
strcat16
Appends 𝑠 to 𝑑.
- unsigned short* d
- const unsigned short* s
- unsigned short*
- 𝑑
strchr
Returns pointer to first instance of character.
- const char* s
- is a NUL-terminated string
- int c
- is masked with 255 as byte to search for
- char*
- pointer to first instance of c or NULL if not found noting that if c is NUL we return pointer to terminator
strchr16
Returns pointer to first instance of character.
- const unsigned short* s
- int c
- unsigned short*
strchrnul
Returns pointer to first instance of character.
If c is not found then a pointer to the nul byte is returned.
- const char* s
- is a NUL-terminated string
- int c
- is masked with 255 as byte to search for
- char*
- pointer to first instance of c, or pointer to NUL terminator if c is not found
strchrnul16
Returns pointer to first instance of character.
- const unsigned short* s
- int c
- unsigned short*
strcmp
Compares NUL-terminated strings.
- const char* a
- is first non-null NUL-terminated string pointer
- const char* b
- is second non-null NUL-terminated string pointer
- int
- is <0, 0, or >0 based on uint8_t comparison
strcmp16
Compares NUL-terminated UCS-2 strings.
- const unsigned short* l
- const unsigned short* r
- int
- is <0, 0, or >0 based on uint16_t comparison
strcoll
Compares strings in the C locale.
- const char* p
- const char* q
- int
strcpy
Copies bytes from 𝑠 to 𝑑 until a NUL is encountered.
- char* d
- const char* s
- char*
- original dest
strcpy16
Copies NUL-terminated UCS-2 or UTF-16 string.
𝑑 and 𝑠 must not overlap unless 𝑑 ≤ 𝑠.
- unsigned short* d
- is dination memory
- const unsigned short* s
- is a NUL-terminated 16-bit string
- unsigned short*
- original d
strcspn16
Returns prefix length, consisting of chars not in reject. a.k.a. Return index of first byte that's in charset.
- const unsigned short* s
- const unsigned short* reject
- is nul-terminated character set
- unsigned long
strdup
Allocates new copy of string.
- const char* s
- is a NUL-terminated byte string
- char*
- new string or NULL w/ errno
_strerdoc
Converts errno value to descriptive sentence.
- int x
- const char*
- non-null rodata string or null if not found
_strerrno
Converts errno value to symbolic name.
- int x
- const char*
- non-null rodata string or null if not found
strerror
Returns string describing err
.
The application shall not modify the string returned.
- int err
- char*
strerror_r
Converts errno value to string.
- int err
- is error number or zero if unknown
- char* buf
- unsigned long size
- int
- 0 on success, or errno on error
buf
strfmon_l
- char* s
- unsigned long n
- struct __global_locale* loc
- const char* fmt
- ...
- unsigned long n
- long
strftime_l
- char* s
- unsigned long n
- const char* f
- struct tm* tm
- struct __global_locale* loc
- unsigned long n
- unsigned long
stripexts
Removes file extensions.
- char* s
- is mutated
- char*
- s
strlcat
Appends string, the BSD way.
Appends src
to string dst
of size dsize
(unlike strncat,
dsize
is the full size of dst
, not space left). At most dsize-1
characters will be copied. Always NUL terminates (unless dsize <=
strlen(dst)
). Returns strlen(src) + MIN(dsize, strlen(initial
dst))
. If retval >= dsize
, truncation occurred.
- char* dst
- const char* src
- unsigned long dsize
- const char* src
- unsigned long
strlcpy
Copies string, the BSD way.
Copy string src to buffer dst
of size dsize
. At most dsize-1
chars will be copied. Always NUL terminates (unless dsize == 0
).
Returns strlen(src)
; if retval >= dsize
, truncation occurred.
- char* dst
- const char* src
- unsigned long dsize
- const char* src
- unsigned long
strlen16
Returns length of NUL-terminated utf-16 string.
- const unsigned short* s
- is non-null NUL-terminated string pointer
- unsigned long
- number of shorts (excluding NUL)
strncasecmp
Compares NUL-terminated strings case-insensitively w/ limit.
- const char* a
- is first non-null NUL-terminated string pointer
- const char* b
- is second non-null NUL-terminated string pointer
- unsigned long n
- int
- is <0, 0, or >0 based on uint8_t comparison
strncasecmp16
Compares NUL-terminated UCS-2 strings case-insensitively w/ limit.
- const unsigned short* a
- is first non-null NUL-terminated char16 string pointer
- const unsigned short* b
- is second non-null NUL-terminated char16 string pointer
- unsigned long n
- int
- is <0, 0, or >0 based on uint8_t comparison
strncat
Appends at most 𝑛 bytes from 𝑠 to 𝑑.
- char* d
- const char* s
- unsigned long n
- const char* s
- char*
- 𝑑
strncat16
Appends at most 𝑛 shorts from 𝑠 to 𝑑.
- unsigned short* d
- const unsigned short* s
- unsigned long n
- const unsigned short* s
- unsigned short*
- 𝑑
strncmp
Compares NUL-terminated strings w/ limit.
- const char* a
- is first non-null NUL-terminated string pointer
- const char* b
- is second non-null NUL-terminated string pointer
- unsigned long n
- int
- is <0, 0, or >0 based on uint8_t comparison
strncmp16
Compares NUL-terminated UCS-2 strings w/ limit.
- const unsigned short* a
- is first non-null NUL-terminated char16 string pointer
- const unsigned short* b
- is second non-null NUL-terminated char16 string pointer
- unsigned long n
- int
- is <0, 0, or >0 based on uint8_t comparison
strncpy
Prepares static search buffer.
- If SRC is too long, it's truncated and *not* NUL-terminated.
- If SRC is too short, the remainder is zero-filled.
- char* dst
- is output buffer
- const char* src
- is a nul-terminated string
- unsigned long dstlen
- is size of
dst
buffer
- char*
- dst
strndup
Allocates new copy of string, with byte limit.
- const char* s
- is a NUL-terminated byte string
- unsigned long n
- if less than strlen(s) will truncate the string
- char*
- new string or NULL w/ errno
strnwidth
Returns monospace display width of UTF-8 string.
- Control codes are discounted
- ANSI escape sequences are discounted
- East asian glyphs, emoji, etc. count as two
- const char* s
- is NUL-terminated string
- unsigned long n
- is max bytes to consider
- unsigned long o
- is offset for doing tabs
- int
- monospace display width
strnwidth16
Returns monospace display width of UTF-16 or UCS-2 string.
- const unsigned short* p
- unsigned long n
- unsigned long o
- unsigned long n
- int
strpbrk
Returns pointer to first byte matching any in accept, or NULL.
- const char* s
- const char* accept
- char*
strpbrk16
Returns pointer to first byte matching any in accept, or NULL.
- const unsigned short* s
- const unsigned short* accept
- unsigned short*
strrchr
Searches for last instance of character in string.
- const char* s
- is NUL-terminated string to search
- int c
- is treated as unsigned char
- char*
- address of last c in s, or NULL if not found
strrchr16
Searches for last instance of char16_t in string.
- const unsigned short* s
- is NUL-terminated char16_t string to search
- int c
- is treated as char16_t
- unsigned short*
- address of last c in s, or NULL if not found
strsep
Tokenizes string.
This works by mutating the caller's pointer and the string itself. The returned value is the next available token, or NULL if we've reached the end. Upon each call, *str is updated to point past the terminator we inserted. Multiple delimiter bytes may be passed, which are treated as a set of characters, not a substring.
- char** str
- on first call points to var holding string to be tokenized and is used by this function to track state on subsequent calls
- const char* delim
- is a set of characters that constitute separators
- char*
- next token or NULL when we've reached the end or *str==NULL
strsignal
Returns string describing signal code.
This returns "0"
for 0 which is the empty value. Symbolic names
should be available for signals 1 through 32. If the system supports
real-time signals, they're returned as SIGRTMIN+%d
. For all other
32-bit signed integer, a plain integer representation is returned.
This function is thread safe when sig
is a known signal magnum.
Otherwise a pointer to static memory is returned which is unsafe.
- int sig
- is signal number which should be in range 1 through 128
- char*
- string which is valid code describing signal
strspn
Returns prefix length, consisting of chars in accept.
- const char* s
- const char* accept
- is nul-terminated character set
- unsigned long
strspn16
Returns prefix length, consisting of chars in accept.
- const unsigned short* s
- const unsigned short* accept
- is nul-terminated character set
- unsigned long
strstr16
Searches for substring.
- const unsigned short* haystack
- is the search area, as a NUL-terminated string
- const unsigned short* needle
- is the desired substring, also NUL-terminated
- unsigned short*
- pointer to first substring within haystack, or NULL
strtok
Extracts non-empty tokens from string.
- char* s
- is mutated and should be NULL on subsequent calls
- const char* sep
- is a NUL-terminated set of bytes to consider separators
- char*
- pointer to next token or NULL for end
strtok_r
Extracts non-empty tokens from string.
- char* s
- is mutated and should be NULL on subsequent calls
- const char* sep
- is a NUL-terminated set of bytes to consider separators
- char** state
- tracks progress between calls
- char*
- pointer to next token or NULL for end
strtol
Decodes signed integer from ASCII string.
atoi 10⁸ 22𝑐 7𝑛𝑠 strtol 10⁸ 37𝑐 12𝑛𝑠 strtoul 10⁸ 35𝑐 11𝑛𝑠 wcstol 10⁸ 30𝑐 10𝑛𝑠 wcstoul 10⁸ 30𝑐 10𝑛𝑠 strtoimax 10⁸ 80𝑐 26𝑛𝑠 strtoumax 10⁸ 78𝑐 25𝑛𝑠 wcstoimax 10⁸ 77𝑐 25𝑛𝑠 wcstoumax 10⁸ 76𝑐 25𝑛𝑠
- const char* s
- is a non-null nul-terminated string
- char** endptr
- if non-null will always receive a pointer to the char following the last one this function processed, which is usually the NUL byte, or in the case of invalid strings, would point to the first invalid character
- int base
- can be anywhere between [2,36] or 0 to auto-detect based on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or decimal (base 10) by default
- long
- the decoded signed saturated number
base
isn't 0 or 2..36
strtold
Converts string to long double.
- const char* s
- char** endptr
- long double
strtoul
Decodes unsigned integer from ASCII string.
- const char* s
- is a non-null nul-terminated string
- char** endptr
- if non-null will always receive a pointer to the char following the last one this function processed, which is usually the NUL byte, or in the case of invalid strings, would point to the first invalid character
- int base
- can be anywhere between [2,36] or 0 to auto-detect based on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or decimal (base 10) by default
- unsigned long
- decoded integer mod 2⁶⁴ negated if leading
-
strwidth
Returns monospace display width of UTF-8 string.
- Control codes are discounted
- ANSI escape sequences are discounted
- East asian glyphs, emoji, etc. count as two
- const char* s
- is NUL-terminated string
- unsigned long o
- is string offset for computing tab widths
- int
- monospace display width
strwidth16
Returns monospace display width of UTF-16 or UCS-2 string.
- const unsigned short* s
- unsigned long o
- int
svigna
Seeds vigna() pseudorandom number generator.
- unsigned long seed
- void
swapcontext
Saves machine to 𝑥 and activates 𝑦, i.e.
getcontext(x); setcontext(y);Except using this API is safer and goes 2x faster:
swapcontext(x, y);
- 0 on success, or -1 w/ errno
symlink
Creates symbolic link.
This is like link() but adds a tiny indirection to make the fact that the file is a link obvious. It also enables certain other features, like the ability to be broken.
- const char* target
- can be relative and needn't exist
- const char* linkpath
- is what gets created
- int
- 0 on success, or -1 w/ errno
symlinkat
Creates symbolic link.
This is like link() but adds a tiny indirection to make the fact that the file is a link obvious. It also enables certain other features, like the ability to be broken.
- const char* target
- can be relative and needn't exist
- int newdirfd
- const char* linkpath
- is what gets created
- int
- 0 on success, or -1 w/ errno
syncfs
Syncs filesystem associated with file descriptor.
Since Linux 5.8, syncfs() will report an error if an inode failed to be written during the time since syncfs() was last called.
- int fd
- int
- 0 on success, or -1 w/ errno
fd
isn't a valid file descriptor
fd
is a zip file
sys_clone_linux
Invokes clone() system call on GNU/Systemd.
- rdi x0 is
- flags
- rsi x1 is
- top of stack
- rdx x2 is
- ptid
- rcx x3 is
- ctid
- r8 x4 is
- tls
- r9 x5 is
- func(void*,int)→int
- 8(rsp) x6 is
- arg
- tid of child on success, or -errno on error
syscall
Translation layer for some Linux system calls:
SYS_gettid
SYS_getrandom
- long number
- ...
- long
- system call result, or -1 w/ errno
syscon_start
Sections for varint encoded magic numbers.
These sections are all ordered by (group_name, constant_name). They're populated by modules simply referencing the symbols.
sysctl
- int* name
- unsigned int namelen
- void* oldp
- unsigned long* oldlenp
- void* newp
- unsigned long newlen
- unsigned int namelen
- int
sysctlbyname
- const char* name
- void* oldp
- unsigned long* oldlenp
- void* newp
- unsigned long newlen
- void* oldp
- int
_sysret
Handles return path of system call on Linux.
- unsigned long res
- unsigned long
__systemfive
Performs System Five System Call.
Cosmopolitan is designed to delegate all function calls into the Linux, FreeBSD, OpenBSD, and XNU kernels via this function, with few exceptions. This function should generally only be called by generated thunks in the libc/sysv/syscalls/ directory.
It's safe to call this function on Windows, where it will always return -1 with errno == ENOSYS. Further note that -1 is the only return value that means error, a common anti-pattern is to check for values less than 0 (which is more problematic on 32-bit).
It is important to consider that system calls are one order of a magnitude more expensive than normal function calls. For example getpid() on Linux usually takes 500ns, and cached i/o calls will take 1µs or more. So we don't need to inline them like Chromium.
Another thing to consider is that BSDs only loosely follow the System Five ABI for the SYSCALL instruction. For example Linux always follows the six argument limit but the FreeBSD sendfile system call accepts a seventh argument that is passed on stack and OpenBSD modifies functions like mmap so that the sixth arg is passed on the stack. There's also the carry flag convention that XNU, FreeBSD, and OpenBSD inherited from 386BSD aka Jolix
- %rax
- function ordinal supplied by jump slot
- %rdi,%rsi,%rdx,%rcx,%r8,%r9
- and rest on stack
- %rax:%rdx is result, or -1 w/ errno on error
systemvpe
Executes program and waits for it to complete, e.g.
systemvpe("ls", (char *[]){"ls", dir, 0}, environ);This function is designed to do the same thing as system() except rather than taking a shell script argument it accepts an array of strings which are safely passed directly to execve().
This function is 5x faster than system() and generally safer, for most command running use cases that don't need to control the i/o file descriptors.
- const char* prog
- is path searched (if it doesn't contain a slash) from
the $PATH environment variable in
environ
(not yourenvp
) - char** argv
- char** envp
- int
- -1 if child process couldn't be created, otherwise a wait status that can be accessed using macros like WEXITSTATUS(s), WIFSIGNALED(s), WTERMSIG(s), etc.
tanhf
Returns hyperbolic tangent of 𝑥.
- float x
- float
tanhf(x)=(expf(x)-expf(-x))/(expf(x)+expf(-x))
tanhf(x)=(expf(2.f*x)-1.f)/(expf(2.f*x)-1.f+2.f)
tcgetattr
Obtains the termios struct.
Here are the approximate defaults you can expect across platforms:
c_iflag = ICRNL IXON c_oflag = OPOST ONLCR NL0 CR0 TAB0 BS0 VT0 FF0 c_cflag = ISIG CREAD CS8 c_lflag = ISIG ICANON ECHO ECHOE ECHOK IEXTEN ECHOCTL ECHOKE cfgetispeed() = B38400 cfgetospeed() = B38400 c_cc[VINTR] = CTRL-C c_cc[VQUIT] = CTRL-\ # ignore this comment c_cc[VERASE] = CTRL-? c_cc[VKILL] = CTRL-U c_cc[VEOF] = CTRL-D c_cc[VTIME] = CTRL-@ c_cc[VMIN] = CTRL-A c_cc[VSTART] = CTRL-Q c_cc[VSTOP] = CTRL-S c_cc[VSUSP] = CTRL-Z c_cc[VEOL] = CTRL-@ c_cc[VSWTC] = CTRL-@ c_cc[VREPRINT] = CTRL-R c_cc[VDISCARD] = CTRL-O c_cc[VWERASE] = CTRL-W c_cc[VLNEXT] = CTRL-V c_cc[VEOL2] = CTRL-@
- int fd
- open file descriptor that isatty()
- struct linux* tio
- is where result is stored
- int
- 0 on success, or -1 w/ errno
tcgetpgrp
Returns which process group controls terminal.
- int fd
- int
- process group id on success, or -1 w/ errno
fd
is isn't controlling teletypewriter
fd
isn't an open file descriptor
tcsetattr
Sets struct on teletypewriter w/ drains and flushes.
- int fd
- open file descriptor that isatty()
- int opt
- can be:
- TCSANOW: sets console settings
- TCSADRAIN: drains output, and sets console settings
- TCSAFLUSH: drops input, drains output, and sets console settings
- struct linux* tio
- int
- 0 on success, -1 w/ errno
tcsetpgrp
Sets foreground process group id.
- int fd
- int pgrp
- int
- 0 on success, or -1 w/ errno
pgrp
is invalid
fd
isn't an open file descriptor
pgrp
didn't match process in our group
fd
is isn't controlling teletypewriter
SIGTTOU
, and process isn't ignoring SIGTTOU
tcsetsid
Associates session with controlling tty.
- int fd
- int pid
- int
- 0 on success, or -1 w/ errno
fd
isn't an open file descriptor
fd
is isn't controlling teletypewriter
pid
isn't session id associated with this process
__text_windows_start
Special area for Windows NT support code.
Isolating this code adds value for Windows users by minimizing page faults through improved locality. On System Five the PIRO runtime can unmap these pages.
__tfork_thread
Creates thread on OpenBSD.
- rdi
- is params
- rsi
- is size of params
- rdx
- is start function
- rcx
- is start parameter
- thread id or negative errno
time
Returns time as seconds from UNIX epoch.
- long* opt_out_ret
- can receive return value on success
- long
- seconds since epoch, or -1 w/ errno
timespec_cmp
Compares nanosecond timestamps.
- struct a a
- struct b b
- int
- 0 if equal, -1 if
a < b
, or +1 ifa > b
timespec_get
Returns high-precision timestamp, the C11 way.
- struct timespec* ts
- receives
CLOCK_REALTIME
timestamp - int base
- must be
TIME_UTC
- int
base
on success, or0
on failure
timespec_getres
Returns high-precision timestamp granularity, the C23 way.
- struct timespec* ts
- receives granularity as a relative timestamp
- int base
- must be
TIME_UTC
- int
base
on success, or0
on failure
timespec_real
Returns current time.
This function uses a CLOCK_REALTIME
clock and never fails. Unlike
clock_gettime() or timespec_real() this interface avoids the use of
pointers which lets time handling code become more elegant.
- struct ts
timespec_tomicros
Reduces ts
from 1e-9 to 1e-6 granularity w/ ceil rounding.
This function uses ceiling rounding. For example, if ts
is one
nanosecond, then one microsecond will be returned. Ceil rounding
is needed by many interfaces, e.g. setitimer(), because the zero
timestamp has a special meaning.
This function also detects overflow in which case INT64_MAX
or
INT64_MIN
may be returned. The errno
variable isn't changed.
- struct ts ts
- long
- 64-bit scalar holding microseconds since epoch
timespec_tomillis
Reduces ts
from 1e-9 to 1e-3 granularity w/ ceil rounding.
This function uses ceiling rounding. For example, if ts
is one
nanosecond, then one millisecond will be returned. Ceil rounding
is needed by many interfaces, e.g. setitimer(), because the zero
timestamp has a special meaning.
This function also detects overflow in which case INT64_MAX
or
INT64_MIN
may be returned. The errno
variable isn't changed.
- struct ts ts
- long
- 64-bit scalar milliseconds since epoch
timespec_tonanos
Converts timespec to scalar.
This returns the absolute number of nanoseconds in a timespec. If
overflow happens, then INT64_MAX
or INT64_MIN
is returned. The
errno
variable isn't changed.
- struct x x
- long
- 64-bit integer holding nanoseconds since epoch
timespec_totimeval
Reduces ts
from 1e-9 to 1e-6 granularity w/ ceil rounding.
This function uses ceiling rounding. For example, if ts
is one
nanosecond, then one microsecond will be returned. Ceil rounding
is needed by many interfaces, e.g. setitimer(), because the zero
timestamp has a special meaning.
- struct ts ts
- struct timeval
- microseconds since epoch
timeval_cmp
Compares microsecond timestamps.
- struct a a
- struct b b
- int
- 0 if equal, -1 if
a < b
, or +1 ifa > b
timeval_tomicros
Converts timeval to scalar.
This returns the absolute number of microseconds in a timeval. If
overflow happens, then INT64_MAX
or INT64_MIN
is returned. The
errno
variable isn't changed.
- struct x x
- long
- 64-bit integer holding microseconds since epoch
timeval_tomillis
Reduces ts
from 1e-6 to 1e-3 granularity w/ ceil rounding.
This function returns the absolute number of milliseconds in a
timeval. Ceiling rounding is used. For example, if ts
is one
nanosecond, then one millisecond will be returned. Ceil rounding is
needed by many interfaces, e.g. setitimer(), because the zero
timestamp has a valial meaning.
This function also detects overflow in which case INT64_MAX
or
INT64_MIN
may be returned. The errno
variable isn't changed.
- struct ts ts
- long
- 64-bit scalar milliseconds since epoch
timeval_toseconds
Converts timeval to seconds.
This function uses ceil rounding, so 1µs becomes 1s. The addition operation is saturating so timeval_toseconds(timeval_max) returns INT64_MAX.
- struct tv tv
- long
timingsafe_bcmp
Tests inequality of first 𝑛 bytes of 𝑝 and 𝑞.
- void* a
- void* b
- unsigned long n
- void* b
- int
- nonzero if unequal, otherwise zero
timingsafe_memcmp
Lexicographically compares the first 𝑛 bytes in 𝑝 and 𝑞.
The following expression:
timingsafe_memcmp(p, q, n)Is functionally equivalent to:
MAX(-1, MIN(1, memcmp(p, q, n)))Running time is independent of the byte sequences compared, making this safe to use for comparing secret values such as cryptographic MACs. In contrast, memcmp() may short-circuit after finding the first differing byte.
timingsafe_memcmp n=0 661 picoseconds timingsafe_memcmp n=1 1 ns/byte 590 mb/s timingsafe_memcmp n=2 1 ns/byte 738 mb/s timingsafe_memcmp n=3 1 ns/byte 805 mb/s timingsafe_memcmp n=4 1 ns/byte 843 mb/s timingsafe_memcmp n=5 1 ns/byte 922 mb/s timingsafe_memcmp n=6 1 ns/byte 932 mb/s timingsafe_memcmp n=7 1 ns/byte 939 mb/s timingsafe_memcmp n=8 992 ps/byte 984 mb/s timingsafe_memcmp n=9 992 ps/byte 984 mb/s timingsafe_memcmp n=15 926 ps/byte 1,054 mb/s timingsafe_memcmp n=16 950 ps/byte 1,026 mb/s timingsafe_memcmp n=17 933 ps/byte 1,045 mb/s timingsafe_memcmp n=31 896 ps/byte 1,089 mb/s timingsafe_memcmp n=32 888 ps/byte 1,098 mb/s timingsafe_memcmp n=33 972 ps/byte 1,004 mb/s timingsafe_memcmp n=80 913 ps/byte 1,068 mb/s timingsafe_memcmp n=128 891 ps/byte 1,095 mb/s timingsafe_memcmp n=256 873 ps/byte 1,118 mb/s timingsafe_memcmp n=16384 858 ps/byte 1,138 mb/s timingsafe_memcmp n=32768 856 ps/byte 1,140 mb/s timingsafe_memcmp n=131072 857 ps/byte 1,138 mb/s bcmp ne n=256 3 ps/byte 246 gb/s bcmp eq n=256 32 ps/byte 30,233 mb/s memcmp ne n=256 3 ps/byte 246 gb/s memcmp eq n=256 31 ps/byte 31,493 mb/s timingsafe_bcmp ne n=256 27 ps/byte 35,992 mb/s timingsafe_bcmp eq n=256 27 ps/byte 35,992 mb/s timingsafe_memcmp ne n=256 877 ps/byte 1,113 mb/s timingsafe_memcmp eq n=256 883 ps/byte 1,105 mb/s
- void* p
- void* q
- unsigned long n
- void* q
- int
- -1, 0, or 1 based on comparison
tinyprint
Writes strings to file descriptor, e.g.
tinyprint(1, "hello", " ", "world", "\n", NULL);This function is intended so that small command line programs (e.g. build utilities) can print succinct error messages automatically to standard io without linking too much binary footprint.
- int fd
- is file descriptor
- const char* s
- is NUL-terminated string, or NULL
- ...
- long
- bytes written on success, or -1 w/ errno
tmpfile
Opens stream backed by anonymous file, e.g.
FILE *f; if (!(f = tmpfile())) { perror("tmpfile"); exit(1); } // do stuff fclose(f);This creates a secure temporary file inside $TMPDIR. If it isn't defined, then /tmp is used on UNIX and GetTempPath() is used on the New Technology. This resolution of $TMPDIR happens once in a ctor.
Once fclose() is called, the returned file is guaranteed to be deleted automatically. On UNIX the file is unlink()'d before this function returns. On the New Technology it happens upon fclose().
On newer Linux only (c. 2013) it's possible to turn the anonymous returned file back into a real file, by doing this:
linkat(AT_FDCWD, gc(xasprintf("/proc/self/fd/%d", fileno(f))), AT_FDCWD, "real.txt", AT_SYMLINK_FOLLOW)On the New Technology, temporary files created by this function should have better performance, because
kNtFileAttributeTemporary
asks the kernel to more aggressively cache and reduce i/o ops.
Favor tmpfd() or tmpfile() over open(O_TMPFILE)
because the latter
is Linux-only and will cause open() failures on all other platforms.
- struct FILE*
tmpnam
Generates temporary file name.
- char* buf
- may be null to generate
/tmp/tmpnam_XXXXXX
to a static buffer (it works on Windows) that is not thread safe; otherwise the caller must supply a buffer withL_tmpnam
bytes available
- char*
- unique generated filename, or null on failure;
buf
memory is only mutated on success
tmpnam_r
Generates temporary file name, reentrantly.
This function is the same as tmpnam() except buf
can't be NULL.
- char* buf
- must have
L_tmpnam
bytes available
- char*
- pointer to
buf
which is populated with a unique generated filename, or null w/ errno on failure; buffer content will only be mutated on success
touch
Creates new file or changes modified time on existing one.
- const char* file
- is a UTF-8 string, which may or may not exist
- unsigned int mode
- is an octal user/group/other permission, e.g. 0755
- int
- 0 on success, or -1 w/ errno
tpenc
Encodes Thompson-Pike variable-length integer.
- unsigned int c
- unsigned long
truncate
Changes size of file.
If the file size is increased, the extended area shall appear as if it were zero-filled. If your file size is decreased, the extra data shall be lost.
Some operating systems implement an optimization, where length
is
treated as a logical size and the requested physical space won't be
allocated until non-zero values get written into it. Our tests show
this happens on Linux (usually with 4096 byte granularity), FreeBSD
(which favors 512-byte granularity), and MacOS (prefers 4096 bytes)
however Windows, OpenBSD, and NetBSD always reserve physical space.
This may be inspected using stat() then consulting stat::st_blocks.
- const char* path
- is name of file that shall be resized
- long length
- int
- 0 on success, or -1 w/ errno
length
is negative
length
is too huge
path
points to invalid memory
path
path
exists as non-directory
path
length exceeds PATH_MAX
path
exists longer than NAME_MAX
path
path
is on a read-only filesystem (e.g. zip)
path
doesn't exist or is an empty string
path
is an executable being executed
ttyname
Returns name of terminal.
This function isn't required to be thread safe, consider ttyname_r().
- int fd
- char*
- terminal path on success, or null w/ errno
ualarm
Sets microsecond-precision alarm.
This generates a SIGALRM
signal after usecs
microseconds. If
reload
is non-zero, then it'll keep generating SIGALRM
every
reload
microseconds after the first signal.
- unsigned int usecs
- unsigned int reload
- unsigned int
__udivmodti4
Performs 128-bit unsigned division and remainder.
- unsigned __int128 a
- is dividend
- unsigned __int128 b
- is divisor
- unsigned __int128* rem
- receives remainder if not NULL
- unsigned __int128
uleb64
Encodes unsigned integer to array.
uleb64 INT64_MAX l: 10𝑐 3𝑛𝑠 zleb64 INT64_MAX l: 13𝑐 4𝑛𝑠 sleb64 INT64_MAX l: 16𝑐 5𝑛𝑠 uleb128 INT64_MAX l: 18𝑐 6𝑛𝑠 zleb128 INT64_MAX l: 18𝑐 6𝑛𝑠 sleb128 INT64_MAX l: 24𝑐 8𝑛𝑠 zleb64 INT64_MIN l: 13𝑐 4𝑛𝑠 sleb64 INT64_MIN l: 16𝑐 5𝑛𝑠 zleb128 INT64_MIN l: 19𝑐 6𝑛𝑠 sleb128 INT64_MIN l: 24𝑐 8𝑛𝑠
- char* p
- is output array
- unsigned long x
- is number
- char*
- p + i
ulock_wait
- unsigned int operation
- void* addr
- unsigned long value
- unsigned int timeout_micros
- void* addr
- int
ulock_wake
- unsigned int operation
- void* addr
- unsigned long wake_value
- void* addr
- int
umask
Sets file mode creation mask.
On Windows, the value of umask() determines how Cosmopolitan goes
about creating synthetic st_mode
bits. The default umask is 077
which is based on the assumption that Windows is being used for a
single user. Don't assume that Cosmopolitan Libc will help you to
secure a multitenant Windows computer.
- unsigned int newmask
- unsigned int
- previous mask
unbing
Turns CP437 unicode glyph into its binary representation.
- int c
- is a unicode character
- int
- byte representation, or -1 if ch wasn't ibm cp437
unbingbuf
Decodes human-readable CP437 glyphs into binary, e.g.
char binged[5]; char golden[5] = "\0\1\2\3\4"; unbingbuf(binged, sizeof(binged), u" ☺☻♥♦", -1); CHECK_EQ(0, memcmp(binged, golden, 5));
- void* buf
- is caller owned
- unsigned long size
- is byte length of buf
- const unsigned short* glyphs
- is UCS-2 encoded CP437 representation of binary data
- int fill
- if -1 will memset any remaining buffer space
- void*
unbingstr
Decodes human-readable CP437 glyphs into binary, e.g.
CHECK_EQ(0, memcmp(gc(unbingstr(u" ☺☻♥♦")), "\0\1\2\3\4", 5));
- const unsigned short* s
- void*
Unchunk
Removes chunk transfer encoding from message body in place.
- struct HttpUnchunker* u
- char* p
- is modified in place
- unsigned long n
- unsigned long* l
- receives content length if not null
- long
- bytes processed, 0 if need more data, or -1 on failure
Underlong
Canonicalizes overlong Thompson-Pike encodings.
Please note that the IETF banned these numbers, so if you want to enforce their ban you can simply strcmp() the result to check for the existence of banned numbers.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
ungetwc
Pushes wide character back to stream.
- unsigned int c
- struct FILE* f
- unsigned int
ungetwc_unlocked
Pushes wide character back to stream.
- unsigned int c
- struct FILE* f
- unsigned int
unhilbert
Decodes Hilbert space-filling curve.
- long n
- long i
- struct m
unleaf
Does nothing.
Calling this function will force the compiler to generate a stack frame. This ensures backtraces will work better in a few critical routines.
- void
unlink
Removes file.
This may be used to delete files but it can't be used to delete directories. The exception are symlinks, which this will delete however not the linked directory.
- const char* name
- int
- 0 on success, or -1 w/ errno
unlinkat
Deletes inode and maybe the file too.
This may be used to delete files and directories and symlinks.
- int dirfd
- is normally AT_FDCWD but if it's an open directory and path is relative, then path becomes relative to dirfd
- const char* path
- is the thing to delete
- int flags
- can have AT_REMOVEDIR
- int
- 0 on success, or -1 w/ errno
unlockpt
Unlocks pseudoteletypewriter pair.
- int fd
- int
- 0 on success, or -1 w/ errno
unmount
Unmounts file system.
The following flags may be specified:
MNT_FORCE
MNT_DETACH
: lazily unmount; Linux-onlyMNT_EXPIRE
UMOUNT_NOFOLLOW
MNT_BYFSID
- const char* target
- int flags
- int
unuleb64
Decodes unsigned integer from array.
- const char* p
- is input array
- unsigned long n
- is capacity of p
- unsigned long* x
- receives number number
- int
- bytes decoded or -1 on error
unzleb64
Decodes array to signed integer w/ zig-zag encoding.
- const char* p
- is array
- unsigned long n
- is byte length of array
- long* o
- optionally receives decoded integer
- int
- bytes decoded or -1 on error
utf16to32
Transcodes UTF-16 to UTF-32.
- const unsigned short* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- int*
utf32to8
Transcodes UTF-32 to UTF-8.
- const int* p
- is input value
- unsigned long n
- if -1 implies wcslen
- unsigned long* z
- if non-NULL receives output length
- char*
utf8to16
Transcodes UTF-8 to UTF-16.
- const char* p
- is input value
- unsigned long n
- if -1 implies strlen
- unsigned long* z
- if non-NULL receives output length
- unsigned short*
utime
Changes last accessed/modified times on file.
- const char* path
- struct utimbuf* times
- if NULL means now
- int
- 0 on success, or -1 w/ errno
utimensat
Sets access/modified time on file, the modern way.
XNU only has microsecond (1e-6) accuracy and there's no
dirfd
-relative support. Windows only has hectonanosecond (1e-7)
accuracy. RHEL5 doesn't support dirfd
or flags
and will truncate
timestamps to seconds.
If you'd rather specify an open file descriptor rather than its filesystem path, then consider using futimens().
- int dirfd
- can be
AT_FDCWD
or an open directory - const char* path
- is filename whose timestamps should be modified
- struct timespec* ts
- is {access, modified} timestamps, or null for current time
- int flags
- can have
AT_SYMLINK_NOFOLLOW
- int
- 0 on success, or -1 w/ errno
flags
had an unrecognized value
flags
are used
fattr
promise
path
isn't unveiled
ts
specifies a nanosecond value that's out of range
path
length exceeds PATH_MAX
path
exists longer than NAME_MAX
dirfd
isn't a valid fd or AT_FDCWD
path
or ts
memory was invalid
path
is on read-only filesystem (e.g. zipos)
dirfd
isn't AT_FDCWD
utimes
Changes last accessed/modified timestamps on file.
- const char* path
- struct timeval* tv
- is access/modified timestamps, or NULL which means now
- int
- 0 on success, or -1 w/ errno
vdprintf
Formats string directly to system i/o device.
- int fd
- const char* fmt
- struct __va_list* va
- const char* fmt
- int
__vdsosym
Returns address of "Virtual Dynamic Shared Object" function on Linux.
- const char* version
- const char* name
- void*
vfork
Forks process without copying page tables.
This function lets a process spawn another process without copying the page tables. The parent process gets suspended until the child calls either execve() or _Exit(), and they share memory during that time. That's at least how we want vfork() to work. Support for these behaviors is patchy. It is also error-prone to use this function in an environment with signal handlers and threads. The best way to use this is by calling posix_spawn() which works around the dangers and determines at runtime the best way to pass error codes
- pid of child process or 0 if forked process
vfprintf
Formats and writes text to stream.
- struct FILE* f
- const char* fmt
- struct __va_list* va
- const char* fmt
- int
vfprintf_unlocked
Formats and writes text to stream.
- struct FILE* f
- const char* fmt
- struct __va_list* va
- const char* fmt
- int
vfscanf
Stream decoder.
- struct FILE* stream
- const char* fmt
- struct __va_list* ap
- const char* fmt
- int
vga_console
Code snippet for initializing the VGA video mode for bare metal.
If a program requests VGA support (by yoinking vga_console), and it is started in bare metal mode, then try to ensure that the VGA monitor is in a known mode. This is easier to do while the program is still running in real mode.
This module also ropes in the sys_writev_vga routine, which implements the actual VGA console output under x86-64 long mode.
vigna
Returns deterministic pseudorandom data, e.g.
uint64_t x = vigna();You can generate different types of numbers as follows:
int64_t x = vigna() >> 1; // make positive signed integer double x = _real1(vigna()); // make float on [0,1]-intervalYou can seed this random number generator using:
svigna(rdseed());You may use the reentrant version of this function:
static uint64_t s = 0; uint64_t x = svigna_r(&s);If you want to fill a buffer with data then rngset() implements vigna's algorithm to do that extremely well:
char buf[4096]; rngset(buf, sizeof(buf), vigna, 0);If you want a fast pseudorandom number generator that seeds itself automatically on startup and fork(), then consider _rand64. If you want true random data then consider rdseed, rdrand, and getrandom.
- unsigned long
- 64 bits of pseudorandom data
vigna_r
Returns pseudorandom data.
- unsigned long* state
- unsigned long
VisualizeControlCodes
Makes control codes and trojan source plainly viewable.
This is useful for logging data like HTTP messages, where we don't want full blown C string literal escaping, but we don't want things like raw ANSI control codes from untrusted devices in our terminals.
This function also canonicalizes overlong encodings. Therefore it isn't necessary to say VisualizeControlCodes(Underlong(𝑥))) since VisualizeControlCodes(𝑥) will do the same thing.
- const char* data
- is input value
- unsigned long size
- if -1 implies strlen
- unsigned long* out_size
- if non-NULL receives output length
- char*
- allocated NUL-terminated buffer, or NULL w/ errno
vprintf
Formats and writes text to stdout.
- const char* fmt
- struct __va_list* va
- int
vscanf
String decoder.
- const char* fmt
- struct __va_list* ap
- int
vsnprintf
Formats string to buffer w/ preexisting vararg state.
- char* buf
- stores output
- unsigned long size
- is byte capacity buf
- const char* fmt
- struct __va_list* va
- int
- number of bytes written, excluding the NUL terminator; or, if the output buffer wasn't passed, or was too short, then the number of characters that *would* have been written is returned
vsprintf
Formats string to buffer hopefully large enough w/ vararg state.
- char* buf
- const char* fmt
- struct __va_list* va
- const char* fmt
- int
vsscanf
Decodes string.
- const char* str
- const char* fmt
- struct __va_list* va
- const char* fmt
- int
wait
Waits for status to change on any child process.
- int* opt_out_wstatus
- optionally returns status code, and *wstatus may be inspected using WEEXITSTATUS(), etc.
- int
- process id of terminated child or -1 w/ errno
wait3
Waits for status to change on any child process.
- int* opt_out_wstatus
- optionally returns status code, and *wstatus may be inspected using WEEXITSTATUS(), etc.
- int options
- can have WNOHANG, WUNTRACED, WCONTINUED, etc.
- struct rusage* opt_out_rusage
- optionally returns accounting data
- int
- process id of terminated child or -1 w/ errno
wait4
Waits for status to change on process.
- int pid
- >0 targets specific process, =0 means any proc in a group, -1 means any child process, <-1 means any proc in specific group
- int* opt_out_wstatus
- optionally returns status code, and *wstatus may be inspected using WEEXITSTATUS(), etc.
- int options
- can have WNOHANG, WUNTRACED, WCONTINUED, etc.
- struct ruchlds* opt_out_rusage
- optionally returns accounting data
- int
- process id of terminated child or -1 w/ errno
waitpid
Waits for status to change on process.
- int pid
- >0 targets specific process, =0 means any proc in a group, -1 means any child process, <-1 means any proc in specific group
- int* opt_out_wstatus
- optionally returns status code, and *wstatus may be inspected using WEXITSTATUS(), etc.
- int options
- can have WNOHANG, WUNTRACED, WCONTINUED, etc.
- int
- process id of terminated child or -1 w/ errno
wchomp
Mutates line to remove line-ending characters.
- int* line
- is NULL-propagating
- int*
wcscasecmp
Compares NUL-terminated wide strings case-insensitively.
- const int* a
- is first non-null NUL-terminated string pointer
- const int* b
- is second non-null NUL-terminated string pointer
- int
- is <0, 0, or >0 based on uint8_t comparison
wcscat
Appends 𝑠 to 𝑑.
- int* d
- const int* s
- int*
- 𝑑
wcschr
Returns pointer to first instance of character.
- const int* s
- int c
- int*
wcscmp
Compares NUL-terminated wide strings.
- const int* a
- is first non-null NUL-terminated string pointer
- const int* b
- is second non-null NUL-terminated string pointer
- int
- is <0, 0, or >0 based on uint8_t comparison
wcscpy
Copies NUL-terminated wide character string.
𝑑 and 𝑠 must not overlap unless 𝑑 ≤ 𝑠.
- int* d
- is destination memory
- const int* s
- is a NUL-terminated string
- int*
- original d
wcscspn
Returns prefix length, consisting of chars not in reject. a.k.a. Return index of first byte that's in charset.
- const int* s
- const int* reject
- is nul-terminated character set
- unsigned long
wcsendswith
Returns true if s has suffix.
- const int* s
- is a NUL-terminated string
- const int* suffix
- is also NUL-terminated
- int
wcsftime_l
- int* s
- unsigned long n
- const int* f
- struct tm* tm
- struct __global_locale* loc
- unsigned long n
- unsigned long
wcslen
Returns length of NUL-terminated wide string.
- const int* s
- is non-null NUL-terminated wide string pointer
- unsigned long
- number of wide characters (excluding NUL)
wcsncasecmp
Compares NUL-terminated wide strings case-insensitively w/ limit.
- const int* a
- is first non-null NUL-terminated string pointer
- const int* b
- is second non-null NUL-terminated string pointer
- unsigned long n
- int
- is <0, 0, or >0 based on uint8_t comparison
wcsncat
Appends at most 𝑛 wides from 𝑠 to 𝑑.
- int* d
- const int* s
- unsigned long n
- const int* s
- int*
- 𝑑
wcsncmp
Compares NUL-terminated wide strings w/ limit.
- const int* a
- is first non-null NUL-terminated string pointer
- const int* b
- is second non-null NUL-terminated string pointer
- unsigned long n
- int
- is <0, 0, or >0 based on uint8_t comparison
wcsnlen
Returns length of NUL-terminated wide string w/ limit.
- const int* s
- is wide string
- unsigned long n
- is max length (a count of wide characters, not bytes)
- unsigned long
- length in characters
wcsnlen_s
Returns length of NUL-terminated wide string w/ limit & blankets.
- const int* s
- is wide string
- unsigned long n
- is max length (a count of wide characters, not bytes)
- unsigned long
- length in characters
wcsnwidth
Returns monospace display width of wide character string.
- const int* pwcs
- unsigned long n
- unsigned long o
- unsigned long n
- int
wcspbrk
Returns pointer to first byte matching any in accept, or NULL.
- const int* s
- const int* accept
- int*
wcsrchr
Searches for last instance of wchar_t in string.
- const int* s
- is NUL-terminated wchar_t string to search
- int c
- is the needle
- int*
- address of last c in s, or NULL if not found
wcsspn
Returns prefix length, consisting of chars in accept.
- const int* s
- const int* accept
- is nul-terminated character set
- unsigned long
wcsstartswith
Returns true if s has prefix.
- const int* s
- is a NUL-terminated string
- const int* prefix
- is also NUL-terminated
- int
wcsstr
Searches for substring.
- const int* haystack
- is the search area, as a NUL-terminated string
- const int* needle
- is the desired substring, also NUL-terminated
- int*
- pointer to first substring within haystack, or NULL
wcstok
Extracts non-empty tokens from string.
- int* s
- is mutated and should be NULL on subsequent calls
- const int* sep
- is a NUL-terminated set of wchars to consider separators
- int** state
- tracks progress between calls
- int*
- pointer to next token or NULL for end
wcstol
Decodes signed long integer from wide string.
- const int* s
- is a non-null nul-terminated string
- int** endptr
- if non-null will always receive a pointer to the char following the last one this function processed, which is usually the NUL byte, or in the case of invalid strings, would point to the first invalid character
- int base
- can be anywhere between [2,36] or 0 to auto-detect based on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or decimal (base 10) by default
- long
- the decoded signed saturated number
wcstoul
Decodes unsigned integer from wide string.
- const int* s
- is a non-null nul-terminated string
- int** endptr
- if non-null will always receive a pointer to the char following the last one this function processed, which is usually the NUL byte, or in the case of invalid strings, would point to the first invalid character
- int base
- can be anywhere between [2,36] or 0 to auto-detect based on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or decimal (base 10) by default
- unsigned long
- decoded integer mod 2⁶⁴ negated if leading
-
wcswidth
Returns monospace display width of wide character string.
- const int* pwcs
- unsigned long o
- int
wctype
Returns number representing character class name.
- const char* s
- can be "alnum", "alpha", "blank", "cntrl", "digit", "graph", "lower", "print", "punct", "space", "upper", "xdigit"
- unsigned int
- nonzero id or 0 if not found
WindowsTimeToTimeSpec
Converts Windows COBOL timestamp to UNIX epoch in nanoseconds.
- long x
- ANONYMOUS-STRUCT
WindowsTimeToTimeVal
Converts Windows COBOL timestamp to UNIX epoch in microseconds.
- long x
- ANONYMOUS-STRUCT
wmemchr
Returns pointer to first instance of character in range.
- const int* s
- int c
- unsigned long n
- int c
- int*
wmemcmp
Compares arrays of 32-bit signed integers.
- const int* a
- is first memory array
- const int* b
- is second memory array
- unsigned long n
- is number of elements in
a
andb
to consider
- int
- is <0, 0, or >0 based on int32_t comparison
wmemrchr
Returns pointer to first instance of character.
- const int* s
- is memory to search
- int c
- is search word
- unsigned long n
- is number of wchar_t elements in
s
- void*
- is pointer to first instance of c or NULL if not found
wmemset
Sets wide memory.
- int* p
- int c
- unsigned long n
- int c
- int*
write
Writes data to file descriptor.
This function changes the current file position. For documentation on file position behaviors and gotchas, see the lseek() function. This function may be used on socket file descriptors, including on Windows.
- int fd
- is open file descriptor
- void* buf
- is copied from, cf. copy_file_range(), sendfile(), etc.
- unsigned long size
- is always saturated to 0x7ffff000 automatically
- long
- [1..size] bytes on success, or -1 w/ errno; noting zero is impossible unless size was passed as zero to do an error check
fd
is negative or not an open file descriptor
fd
wasn't opened with O_WRONLY
or O_RDWR
fd
is a pipe whose other reader end was closed,
after the SIGPIPE
signal was delivered, blocked, or ignored
RLIMIT_FSIZE
soft limit was exceeded, after the
SIGXFSZ
signal was either delivered, blocked, or ignored
size
is nonzero and buf
points to bad memory
fd
is full
O_NONBLOCK
is in play and write needs to block
writev
Writes data from multiple buffers.
This is the same thing as write() except it has multiple buffers. This yields a performance boost in situations where it'd be expensive to stitch data together using memcpy() or issuing multiple syscalls. This wrapper is implemented so that writev() calls where iovlen<2 may be passed to the kernel as write() instead. This yields a 100 cycle performance boost in the case of a single small iovec.
Please note that it's not an error for a short write to happen. This can happen in the kernel if EINTR happens after some of the write has been committed. It can also happen if we need to polyfill this system call using write().
It's possible for file write request to be partially completed. For
example, if the sum of iov
lengths exceeds 0x7ffff000 then bytes
beyond that will be ignored. This is a Linux behavior that Cosmo
polyfills across platforms.
- int fd
- struct iovec* iov
- int iovlen
- struct iovec* iov
- long
- number of bytes actually handed off, or -1 w/ errno
WSAGetOverlappedResult
Gets overlap i/o result.
- unsigned long s
- struct NtOverlapped* lpOverlapped
- unsigned int* out_lpcbTransfer
- int fWait
- unsigned int* out_lpdwFlags
- struct NtOverlapped* lpOverlapped
- int
- true on success, or false on failure
WSAStartup
Winsock2 prototypes.
- int
xasprintf
Returns dynamically formatted string.
- const char* fmt
- ...
- char*
- must be free()'d or gc()'d
xbarf
Writes data to file.
- const char* path
- void* data
- unsigned long size
- void* data
- can be -1 to strlen(data)
- int
- 0 on success or -1 w/ errno
xbasename
Returns base portion of path.
- const char* path
- char*
xcalloc
Allocates initialized memory, or dies.
- unsigned long count
- unsigned long size
- void*
xdirname
Returns directory portion of path.
- const char* path
- char*
xdtoa
Converts double to string the easy way.
- double d
- char*
- string that needs to be free'd
xdtoaf
Converts double to string w/ high-accuracy the easy way.
- float d
- char*
- string that needs to be free'd
xdtoal
Converts long double to string the easy way.
- long double d
- char*
- string that needs to be free'd
xgetline
Reads line from stream.
- struct FILE* f
- char*
- allocated line that needs free() and usually chomp() too, or NULL on ferror() or feof()
xjoinpaths
Joins paths, e.g.
"a" + "b" → "a/b" "a/" + "b" → "a/b" "a" + "b/" → "a/b/" "a" + "/b" → "/b" "." + "b" → "b" "" + "b" → "b"
- const char* path
- const char* other
- char*
- newly allocated string of resulting path
xload
Inflates data once atomically, e.g.
void *GetData(void) { static _Atomic(void *) ptr; static const unsigned char rodata[] = {...}; return xload(&ptr, rodata, 112, 1024); }The above is an example of how this helper may be used to have lazy loading of big infrequently accessed image data.
- void* a_
- void* p
- is read-only data compressed using raw deflate
- unsigned long n
- is byte length of deflated data
- unsigned long m
- is byte length of inflated data
- void*
- pointer to inflated data
xmalloc
Allocates uninitialized memory, or dies.
- unsigned long bytes
- void*
xmemalign
Allocates aligned memory, or dies.
- unsigned long alignment
- unsigned long bytes
- void*
xmemalignzero
Allocates aligned cleared memory, or dies.
- unsigned long alignment
- unsigned long bytes
- void*
xrealloc
Allocates/expands/shrinks/frees memory, or die.
This API enables you to do the following:
p = xrealloc(p, n)The standard behaviors for realloc() still apply:
!p
means xmalloc (returns non-NULL)p && n
means resize (returns non-NULL)p && !n
means free (returns NULL)
- void* p
- unsigned long n
- void*
xsigaction
Installs handler for kernel interrupt, e.g.:
onctrlc(sig) { exit(128+sig); } CHECK_NE(-1, xsigaction(SIGINT, onctrlc, SA_RESETHAND, 0, 0));
- int sig
- can be SIGINT, SIGTERM, etc.
- void* handler
- is SIG_DFL, SIG_IGN, or a pointer to a 0≤arity≤3 callback function passed (sig, siginfo_t *, ucontext_t *).
- unsigned long flags
- can have SA_RESETHAND, SA_RESTART, SA_SIGINFO, etc.
- unsigned long mask
- is 1ul«SIG₁[…|1ul«SIGₙ] bitset to block in handler
- struct sa* old
- optionally receives previous handler
- int
- 0 on success, or -1 w/ errno
xslurp
Reads entire file into memory.
- const char* path
- unsigned long* opt_out_size
- void*
- NUL-terminated malloc'd contents, or NULL w/ errno
xspawn
Spawns process using fork().
- struct rusage* r
- if provided gets accounting data
- int
- wstatus, or -2 on child, or -1 w/ errno
xstrcat
Concatenates strings / chars to newly allocated memory, e.g.
xstrcat("hi", ' ', "there")Or without the C99 helper macro:
(xstrcat)("hi", ' ', "there", NULL)This goes twice as fast as the more powerful xasprintf(). It's not quadratic like strcat(). It's much slower than high-effort stpcpy(), particularly with string literals.
- const char* s
- ...
- char*
xstrdup
Allocates new copy of string, or dies.
- const char* s
- char*
xstripext
Removes file extension.
- const char* s
- is mutated
- char*
- s
xstripexts
Removes file extensions.
- const char* s
- is mutated
- char*
- s
xstrndup
Allocates new copy of string, with byte limit.
- const char* s
- is a NUL-terminated byte string
- unsigned long n
- if less than strlen(s) will truncate the string
- char*
- new string or NULL w/ errno
xunbing
Decodes CP437 glyphs to bounds-checked binary buffer, e.g.
char *mem = xunbing(u" ☺☻♥♦"); EXPECT_EQ(0, memcmp("\0\1\2\3\4", mem, 5)); tfree(mem);
- const unsigned short* binglyphs
- void*
xunbinga
Same as xunbing() w/ alignment guarantee.
- unsigned long a
- const unsigned short* binglyphs
- void*
xvalloc
Allocates frame-aligned memory, or dies.
- unsigned long size
- void*
xvasprintf
Returns dynamically formatted string.
- const char* fmt
- struct __va_list* va
- char*
- fully formatted string, which must be free()'d
xvspawn
Spawns process using vfork().
- void(*)() f
- is child callback
- void* ctx
- struct rusage* r
- if provided gets accounting data
- int
- wstatus, or -1 w/ errno
xwrite
Writes data uninterruptibly.
- int fd
- void* p
- unsigned long n
- void* p
- int
- 0 on success, or -1 w/ errno
zleb64
Encodes signed integer to array w/ zig-zag encoding.
uleb64 INT64_MAX l: 10𝑐 3𝑛𝑠 zleb64 INT64_MAX l: 13𝑐 4𝑛𝑠 sleb64 INT64_MAX l: 16𝑐 5𝑛𝑠 uleb128 INT64_MAX l: 18𝑐 6𝑛𝑠 zleb128 INT64_MAX l: 18𝑐 6𝑛𝑠 sleb128 INT64_MAX l: 24𝑐 8𝑛𝑠
- char* p
- is output array which should have 10 items
- long x
- is number
- char*
- p + i