Sunshine0.0.5917
Sunshine 0.0.5917
Self-hosted game stream host for Moonlight.
Loading...
Searching...
No Matches
misc.cpp File Reference

Miscellaneous definitions for Linux. More...

#include <array>
#include <cerrno>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <utility>
#include <arpa/inet.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <gio/gio.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <pwd.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/host_name.hpp>
#include <lizardbyte/common/env.h>
#include "graphics.h"
#include "misc.h"
#include "src/boost_process_compat.h"
#include "src/config.h"
#include "src/entry_handler.h"
#include "src/globals.h"
#include "src/logging.h"
#include "src/platform/common.h"
#include "src/platform/permissions.h"
#include "vaapi.h"
Include dependency graph for misc.cpp:

Classes

class  platf::linux_high_precision_timer
 Explicitly linux high-precision timer implementation backed by timerfd. More...
class  platf::qos_t
 Linux QoS state used to tune socket priority while streaming. More...

Macros

#define _GNU_SOURCE   1
 Macro for GNU SOURCE.
#define SOL_IP   IPPROTO_IP
 Macro for SOL IP.
#define SOL_IPV6   IPPROTO_IPV6
 Macro for SOL IPv6.
#define SOL_UDP   IPPROTO_UDP
 Macro for SOL UDP.
#define SUNSHINE_GNUC_EXTENSION
 Macro for SUNSHINE GNUC EXTENSION.

Typedefs

using platf::ifaddr_t = util::safe_ptr<ifaddrs, &freeifaddrs>
 Owning pointer for getifaddrs results.

Enumerations

enum  platf::source::source_e : std::size_t { platf::source::WAYLAND , platf::source::MAX_FLAGS }
 Enumerates supported source options. More...

Functions

void platf::adjust_thread_priority (thread_priority_e priority)
 Apply the requested scheduling priority to the current thread.
std::filesystem::path platf::appdata ()
 Performs migration if necessary, then returns the appdata directory.
std::unique_ptr< high_precision_timer > platf::create_high_precision_timer ()
 Create platform-specific timer capable of high-precision sleep.
std::shared_ptr< display_t > platf::display (mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config)
 Get the display_t instance for the given hwdevice_type. If display_name is empty, use the first monitor that's compatible you can find If you require to use this parameter in a separate thread, make a copy of it.
std::vector< std::string > platf::display_names (mem_type_e hwdevice_type)
 List display names accepted by the selected capture backend.
void platf::drop_elevated_privileges (bool all_caps)
 Drop elevated privileges (e.g. system admin/nice etc.).
void platf::enable_mouse_keys ()
 Enable or disable X11 mouse keys for the current session.
std::unique_ptr< deinit_t > platf::enable_socket_qos (uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type, bool dscp_tagging)
 Enable QoS on the given socket for traffic to the specified destination.
std::string platf::find_render_node_with_display ()
 Find the DRM render node associated with the active display.
std::string platf::from_sockaddr (const sockaddr *const)
 Convert a socket address to a printable IP address.
std::pair< std::uint16_t, std::string > platf::from_sockaddr_ex (const sockaddr *const)
 Convert a socket address to a port and printable IP address.
std::string platf::get_host_name ()
 Returns the current computer name in UTF-8.
ifaddr_t platf::get_ifaddrs ()
 Read the local interface address list.
std::string platf::get_mac_address (const std::string_view &address)
 Return the hardware MAC address associated with a network address.
std::vector< permission_status_t > platf::get_permission_statuses ()
 Query access needed by Sunshine on the current platform.
std::filesystem::path platf::get_xdg_restore_token_path ()
 XDG restore token path.
library_t * dyn::handle (const std::vector< const char * > &libs)
 Open the first available shared library from a nonempty list.
bool platf::has_elevated_privileges (bool all_caps)
 Check is the current process is running with elevated privileges (e.g. system admin/etc.).
