Skip to content
Snippets Groups Projects
Commit 9a764d18 authored by Ludovico de Nittis's avatar Ludovico de Nittis
Browse files

steam-remote: Add a stub steam executable

This stub steam executable tries to directly pass the given commands,
e.g. "steam://nav/downloads

", to the running Steam client, if any.

This helps games that tries to run "steam ${command}" because when we
are in a LD_LIBRARY_PATH runtime, "steam" might not be pointing to the
same version that is currently running. Or if we are in a container,
there is no "steam" executable in the PATH at all.

Signed-off-by: default avatarLudovico de Nittis <ludovico.denittis@collabora.com>
parent e61ecceb
No related branches found
No related tags found
1 merge request!280steam-remote: Add a stub steam executable
Pipeline #10913 passed
......@@ -51,10 +51,21 @@ executable(
install_rpath : bin_rpath,
)
executable(
'steam-runtime-steam-remote',
'steam-remote.c',
dependencies : [glib, gio_unix, libglnx_dep, libsteamrt_static_dep],
install : true,
# Use GLib from the adjacent libdir, ignoring LD_LIBRARY_PATH
build_rpath : bin_rpath,
install_rpath : bin_rpath,
)
if get_option('man')
foreach bin_name : [
'check-requirements',
'input-monitor',
'steam-remote',
'system-info',
]
custom_target(
......
/*
* Copyright © 2021 Collabora Ltd.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Stub Steam executable that tries to directly pass the given commands to
* the running Steam client.
*/
#include <libglnx.h>
#include <glib.h>
#include <glib-object.h>
#include <steam-runtime-tools/utils-internal.h>
int
main (int argc,
const char **argv)
{
static const char *default_argv[] = {"steam", "-foreground", NULL};
g_autoptr(GError) error = NULL;
if (argc <= 1)
{
/* If we don't have arguments, Steam is expected to send the command
* "-foreground" by default */
argv = default_argv;
argc = 2;
}
if (!_srt_steam_command_via_pipe (argv + 1, argc - 1, &error))
{
g_printerr ("steam-runtime-steam-remote: %s\n", error->message);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
---
title: steam-runtime-steam-remote
section: 1
...
# NAME
steam-runtime-steam-remote - stub Steam executable
# SYNOPSIS
**steam-runtime-steam-remote** [*ARGUMENT*]...
# DESCRIPTION
**steam-runtime-steam-remote** passes its command-line arguments
to the Steam client that is currently running, if any.
The command-line arguments will typically be a single
[steam: URL](https://developer.valvesoftware.com/wiki/Steam_browser_protocol)
such as `steam://advertise/70`, but can include other
[Steam command-line options](https://developer.valvesoftware.com/wiki/Command_Line_Options#Steam_.28Windows.29)
such as `-foreground`.
A typical use for **steam-runtime-steam-remote** is to add a symbolic
link named **steam** to a directory in the **PATH**, so that when a
game runs a command like `steam -foreground`, it will be converted into
an inter-process communication to the Steam client that is already running.
# OUTPUT
If the commands are correctly passed, the output will be empty.
On error, a human-readable message is shown on standard error.
# EXIT STATUS
0
: **steam-runtime-steam-remote** ran successfully
Other Nonzero
: An error occurred.
# EXAMPLES
Bring Steam's graphical user interface to the foreground:
steam-runtime-steam-remote -foreground
Attempt to install Half-Life:
steam-runtime-steam-remote steam://install/70
<!-- vim:set sw=4 sts=4 et: -->
usr/bin/steam-runtime-check-requirements
usr/bin/steam-runtime-input-monitor
usr/bin/steam-runtime-steam-remote
usr/bin/steam-runtime-system-info
usr/share/man/man1/steam-runtime-*
......@@ -109,6 +109,10 @@ G_GNUC_INTERNAL gboolean _srt_str_is_integer (const char *str);
gboolean _srt_fstatat_is_same_file (int afd, const char *a,
int bfd, const char *b);
G_GNUC_INTERNAL gboolean _srt_steam_command_via_pipe (const char * const *arguments,
gssize n_arguments,
GError **error);
/*
* _srt_is_same_stat:
* @a: a stat buffer
......
......@@ -1022,3 +1022,78 @@ _srt_fstatat_is_same_file (int afd,
&& fstatat (bfd, b, &b_buffer, AT_EMPTY_PATH) == 0
&& _srt_is_same_stat (&a_buffer, &b_buffer));
}
/*
* _srt_steam_command_via_pipe:
* @arguments: (not nullable) (element-type utf8) (transfer none): An array
* of command-line arguments that need to be passed to the Steam pipe
* @n_arguments: Number of elements of @arguments to use, or negative if
* @arguments is %NULL-terminated
* @error: Used to raise an error on failure
*
* If @n_arguments is positive it's the caller's responsibility to ensure that
* @arguments has at least @n_arguments elements.
* If @n_arguments is negative, @arguments must be %NULL-terminated.
*
* Returns: %TRUE if the provided @arguments were successfully passed to the
* running Steam client instance
*/
gboolean
_srt_steam_command_via_pipe (const char * const *arguments,
gssize n_arguments,
GError **error)
{
glnx_autofd int fd = -1;
int ofd_flags;
g_autofree gchar *steampipe = NULL;
g_autoptr(GString) args_string = g_string_new ("");
gsize length;
gsize i;
g_return_val_if_fail (arguments != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (n_arguments >= 0)
length = n_arguments;
else
length = g_strv_length ((gchar **) arguments);
steampipe = g_build_filename (g_get_home_dir (), ".steam", "steam.pipe", NULL);
fd = open (steampipe, O_WRONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY);
if (fd < 0 && (errno == ENOENT || errno == ENXIO))
return glnx_throw_errno_prefix (error, "Steam is not running");
else if (fd < 0)
return glnx_throw_errno_prefix (error, "An error occurred trying to open the Steam pipe");
ofd_flags = fcntl (fd, F_GETFL, 0);
/* Remove O_NONBLOCK to block if we write more than the pipe-buffer space */
if (fcntl (fd, F_SETFL, ofd_flags & ~O_NONBLOCK) != 0)
return glnx_throw_errno_prefix (error, "Unable to set flags on the steam pipe fd");
/* We hardcode the canonical steam installation path, instead of actually
* searching where Steam has been installed, because apparently this
* information is not used for anything in particular and Steam just
* discards it */
g_string_append (args_string, "'~/.steam/root/ubuntu12_32/steam'");
for (i = 0; i < length; i++)
{
g_autofree gchar *quoted = NULL;
quoted = g_shell_quote (arguments[i]);
g_string_append (args_string, " ");
g_string_append (args_string, quoted);
}
g_string_append (args_string, "\n");
if (glnx_loop_write (fd, args_string->str, args_string->len) < 0)
return glnx_throw_errno_prefix (error,
"An error occurred trying to write to the Steam pipe");
return TRUE;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment