POSIX#

📦 min

The POSIX (IEEE Std 1003.1) C standard library, exposed to Perl.

Reach for POSIX when you need something the Perl core does not give you directly: a strftime format, setlocale to switch numeric conventions, sigaction for signal handling, wait-status macros like WIFEXITED / WEXITSTATUS, mkfifo, or any of the hundreds of E* / O_* / F_* / S_* constants from <errno.h>, <fcntl.h>, and friends.

use POSIX qw(strftime floor ceil fmod :sys_wait_h);
use POSIX qw(:math_h_c99);

print strftime("%Y-%m-%d %H:%M:%S", gmtime 86400 * 365), "\n";   # 1971-01-01 00:00:00
printf "%s %s %s %s\n", floor(-1.5), ceil(-1.5), fmod(7, -3), round(2.5);   # -2 -1 1 3

system $^X, '-e', 'exit 3';
print "exited ", WEXITSTATUS($?), "\n" if WIFEXITED($?);           # exited 3

printf "EINTR is %d, PATH_MAX %d\n", POSIX::EINTR, POSIX::PATH_MAX;   # 4, 4096

The functions below are the C library’s, called directly, so they behave as the host’s C library does (glibc or musl on Linux). This is a native implementation of the XS half of POSIX 2.26; its POSIX.pm is used unchanged. That .pm also provides the many POSIX names that are perl built-ins under another name (POSIX::printf is printf, POSIX::exit is exit, POSIX::getpid is $$ …), the classes POSIX::SigSet, POSIX::SigAction and POSIX::Termios, and a helpful die for the C functions that make no sense in Perl (POSIX::malloc, POSIX::strcpy …).

use POSIX with no list exports 587 names - most of the C89 library and its constants. Ask for less: a list of names, or one of the tags named after the C header it comes from (:sys_wait_h, :fcntl_h, :math_h, :math_h_c99 for the C99 math functions, :termios_h, :signal_h, …). The C99 functions are never exported by default.

Every macro the platform defines is a constant sub. Any other name dies when called: one POSIX knows but the platform lacks with “Your vendor has not defined POSIX macro OPEN_MAX, used at FILE line N”, one that is no POSIX macro with “tcgetattr is not a valid POSIX macro at FILE line N” - the location being the caller’s.

Differences from upstream#

One, where perl 5.44 with POSIX.xs fails: a NaN payload of 2**64 or more (nan(1e20), setpayload($x, 1e20)) gives the largest payload and warns “payload lost bits”. POSIX.xs’s conversion of such a number is undefined C: on x86-64 it gives payload 0 and no warning, losing every bit silently (t/81-xs-native/POSIX/380-or-better.t).

Modules#

Functions#

Math#

acos#

acos($x): the arc cosine of $x, in radians; NaN outside -1..1. Exported by default.

acosh#

acosh($x): the inverse hyperbolic cosine; NaN below 1.

asin#

asin($x): the arc sine of $x, in radians; NaN outside -1..1. Exported by default.

asinh#

asinh($x): the inverse hyperbolic sine.

atan#

atan($x): the arc tangent of $x, in radians, between -pi/2 and pi/2. Perl’s own atan2($y, $x) covers the full circle. Exported by default.

atanh#

atanh($x): the inverse hyperbolic tangent; infinite at -1 and 1, NaN outside them.

cbrt#

cbrt($x): the cube root, negative for negative $x: cbrt(-27) is -3.

ceil#

ceil($x): the smallest integral value not below $x, as a floating-point number: ceil(-1.5) is -1. Exported by default.

cosh#

cosh($x): the hyperbolic cosine. Exported by default.

erf#

erf($x): the error function.

erfc#

erfc($x): the complementary error function, 1 - erf($x), computed without the loss of precision for large $x.

exp2#

exp2($x): 2 to the power $x.

expm1#

expm1($x): exp($x) - 1, accurate for $x near 0.

floor#

floor($x): the largest integral value not above $x, as a floating-point number: floor(-1.5) is -2. Exported by default.

j0#

j0($x): the Bessel function of the first kind of order 0; j1 is order 1, jn any order.

j1#

j1($x): the Bessel function of the first kind of order 1.

lgamma#

lgamma($x): the natural logarithm of the absolute value of the gamma function: lgamma(5) is log(24).

log10#

log10($x): the base-10 logarithm. Exported by default.

log1p#

log1p($x): log(1 + $x), accurate for $x near 0.

log2#

log2($x): the base-2 logarithm.

logb#

logb($x): the binary exponent of $x, as a floating-point number: logb(8) is 3. ilogb returns it as an integer.

nearbyint#

nearbyint($x): $x rounded to an integral value in the current rounding mode (see fesetround), without raising the inexact floating-point exception.