std::unique_ptr< deinit_t > platf::init ()
 Initialize the platform-specific high precision timer.
int dyn::load (library_t *handle, const std::vector< std::tuple< apiproc *, const char * > > &funcs, bool strict)
 Load named functions from an open shared library.
bool platf::needs_encoder_reenumeration ()
 Check if GPUs/drivers have changed since the last call to this function.
int platf::open_drm_card_fd (const std::filesystem::path &path, int flags)
 Open a DRM card node, dropping implicit DRM master when possible.
void platf::open_url (const std::string &url)
 Open a url in the default web browser.
bool platf::process_group_running (std::uintptr_t native_handle)
 Check if a process group still has running children.
bool platf::request_permission (std::string_view id)
 Initiate a native request or settings action for an access item.
bool platf::request_process_group_exit (std::uintptr_t native_handle)
 Attempt to gracefully terminate a process group.
std::string platf::resolve_render_device ()
 Resolves the render device path to use for hardware encoding.
void platf::restart ()
 Restart the Sunshine process through the platform launcher.
void platf::restart_on_exit ()
 Request a Sunshine process restart on exit.
bp::child platf::run_command (bool, bool, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group)
 Launch a command using the caller's Linux privileges and session.
bool platf::sanitize_process_environment ()
 Remove environment variables that can load untrusted GUI modules.
bool platf::send (send_info_t &send_info)
 Send the serialized response over the active socket.
bool platf::send_batch (const batched_send_info_t &send_info)
 Send fixed-size UDP payload blocks without modifying the batch descriptor.
void platf::set_thread_name (std::string_view name)
 Name the current thread for use with development tools.
void platf::streaming_will_start ()
 Apply Linux platform state before streaming starts.
void platf::streaming_will_stop ()
 Restore Linux platform state after streaming stops.
struct sockaddr_in platf::to_sockaddr (boost::asio::ip::address_v4 address, uint16_t port)
 Convert to sockaddr.
struct sockaddr_in6 platf::to_sockaddr (boost::asio::ip::address_v6 address, uint16_t port)
 Convert to sockaddr.
bool platf::verify_wl ()
 Check whether Wayland capture is available for the current session.
std::shared_ptr< display_t > platf::wl_display (mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config)
 Create a Wayland display capture backend.
std::vector< std::string > platf::wl_display_names ()
 Enumerate displays available through the Wayland capture backend.

Variables

constexpr std::span< const cap_value_t > platf::ELEVATED_PRIVILEGES_ADMIN {ADMIN_CAPS}
 Protocol or platform constant for elevated privileges admin.
constexpr std::span< const cap_value_t > platf::ELEVATED_PRIVILEGES_FULL {FULL_CAPS}
 Protocol or platform constant for elevated privileges full.
window_system_e window_system
 Window system.

Detailed Description

Miscellaneous definitions for Linux.

Enumeration Type Documentation

◆ source_e

enum platf::source::source_e : std::size_t

Enumerates supported source options.

Enumerator
WAYLAND 

Wayland.

MAX_FLAGS 

The maximum number of flags.

Function Documentation

◆ adjust_thread_priority()

void platf::adjust_thread_priority ( thread_priority_e priority)

Apply the requested scheduling priority to the current thread.

Set the calling thread's Windows scheduling priority.

Parameters
priorityThread priority requested from the platform backend.

◆ appdata()

std::filesystem::path platf::appdata ( )

Performs migration if necessary, then returns the appdata directory.

This is used for the log directory, so it cannot invoke Boost logging!

Returns
The path of the appdata directory that should be used.

◆ create_high_precision_timer()

std::unique_ptr< high_precision_timer > platf::create_high_precision_timer ( )

Create platform-specific timer capable of high-precision sleep.

Returns
A unique pointer to timer

◆ display()

std::shared_ptr< display_t > platf::display ( platf::mem_type_e hwdevice_type,
const std::string & display_name,
const video::config_t & config )

