libc_service.master

Synopsis

local libc_service = require "libc_service"

The master arbiters calls to libc that are related to ambient authority in the process holding the slave end. Before a call to the real libc is attempted in the slave end, the process forwards the request to the master and blocks the thread until a reply is received.

The protocol follows the request-reply model. Low-level protocol details are hidden by the Emilua runtime and the Lua programmer only sees a request-reply API.

Multiplexing is not allowed. That means only one thread from the slave end can be served at anytime and this layout will minimize the opportunity for possible parallelism if the process holding the slave end makes too many calls for ambient authority access. As a hidden implementation detail, Emilua will transparently pipeline requests from different threads to minimize latency a little.

Functions

receive(self)

Receive the next attempted libc call for ambient authority.

Data about the call is stored in the object’s properties.

send(self, result: value, errno: integer|generic_error|system_error = 0)

Send the result for the currently arbitrated libc call.

Function result

open

integer

openat

integer

unlink

integer

rename

integer

stat, lstat

On error, it should be the number -1.

On success, it should be an object (table) with the following properties:

dev: number

Device ID.

ino: number

Inode number.

mode: number

File access mode bits.

type: "regular"|"directory"|"symlink"|"block"|"character"|"fifo"|"socket"

File type.

nlink: number

Number of hardlinks.

uid: number

User ID of owner.

gid: number

Group ID of owner.

rdev: number

Like dev, but for special files.

size: number

Total size, in bytes.

atime: filesystem.clock.time_point

The time of the last access.

mtime: filesystem.clock.time_point

The time of the last modification.

ctime: filesystem.clock.time_point

The time of the last status change.

blksize: number

Block size for filesystem I/O.

blocks: number

Number of blocks allocated.

access, eaccess

integer

mkdir

integer

rmdir

integer

connect_unix

integer

connect_inet

integer

connect_inet6

integer

bind_unix

integer

bind_inet

integer

bind_inet6

integer

getaddrinfo

On error, it should be one of the strings below:

  • "again"

  • "badflags"

  • "fail"

  • "family"

  • "memory"

  • "noname"

  • "service"

  • "socktype"

  • "system"

On success, it should be an array with the following members (in the same order):

ip: ip.address

The address the query resolved to.

service: integer|nil

The service port the query resolved to.

Alternatively, if the call should succeed with a reply of 0 elements (a valid scenario for DNS and getaddrinfo()), the the value nil can be used instead.

send_with_fds(self, result: value, fds: file_descriptor[], errno: integer|generic_error|system_error = 0)

Send the result for the currently arbitrated libc call.

Function result

open

integer

openat

integer

unlink

integer

rename

integer

stat, lstat

On error, it should be the number -1.

On success, it should be an object (table) with the following properties:

dev: number

Device ID.

ino: number

Inode number.

mode: number

File access mode bits.

type: "regular"|"directory"|"symlink"|"block"|"character"|"fifo"|"socket"

File type.

nlink: number

Number of hardlinks.

uid: number

User ID of owner.

gid: number

Group ID of owner.

rdev: number

Like dev, but for special files.

size: number

Total size, in bytes.

atime: filesystem.clock.time_point

The time of the last access.

mtime: filesystem.clock.time_point

The time of the last modification.

ctime: filesystem.clock.time_point

The time of the last status change.

blksize: number

Block size for filesystem I/O.

blocks: number

Number of blocks allocated.

access, eaccess

integer

mkdir

integer

rmdir

integer

connect_unix

integer

connect_inet

integer

connect_inet6

integer

bind_unix

integer

bind_inet

integer

bind_inet6

integer

getaddrinfo

On error, it should be one of the strings below:

  • "again"

  • "badflags"

  • "fail"

  • "family"

  • "memory"

  • "noname"

  • "service"

  • "socktype"

  • "system"

On success, it should be an array with the following members (in the same order):

ip: ip.address

The address the query resolved to.

service: integer|nil

The service port the query resolved to.

Alternatively, if the call should succeed with a reply of 0 elements (a valid scenario for DNS and getaddrinfo()), the the value nil can be used instead.

use_slave_credentials(self)

Forward the request to the real libc running in the slave end.

arguments(self) → value…​

The arguments passed to the last requested call.

The arguments depend on the called function (see the property function_ below).