rint#

rint($x): $x rounded to an integral value in the current rounding mode; in the default mode halves go to the even neighbour: rint(2.5) is 2.

round#

round($x): $x rounded to the nearest integral value, halves away from zero: round(2.5) is 3, round(-2.5) is -3.

sinh#

sinh($x): the hyperbolic sine. Exported by default.

tan#

tan($x): the tangent of $x radians. Exported by default.

tanh#

tanh($x): the hyperbolic tangent. Exported by default.

tgamma#

tgamma($x): the gamma function: tgamma(5) is 24.

trunc#

trunc($x): $x with its fraction dropped, towards zero: trunc(-2.7) is -2.

y0#

y0($x): the Bessel function of the second kind of order 0; y1 is order 1, yn any order.

y1#

y1($x): the Bessel function of the second kind of order 1.

copysign#

copysign($x, $y): the magnitude of $x with the sign of $y, negative zero included: copysign(3, -0.0) is -3.

fdim#

fdim($x, $y): $x - $y when that is positive, else 0.

fmax#

fmax($x, $y): the larger of the two; a NaN argument is ignored: fmax(1, "nan") is 1.

fmin#

fmin($x, $y): the smaller of the two; a NaN argument is ignored.

fmod#

fmod($x, $y): the floating-point remainder of $x / $y, with the sign of $x: fmod(7, -3) is 1. Unlike %, it does not truncate its operands to integers. Exported by default.

hypot#

hypot($x, $y): sqrt($x**2 + $y**2), without overflow or underflow in the squares: hypot(3, 4) is 5.

nextafter#

nextafter($x, $y): the next representable floating-point number after $x in the direction of $y.

nexttoward#

nexttoward($x, $y): as nextafter; C’s version takes $y as a long double, which for a Perl number makes no difference.

remainder#

remainder($x, $y): $x - $n * $y with $n the integer nearest to $x / $y (halves to even), so the result can be negative: remainder(7, 3) is 1, remainder(8, 3) is -1.

frexp#

Split a floating-point number into mantissa and exponent.

modf#

Split a number into integer and fractional parts, both as doubles.

ldexp#

Compute $x * 2**$exp with a single rounding step.

Synopsis

my $y = POSIX::ldexp(1.5, 10);   # 1536

Differences from upstream

Fully compatible with upstream POSIX.

scalbn#

Compute $x * FLT_RADIX**$n efficiently. On IEEE-754 systems scalbn is equivalent to ldexp.

Differences from upstream

Fully compatible with upstream POSIX.

fma#

Fused multiply-add: $x * $y + $z with a single rounding.

nan#

Build a NaN, optionally carrying a payload.

remquo#

Floating-point remainder with partial quotient.

jn#

Bessel function of the first kind, integer order $n.

yn#

Bessel function of the second kind, integer order $n.

Float classification#

getpayload#

getpayload($nv) - the payload carried by the NaN $nv, as a number.

setpayload#

setpayload($nv, $payload) - make $nv a quiet NaN carrying $payload.

setpayloadsig#

setpayloadsig($nv, $payload) - make $nv a SIGNALING NaN carrying $payload, writing the result back into the first argument exactly as setpayload does.

issignaling#

issignaling($nv) - true when $nv is a signaling NaN.

fpclassify#

Classify a floating-point number.

ilogb#

Exponent of $x as an integer, trunc(log2(|$x|)).

Edge cases

  • ilogb(0) returns FP_ILOGB0 (typically INT_MIN).

  • ilogb(NaN) returns FP_ILOGBNAN.

  • ilogb(inf) returns INT_MAX.

Differences from upstream

Fully compatible with upstream POSIX.

isfinite#

isfinite($x): 1 when $x is neither infinite nor NaN, else 0.

isinf#

isinf($x): 1 when $x is infinite, of either sign, else 0.

isnan#

isnan($x): 1 when $x is NaN, else 0.

isnormal#

isnormal($x): 1 when $x is a normal number - not zero, subnormal, infinite or NaN: isnormal(1e-310) is 0.

signbit#

signbit($x): 1 when the sign bit of $x is set, which includes negative zero: signbit(-0.0) is 1.

lrint#

Round $x to the nearest integer, respecting the current rounding mode, and return it as an integer.

Differences from upstream

Fully compatible with upstream POSIX.

See also

  • lround - always rounds half-away-from-zero regardless of mode.

  • fegetround / fesetround - query or change the rounding mode.

lround#

Round $x half-away-from-zero to the nearest integer.

Differences from upstream

Fully compatible with upstream POSIX.

See also

  • lrint - rounds according to the current FP rounding mode.

isgreater#

