Introduction

Lua is a powerful, efficient, lightweight, embeddable scripting language.

WirePlumber uses Lua version 5.4 to implement its engine. For older systems, Lua 5.3 is also supported.

There are currently two uses for Lua in WirePlumber:

  • To implement the scripting engine

  • To implement lua-based config files

This section is only documenting the API of the scripting engine. Scripts can be ran with the wpexec tool.

Example scripts can be found in the tests/examples directory of the wireplumber source tree.

Lua Reference

If you are not familiar with the Lua language and its API, please refer to the Lua 5.4 Reference Manual

Sandbox

WirePlumber’s scripting engine sandboxes the lua scripts to a safe environment. In this environment, the following rules apply:

  • Scripts are isolated from one another; global variables in one script are not visible from another, even though they are actually executed in the same lua_State

  • Tables that hold API methods are not writable. While this may sound strange, standard Lua allows you to change standard API, for instance string.format = rogue_format is valid outside the sandbox. WirePlumber does not allow that.

  • The standard Lua API is limited to a subset of safe functions. For instance, functions that interact with the file system (io.*) and the process’s state (ex.: os.exit) are not allowed.

    Here is a full list of Lua functions (and API tables) that are exposed:

        ([[ _VERSION assert error ipairs   next pairs  tonumber
            pcall    select print tostring type xpcall require
            table    string math  package  utf8 debug  coroutine
            os.clock  os.difftime os.time  os.date     os.getenv
    
  • Object methods are not exposed in public tables. To call an object method you must use the method call syntax of Lua, i.e. object:method(params)

    The following, for instance, is not valid:

    -- this will cause an exception
    local node = ...
    Node.send_command(node, "Suspend")
    

    The correct form is this:

    local node = ...
    node:send_command("Suspend")