Get the display_t instance for the given hwdevice_type. If display_name is empty, use the first monitor that's compatible you can find If you require to use this parameter in a separate thread, make a copy of it.

Parameters
display_nameThe name of the monitor that SHOULD be displayed
configStream configuration
Returns
The display_t instance based on hwdevice_type.

Pick a display adapter and capture method.

Parameters
hwdevice_typeenables possible use of hardware encoder

◆ display_names()

std::vector< std::string > platf::display_names ( mem_type_e hwdevice_type)

List display names accepted by the selected capture backend.

Parameters
hwdevice_typeHardware device type requested for capture or encode.
Returns
Display names accepted by the selected capture backend.

◆ drop_elevated_privileges()

void platf::drop_elevated_privileges ( bool all_caps)

Drop elevated privileges (e.g. system admin/nice etc.).

Parameters
all_capsBool that specifies whether to drop all caps or only CAP_SYS_ADMIN

◆ enable_socket_qos()

std::unique_ptr< deinit_t > platf::enable_socket_qos ( uintptr_t native_socket,
boost::asio::ip::address & address,
uint16_t port,
qos_data_type_e data_type,
bool dscp_tagging )

Enable QoS on the given socket for traffic to the specified destination.

Enables QoS on the given socket for traffic to the specified destination.

Parameters
native_socketThe native socket handle.
addressThe destination address for traffic sent on this socket.
portThe destination port for traffic sent on this socket.
data_typeThe type of traffic sent on this socket.
dscp_taggingSpecifies whether to enable DSCP tagging on outgoing traffic.
Returns
Cleanup handle that restores or releases QoS state when destroyed.

◆ find_render_node_with_display()

std::string platf::find_render_node_with_display ( )

Find the DRM render node associated with the active display.

Returns
Render-node path, or an empty string when no matching node is found.

◆ from_sockaddr()

std::string platf::from_sockaddr ( const sockaddr * const ip_addr)

Convert a socket address to a printable IP address.

Parameters
ip_addrSocket address to format.
Returns
Printable address, or an empty string for an unsupported address family.

◆ from_sockaddr_ex()

std::pair< std::uint16_t, std::string > platf::from_sockaddr_ex ( const sockaddr * const ip_addr)

Convert a socket address to a port and printable IP address.

Parameters
ip_addrSocket address to format.
Returns
Port in network byte order and printable address, or zero and an empty string for an unsupported family.

◆ get_host_name()

std::string platf::get_host_name ( )

Returns the current computer name in UTF-8.

Returns
Computer name or a placeholder upon failure.

◆ get_ifaddrs()

ifaddr_t platf::get_ifaddrs ( )

Read the local interface address list.

Returns
Owning pointer to the interface address list, or nullptr on failure.

◆ get_mac_address()

std::string platf::get_mac_address ( const std::string_view & address)

Return the hardware MAC address associated with a network address.

Parameters
addressNetwork address being parsed or filtered.
Returns
Hardware MAC address string, or an empty string when it cannot be resolved.

◆ get_permission_statuses()

std::vector< permission_status_t > platf::get_permission_statuses ( )

Query access needed by Sunshine on the current platform.

Returns
Permission status records for the Web UI.

◆ get_xdg_restore_token_path()

std::filesystem::path platf::get_xdg_restore_token_path ( )

XDG restore token path.

XDG Portal token path (unused on Windows).

XDG Portal token path (unused on MacOS).

Get path of the XDG Portal restore token.

Returns
Path of token that may include the session desktop as a suffix (e.g. .gnome, .kde).
Path of portal_token in appdata path.

◆ handle()

void * dyn::handle ( const std::vector< const char * > & libs)

Open the first available shared library from a nonempty list.

Return the native handle owned by the wrapper.

Returns
Open library handle, or null if none could be loaded.
Parameters
libsList of libraries to probe for the requested symbol.
Returns
Native dynamic-library handle, or nullptr when no library can be opened.

