SkillAgentSearch skills...

Lunix

Lua Unix Module.

Install / Use

/learn @wahern/Lunix
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

About

lunix is a Lua bindings library module to common Unix system APIs. The module is regularly tested on recent versions of AIX, FreeBSD, Linux/glibc, Linux/musl, NetBSD, OpenBSD, OS X, and Solaris. The best way to describe it is in contradistinction to luaposix, the most popular bindings module for Unix APIs in Lua.

Thread-safety

Unlike luaposix, it strives to be as thread-safe as possible on the host platform. Interfaces like strerror_r and O_CLOEXEC are used throughout where appropriate. The module even includes a novel solution for the inherently non-thread-safe umask system call, where calling umask from one thread might result in another thread creating a file with unsafe or unexpected permissions.

POSIX Extensions

Unlike luaposix, the library does not restrict itself to POSIX, and where possible emulates an interface when not available natively on a supported platform. For example, the library provides arc4random (absent on Linux and older Solaris releases), clock_gettime (absent on older macOS releases), and a thread-safe timegm (absent on Solaris).

Leak-safety

Unlike luaposix, the library prefers dealing with FILE handles rather than raw integer descriptors. This helps to mitigate and prevent leaks or double-close bugs---a common source of problems in, e.g., asynchronous applications where a descriptor is closed that has already been reassigned to another resource. Routines like chdir, stat, and opendir transparently accept string paths, FILE handles, DIR handles, and raw integer descriptors.

Lua Versions

lunix supports the Lua 5.1, 5.2, and 5.3 APIs. lunix supports LuaJIT wth the caveat that when creating custom FILE handles using fdopen (directly or indirectly through, e.g., fdup) the process must have read access to an existing filesystem resource (presently . or /dev/null) in order to create a LUA_FILEHANDLE object in the VM. This might not work in some sandboxed environments.

Installation

The usual GNU-style flags are supported, such as CC, CPPFLAGS, CFLAGS, LDFLAGS, SOFLAGS, and LIBS. ...

TODO. See lunix Userguide PDF

API

Conventions

Namespace

Unlike recent versions of luaposix, interfaces are not grouped into submodules. (But see unix.unsafe submodule.) Both Unix and POSIX evolved organically over time and neither consistently group interfaces, either by header or any other singular convention. And while theoretically it could done de novo I feel that might add confusion and is otherwise wasted effort. In C the interfaces exist in a single namespace. While from a C source language perspective a small handful of interfaces technically have naming conflicts depending on which standard is selected at compile-time, in 2016 this is largely a theoretical problem. Where it does exist (e.g. GNU strerror_r vs POSIX strerror_r) this can easily be smoothed over transparently by lunix.

f prefix.

Following the example of fopen, lunix implements a sister interface for some routines to atomically wrap a descriptor within a FILE handle. This cannot be easily accomplished from Lua script because of the possibility of memory allocation failure. (Despite a widespread myth, this can easily happen even on systems like Linux in the presence of process resource limits, regardless of allocation size.) For example, the lunix routine fdup behaves just like dup but returns a FILE handle instead of an integer descriptor. Note that both dup and fdup will accept either an integer descriptor or FILE handle.

Errors

Generally, errors with argument type or format are thrown using lua_error. System errors are returned directly using the idiomatic 3-tuple Lua convention---nil or boolean false, error string description, error integer code.

Some internal allocation errors are returned as-if they were system errors, particularly where they arise in the C portion of an emulated routine. In such a case the call may return with ENOMEM even through neither the local system nor the POSIX specification specify such an error. Other allocation errors are thrown, particularly where they occur within the Lua/C preamble of a binding.

Arithmetic Overflow

The module takes great care to detect arithmetic overflow, including undefined arithmetic conversions between lua_Integer, lua_Number, and the relevant system types. When detected arithemtic overflow is generally treated as a type error and thrown (see Errors, above).

Constants

TODO. See lunix Userguide PDF.

Routines

All of the following routines are implemented though they may not yet be documented. Descriptions for some interfaces may be in the original PDF userguide.

accept

access

alarm

arc4random

arc4random : () -> (integer)