isgreater($x, $y): 1 when $x > $y, else 0 - and 0 when either is NaN, as for isgreaterequal, isless, islessequal and islessgreater; isunordered tells that case apart.

isgreaterequal#

isgreaterequal($x, $y): 1 when $x >= $y, else 0.

isless#

isless($x, $y): 1 when $x < $y, else 0.

islessequal#

islessequal($x, $y): 1 when $x <= $y, else 0.

islessgreater#

islessgreater($x, $y): 1 when $x is less or greater than $y, 0 when they are equal or either is NaN.

isunordered#

isunordered($x, $y): 1 when either is NaN, so that they cannot be compared, else 0.

fegetround#

Current floating-point rounding direction.

What you get back

An integer matching one of the FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO constants.

Differences from upstream

Fully compatible with upstream POSIX.

See also

  • fesetround - change the mode.

FLT_ROUNDS#

The current rounding direction as C’s FLT_ROUNDS reports it.

fesetround#

Change the floating-point rounding direction.

Wait status#

WEXITSTATUS#

Exit code of a child that terminated normally.

WIFEXITED#

True if the child terminated normally (via exit or return from main).

Differences from upstream

Fully compatible with upstream POSIX.

WIFSIGNALED#

True if the child was killed by a signal.

Differences from upstream

Fully compatible with upstream POSIX.

See also

  • WTERMSIG - the signal number, when this is true.

WIFSTOPPED#

True if the child is stopped (usable with waitpid(..., WUNTRACED)).

Differences from upstream

Fully compatible with upstream POSIX.

WSTOPSIG#

Signal number that stopped the child, meaningful only when WIFSTOPPED($status) is true.

Differences from upstream

Fully compatible with upstream POSIX.

WTERMSIG#

Signal number that killed the child, meaningful only when WIFSIGNALED($status) is true.

Differences from upstream

Fully compatible with upstream POSIX.

Strings and printing#

mblen#

mblen($s, $n = ~0) - the number of bytes in the first multibyte character of $s, examining at most $n bytes.

mbtowc#

mbtowc($pwc, $s, $n = ~0) - decode the first multibyte character of $s into $pwc and return how many bytes it occupied.

wctomb#

wctomb($s, $wchar) - encode the wide character $wchar into $s and return the number of bytes written.

strtold#

strtold($str) - parse a floating-point number off the front of $str.

strtod#

Parse a double from the start of a string, locale-aware.

strtol#

Parse a signed integer from the start of a string, in a given base.

strtoul#

Parse an unsigned integer from the start of a string, in a given base.

strcoll#

Compare two strings using the current LC_COLLATE ordering.

What you get back

A negative, zero, or positive integer, suitable for use as a cmp-like sort return. The ordering depends on the locale set via setlocale(LC_COLLATE, ...).

Differences from upstream

Fully compatible with upstream POSIX.

strxfrm#

Locale-transformed form of a string, for repeated collation.

System and process#

cuserid#

cuserid($s = 0) - the login name associated with the process’s effective user ID, or undef when it cannot be determined.

setuid#

Change the real user ID of the current process.

What you get back

1 on success, 0 on failure (and $! is set). Permission is required; only privileged processes can switch to arbitrary UIDs.

Differences from upstream

Fully compatible with upstream POSIX.

setgid#

Change the real group ID of the current process.

What you get back

1 on success, 0 on failure.

Differences from upstream

Fully compatible with upstream POSIX.

setpgid#

Put process $pid into process group $pgid.

setsid#

Create a new session and become its leader.

What you get back

The new session ID on success, -1 on failure. The caller must not already be a process group leader.

Differences from upstream

Fully compatible with upstream POSIX.

uname#

Kernel and machine identification as a five-element list.

sysconf#

Runtime system configuration value for the given _SC_* name.

_exit#

Terminate the process immediately with the given status, skipping END blocks, destructors, and stdio flushing.

abort#

Abort the process abnormally (typically producing a core dump).

Differences from upstream

Fully compatible with upstream POSIX.

nice#

Adjust the current process’s scheduling niceness by $incr.

pause#

Suspend the process until any signal is delivered.

What you get back

Always -1 (with $! set to EINTR) once a signal handler returns - pause has no “success” exit path.

Differences from upstream

Fully compatible with upstream POSIX.

sleep#

Suspend the process for $secs seconds, or until a signal arrives.

What you get back

The number of seconds left unslept - 0 for a full sleep, or a positive remainder when a signal cut the sleep short.

Differences from upstream

Fully compatible with upstream POSIX.

File and I/O#

ttyname#

Device path of the terminal attached to $fd, or undef if none.

Differences from upstream

Fully compatible with upstream POSIX.

ctermid#

Path of the controlling terminal.

What you get back

On most systems, the string "/dev/tty".

Differences from upstream