◆ has_elevated_privileges()

bool platf::has_elevated_privileges ( bool all_caps)

Check is the current process is running with elevated privileges (e.g. system admin/etc.).

Parameters
all_capsBool that specifies whether to check all caps or only CAP_SYS_ADMIN
Returns
True if capabilities specified to be checked are present.

◆ init()

std::unique_ptr< deinit_t > platf::init ( )
nodiscard

Initialize the platform-specific high precision timer.

Initialize the Linux high-precision timer file descriptor.

Returns
Cleanup handle for initialized platform resources, or null if none are needed.

◆ load()

int dyn::load ( library_t * handle,
const std::vector< std::tuple< apiproc *, const char * > > & funcs,
bool strict = true )

Load named functions from an open shared library.

Parameters
handleLibrary whose symbols are queried.
funcsFunction pointer destinations and corresponding symbol names.
strictWhether missing symbols make the operation fail.
Returns
Zero on success or minus one when a required symbol is missing.

◆ needs_encoder_reenumeration()

bool platf::needs_encoder_reenumeration ( )

Check if GPUs/drivers have changed since the last call to this function.

Check whether DXGI reports that adapter or driver enumeration is stale.

Report whether encoder backends should be probed again before streaming.

Returns
true if a change has occurred or if it is unknown whether a change occurred.
Always true because Linux GPU changes are not tracked by this backend.
Always true because macOS GPU changes are not tracked by this backend.

◆ open_drm_card_fd()

int platf::open_drm_card_fd ( const std::filesystem::path & path,
int flags )

Open a DRM card node, dropping implicit DRM master when possible.

Open a DRM card node and drop implicit DRM master, if any.

See misc.h for full documentation. Master check/drop failures are logged as warnings but do not fail the call.

Performs open(path, flags | O_CLOEXEC) and probes the resulting fd with DRM_IOCTL_AUTH_MAGIC. If the kernel implicitly handed us master, calls drmDropMaster and re-verifies before returning. Master check/drop failures are logged as warnings but do not fail the call: the caller still receives a usable fd.

Callers should use this helper for any /dev/dri/cardN open so we never keep implicit master and block compositors from re-acquiring it on VT switches.

Parameters
pathPath to the DRM card node (e.g. /dev/dri/card0).
flagsopen() flags. O_CLOEXEC is always OR-ed in.
Returns
A file descriptor on success, or -1 if open() itself fails.

◆ open_url()

void platf::open_url ( const std::string & url)

Open a url in the default web browser.

Parameters
urlThe url to open.

◆ process_group_running()

bool platf::process_group_running ( std::uintptr_t native_handle)

Check if a process group still has running children.

Parameters
native_handleThe native handle of the process group.
Returns
true if processes are still running.

◆ request_permission()

bool platf::request_permission ( std::string_view id)

Initiate a native request or settings action for an access item.

On macOS, Local Network opens Privacy & Security, where the user selects Local Network.

Parameters
idStable identifier of the access item.
Returns
True when the action was recognized and initiated.

◆ request_process_group_exit()

bool platf::request_process_group_exit ( std::uintptr_t native_handle)

Attempt to gracefully terminate a process group.

Parameters
native_handleThe native handle of the process group.
Returns
true if termination was successfully requested.

◆ resolve_render_device()

std::string platf::resolve_render_device ( )

Resolves the render device path to use for hardware encoding.

If config::video.adapter_name is set, returns that. Otherwise, auto-detects the GPU with a connected display via find_render_node_with_display(). Falls back to /dev/dri/renderD128 if detection fails.

Returns
Resolved render device path (may be empty on non-Linux platforms).

◆ restart_on_exit()

void platf::restart_on_exit ( )

Request a Sunshine process restart on exit.

This is registered as an atexit handler by restart(). It forks a child process with a fresh PID so that macOS WindowServer treats it as a new application (required for the system tray icon to reinitialize).