open
path: filesystem.path

The file path.

flags: string[]

The open flags.

flags may contain:

"append"

Open the file in append mode.

"create"

Create the file if it does not exist.

"directory"

If pathname is not a directory, cause the open to fail.

"exclusive"

Ensure a new file is created. Must be combined with create.

"no_follow"

Fail if path resolves to a symbolic link.

"path"

Get a stable reference to an inode without actually opening the contents.

"read_only"

Open the file for reading.

"read_write"

Open the file for reading and writing.

"sync_all_on_write"

Open the file so that write operations automatically synchronise the file data and metadata to disk (FILE_FLAG_WRITE_THROUGH/O_SYNC).

"temporary"

Create an unnamed temporary regular file.

"truncate"

Open the file with any existing contents truncated.

"write_only"

Open the file for writing.

mode: integer

Optional argument. Only present if "create" or "temporary" appear in flags.

openat
path: filesystem.path

The file path.

flags: string[]

The open flags.

flags may contain:

"append"

Open the file in append mode.

"create"

Create the file if it does not exist.

"directory"

If pathname is not a directory, cause the open to fail.

"exclusive"

Ensure a new file is created. Must be combined with create.

"no_follow"

Fail if path resolves to a symbolic link.

"path"

Get a stable reference to an inode without actually opening the contents.

"read_only"

Open the file for reading.

"read_write"

Open the file for reading and writing.

"sync_all_on_write"

Open the file so that write operations automatically synchronise the file data and metadata to disk (FILE_FLAG_WRITE_THROUGH/O_SYNC).

"temporary"

Create an unnamed temporary regular file.

"truncate"

Open the file with any existing contents truncated.

"write_only"

Open the file for writing.

"resolve_beneath"

Path resolution must not cross the fd directory.

"resolve_in_root"

Treat the directory referred to by dirfd as the root directory while resolving pathname. Absolute symbolic links are interpreted relative to dirfd.

"resolve_no_magiclinks"

Disallow all magic-link resolution during path resolution.

"resolve_no_symlinks"

Disallow resolution of symbolic links during path resolution.

"resolve_no_xdev"

Disallow traversal of mount points during path resolution (including all bind mounts).

"resolve_cached"

Make the open operation fail unless all path components are already present in the kernel’s lookup cache.

mode: integer

Optional argument. Only present if "create" or "temporary" appear in flags.

unlink
path: filesystem.path

The file path.

rename
path1: filesystem.path

The file1 path.

path2: filesystem.path

The file2 path.

stat
lstat
path: filesystem.path

The file path.

access
eaccess
path: filesystem.path

The file path.

amode: "f"|string[]

Requested access mode.

It’s either "f", or an array of strings that may contain:

"r"

R_OK. Read permission.

"w"

W_OK. Write permission.

"x"

X_OK. Execute permission.

mkdir
path: filesystem.path

The file path.

mode: integer

File access mode bits.

rmdir
path: filesystem.path

The file path.

connect_unix
path: filesystem.path

The UNIX socket path.

connect_inet
ipv4_addr: ip.address

The IPv4 address.

port: integer

The port.

connect_inet6
ipv6_addr: ip.address

The IPv6 address.

port: integer

The port.

bind_unix
path: filesystem.path

The UNIX socket path.

bind_inet
ipv4_addr: ip.address

The IPv4 address.

port: integer

The port.

bind_inet6
ipv6_addr: ip.address

The IPv6 address.

port: integer

The port.

getaddrinfo
node: string

An Internet host such as host.example.

service: string

An Internet service such as http.

protocol: "tcp"|"udp"|nil

An Internet protocol. Only really useful if you’re resolving the service as well.

descriptors(self) → file_descriptor…​

Extract and return the file descriptors received with the last requested call.

Once you call this function, the returned descriptors no longer stay stored in this object. IOW, a second call to this function will always return nothing.

Properties

function_: string

The last requested call.

Possible values:

  • "open"

  • "openat"

  • "unlink"

  • "rename"

  • "stat"

  • "lstat"

  • "access"

  • "eaccess"

  • "mkdir"

  • "rmdir"

  • "connect_unix"

  • "connect_inet"

  • "connect_inet6"

  • "bind_unix"

  • "bind_inet"

  • "bind_inet6"

  • "getaddrinfo"