Returns a cryptographically strong, uniformly random 32-bit integer as a Lua number. On Linux the RANDOM_UUID sysctl feature is used to seed the generator if available; or on more recent Linux and Solaris kernels the getrandom interface.[^sysctl_uuid] This avoids fiddling with file descriptors, and also works in a chroot jail. On other platforms without a native arc4random interface, such as Solaris 11.2 or earlier, the implementation must resort to /dev/urandom for seeding.

Note that unlike the original implementation on OpenBSD, arc4random on some older platforms (e.g. FreeBSD prior to 10.10) seeds itself from /dev/urandom. This could cause problems in chroot jails.

[^sysctl_uuid]: Some Linux distributions, such as Red Hat, disable sysctl(2).

arc4random_buf

arc4random_buf : (n:integer) -> (string)

Returns a string of length $n$ containing cryptographically strong random octets using the same CSPRNG underlying arc4random.

arc4random_stir

arc4random_stir : () -> (true)

Stir the arc4random entropy pool using the best available resources. This normally should be unnecessary and is a noop on some systems.

arc4random_uniform

arc4random_uniform : (n:integer?) -> (integer)

Returns a cryptographically strong uniform random integer in the interval $[0, n-1]$ where $n \leq 2^{32}$. If $n$ is omitted the interval is $[0, 2^{32}-1]$ and effectively behaves like arc4random.

bind

bitand

bitor

chdir

chdir : (path:string|file|fd:integer) -> (true) | (false, string, integer)

If $dir$ is a string, attempts to change the current working directory using chdir(2). Otherwise, if $dir$ is a FILE handle referencing a directory, or an integer file descriptor referencing a directory, attempts to change the current working directory using fchdir(2).

Returns true on success, otherwise returns false, an error string, and an integer system error.

chmod

chown

chown : (path:string|file|fd:integer, uid?, gid?) -> (true) | (false, string, integer)

$file$ may either be a string path for use with chown(2), or a FILE handle or integer file descriptor for use with fchown(2). $uid$ and $gid$ may be integer values or symbolic string names.

Returns true on success, otherwise returns false, an error string, and an integer system error.

chroot

chroot : (path:string) -> (true) | (false, string, integer)

Attempt to chroot to the specified string $path$.

Returns true on success, otherwise returns false, an error string, and an integer system error.

clearerr

clock_gettime

clock_gettime : (id:string|id:number) -> (integer) | (nil, string, integer)

$id$ should be the string "realtime" or "monotonic", or the integer constant CLOCK_REALTIME or CLOCK_MONOTONIC.

Returns a time value as a Lua floating point number, otherwise returns nil, an error string, and an integer system error.

close

closedir

closedir : (DIR) -> (true) | (false, string, integer)

Closes the DIR handle, releasing the underlying file descriptor.

closelog

compl

connect

dup

dup2

dup3

execve

execve : (path:string, {string*}, {string*}) -> (false, string, integer)

Executes $path$, replacing the existing process image. $path$ should be an absolute pathname as the $PATH environment variable is not used. $argv$ is a table or ipairs--iterable object specifying the argument vector to pass to the new process image. Traditionally the first such argument should be the basename of $path$, but this is not enforced. If absent or empty the new process image will be passed an empty argument vector. $env$ is a table or ipairs--iterable object specifying the new environment. If absent or empty the new process image will contain an empty environment.

On success never returns. On failure returns false, an error string, and an integer system error.

execl

execl : (path:string, string*) -> (false, string, integer)

Executes $path$, replacing the existing process image. The $PATH environment variable is not used. Any subsequent arguments are passed to the new process image. The new process image inherits the current environment table.

On success never returns. On failure returns false, an error string, and an integer system error.

execlp

execlp : (file:string, string*) -> (false, string, integer)

Executes $file$, replacing the existing process image. The $PATH environment variable is used to search for $file$. Any subsequent arguments are passed to the new process image. The new process image inherits the current environment table.

On success never returns. On failure returns false, an error string, and an integer system error.

execvp

execvp : (file:string, string*) -> (false, string, integer)

Executes $file$, replacing the existing process image. The $PATH environment variable is used to search for $file$. An

Related Skills

View on GitHub
GitHub Stars61
CategoryDevelopment
Updated8d ago
Forks14

Languages

C

Security Score

90/100

Audited on Mar 23, 2026

No findings