The parent process stays alive as a transparent supervisor: it forwards signals (SIGINT, SIGTERM, SIGHUP) to the child and blocks in waitpid(). This keeps the shell tracking the original PID as its foreground job, preserving Ctrl+C and terminal log output.

◆ run_command()

bp::child platf::run_command ( bool elevated,
bool interactive,
const std::string & cmd,
boost::filesystem::path & working_dir,
const bp::environment & env,
FILE * file,
std::error_code & ec,
bp::group * group )

Launch a command using the caller's Linux privileges and session.

Run a command on the users profile.

The common platform signature's elevation and interactivity flags do not apply on Linux.

Launches a child process as the user, using the current user's environment and a specific working directory.

Parameters
elevatedSpecify whether to elevate the process.
interactiveSpecify whether this will run in a window or hidden.
cmdThe command to run.
working_dirThe working directory for the new process.
envThe environment variables to use for the new process.
fileA file object to redirect the child process's output to (may be nullptr).
ecAn error code, set to indicate any errors that occur during the launch process.
groupA pointer to a bp::group object to which the new process should belong (may be nullptr).
Returns
A bp::child object representing the new process, or an empty bp::child object if the launch fails.

◆ sanitize_process_environment()

bool platf::sanitize_process_environment ( )

Remove environment variables that can load untrusted GUI modules.

Loader paths and module lists used by Qt, GTK, GIO, and GdkPixbuf are removed before any of those libraries can initialize. The caller determines whether privileged execution requires the policy.

Returns
true when the environment is safe to use; false if a variable could not be removed.

◆ send()

bool platf::send ( send_info_t & send_info)

Send the serialized response over the active socket.

Parameters
send_infoSocket addresses, buffers, and sizes for the send operation.
Returns
True when the packet is submitted to the socket.

◆ send_batch()

bool platf::send_batch ( const batched_send_info_t & send_info)

Send fixed-size UDP payload blocks without modifying the batch descriptor.

Send multiple fixed-size UDP payload blocks using the platform backend.

Parameters
send_infoSocket addresses, buffers, and sizes for the send operation.
Returns
True when all requested packet blocks are submitted to the socket.

◆ set_thread_name()

void platf::set_thread_name ( std::string_view name)

Name the current thread for use with development tools.

Note
On Linux this will be truncated after 15 characters.
Parameters
nameHuman-readable name to assign.

◆ to_sockaddr() [1/2]

SOCKADDR_IN platf::to_sockaddr ( boost::asio::ip::address_v4 address,
uint16_t port )

Convert to sockaddr.

Parameters
addressNetwork address being parsed or filtered.
portTCP or UDP port number.
Returns
Value converted to sockaddr.

◆ to_sockaddr() [2/2]

SOCKADDR_IN6 platf::to_sockaddr ( boost::asio::ip::address_v6 address,
uint16_t port )

Convert to sockaddr.

Parameters
addressNetwork address being parsed or filtered.
portTCP or UDP port number.
Returns
Value converted to sockaddr.

◆ verify_wl()

bool platf::verify_wl ( )

Check whether Wayland capture is available for the current session.

Returns
True when the active window system is Wayland and at least one output is discoverable.

◆ wl_display()

std::shared_ptr< display_t > platf::wl_display ( mem_type_e hwdevice_type,
const std::string & display_name,
const video::config_t & config )

Create a Wayland display capture backend.

Create a Wayland capture backend for the requested memory type.

Parameters
hwdevice_typeHardware device type requested for capture or encode.
display_nameDisplay name.
configConfiguration values to apply.
Returns
Display backend, or nullptr when Wayland capture initialization fails.

◆ wl_display_names()

std::vector< std::string > platf::wl_display_names ( )

Enumerate displays available through the Wayland capture backend.

Enumerate capture display names reported by the Wayland compositor.

Returns
Wayland display names, or an empty list when discovery fails.