Fully compatible with upstream POSIX.

getcwd#

Current working directory as an absolute path.

What you get back

The path as a byte string, or undef if the call fails (for example, if the process has no read permission on some ancestor directory).

Differences from upstream

Fully compatible with upstream POSIX.

See also

  • Cwd::getcwd - the recommended Perl-level interface.

access#

Check the caller’s permissions on a path.

lchown#

Change the owner/group of a symlink itself (without following it).

Synopsis

POSIX::lchown($uid, $gid, $path);

What you get back

1 on success, 0 on failure.

Differences from upstream

Fully compatible with upstream POSIX.

mkfifo#

Create a FIFO (named pipe) at $path with permission bits $mode.

What you get back

1 on success, 0 on failure.

Differences from upstream

Fully compatible with upstream POSIX.

open#

Open a file by path, returning a raw file descriptor.

close#

Close a raw file descriptor.

What you get back

"0 but true" on success, undef on failure. A negative $fd is rejected with $! set to EBADF.

Differences from upstream

Fully compatible with upstream POSIX.

See also

  • open, dup, dup2 - where fds come from.

dup#

Duplicate a file descriptor, returning the lowest-numbered unused fd.

What you get back

The new fd as an integer on success, undef on failure. A negative $fd is rejected with $! set to EBADF.

Differences from upstream

Fully compatible with upstream POSIX.

dup2#

Duplicate $fd1 onto $fd2, closing $fd2 first if necessary.

lseek#

Reposition the read/write offset of an open fd.

pipe#

Create an anonymous pipe and return its two fds.

read#

Read up to $nbytes bytes from $fd into $buffer.

write#

Write bytes from $buffer to $fd.

Time#

strftime#

Format a broken-down time as a string using a format template.

mktime#

Convert a broken-down local time into epoch seconds.

difftime#

Difference between two epoch times, $t1 - $t2, as a double.

Differences from upstream

Fully compatible with upstream POSIX.

tzset#

Refresh the process’s timezone information from the TZ environment variable.

Differences from upstream

Fully compatible with upstream POSIX.

tzname#

Short names of the current standard and daylight timezones.

clock#

Approximate processor time used by the program, in CLOCKS_PER_SEC units.

What you get back

An integer count of clock ticks. Divide by POSIX::CLOCKS_PER_SEC for seconds. On Linux this counts user+system CPU time of the whole process.

Differences from upstream

Fully compatible with upstream POSIX.

times#

Raw wall + CPU times of the process and its children, as a five-element list.

asctime#

Canonical English timestamp string from a broken-down time.

ctime#

Canonical English timestamp string for an epoch time, in local time.

Locale#

setlocale#

Query or change the program’s locale setting.

localeconv#

Numeric and monetary formatting rules for the active locale.

Errno and path limits#

fpathconf#

Runtime limit for a configuration variable on an open fd.

pathconf#

Runtime limit for a configuration variable on a pathname.

What you get back

The limit value, or -1 if unsupported/unlimited.

Differences from upstream

Fully compatible with upstream POSIX.

See also

  • fpathconf - same query on an already-open fd.

Terminal control#

tcdrain#

Block until all queued output on $fd has been transmitted.

What you get back

"0 but true" on success, undef on failure. A negative $fd sets $! to EBADF.

Differences from upstream

Fully compatible with upstream POSIX.

tcflow#

Suspend or resume transmission or reception on terminal $fd.

tcflush#

Discard buffered input, output, or both on terminal $fd.

tcsendbreak#

Send a continuous break condition on terminal $fd for roughly $duration tenths of a second (0 means the implementation default).

What you get back

"0 but true" on success, undef on failure. Negative $duration sets $! to EINVAL.

Differences from upstream

Fully compatible with upstream POSIX.

tcgetpgrp#

Process group ID of the foreground process group for terminal $fd.

What you get back

The pgid as an integer, or -1 on error (with $! set).

Differences from upstream

Fully compatible with upstream POSIX.

tcsetpgrp#

Make $pgrp the foreground process group of terminal $fd.

What you get back

"0 but true" on success, undef on failure.

Differences from upstream

Fully compatible with upstream POSIX.

Signals#

sigprocmask#

Change, query, or both the set of signals blocked for this process.

sigpending#

Fill $sigset with the signals currently pending for delivery.

What you get back

"0 but true" on success, undef on failure.

Differences from upstream

Fully compatible with upstream POSIX.

sigsuspend#

Temporarily replace the signal mask with $sigset and suspend the process until any non-blocked signal arrives.

What you get back

Always undef (with $! set to EINTR) once a signal handler has run - there is no success exit path.

Differences from upstream

Fully compatible with upstream POSIX.

sigaction#

Install or inspect a signal handler for signal $sig.