From 2af455c8bda5552ccab88b5f20413fc53bee2a78 Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Fri, 25 Sep 2020 14:19:16 +0100 Subject: [PATCH] Move pv_divert_stdout_to_stderr() to libs-r-t This avoids duplicating it in the command-line tools. The test is still in tests/pressure-vessel/ for now, because it needs testutils.py, which uses its own location to find G_TEST_SRCDIR. Signed-off-by: Simon McVittie <smcv@collabora.com> --- bin/check-requirements.c | 52 +---------------------- bin/system-info.c | 52 +---------------------- pressure-vessel/adverb.c | 2 +- pressure-vessel/launch.c | 3 +- pressure-vessel/launcher.c | 3 +- pressure-vessel/meson.build | 3 ++ pressure-vessel/utils.c | 57 ------------------------- pressure-vessel/utils.h | 2 - pressure-vessel/wrap.c | 3 +- steam-runtime-tools/meson.build | 1 + steam-runtime-tools/utils-internal.h | 4 ++ steam-runtime-tools/utils.c | 57 +++++++++++++++++++++++++ tests/adverb.c | 63 +++++++--------------------- tests/meson.build | 2 +- tests/pressure-vessel/helper.c | 3 +- tests/pressure-vessel/meson.build | 1 + 16 files changed, 92 insertions(+), 216 deletions(-) diff --git a/bin/check-requirements.c b/bin/check-requirements.c index a28c25210..3f26d11bb 100644 --- a/bin/check-requirements.c +++ b/bin/check-requirements.c @@ -81,56 +81,6 @@ usage (int code) exit (code); } -static FILE * -divert_stdout_to_stderr (GError **error) -{ - int original_stdout_fd; - FILE *original_stdout; - - /* Duplicate the original stdout so that we still have a way to write - * machine-readable output. */ - original_stdout_fd = dup (STDOUT_FILENO); - - if (original_stdout_fd < 0) - { - int saved_errno = errno; - - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno), - "Unable to duplicate fd %d: %s", - STDOUT_FILENO, g_strerror (saved_errno)); - return NULL; - } - - /* If something like g_debug writes to stdout, make it come out of - * our original stderr. */ - if (dup2 (STDERR_FILENO, STDOUT_FILENO) != STDOUT_FILENO) - { - int saved_errno = errno; - - close (original_stdout_fd); - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno), - "Unable to make fd %d a copy of fd %d: %s", - STDOUT_FILENO, STDERR_FILENO, g_strerror (saved_errno)); - return NULL; - } - - /* original_stdout takes ownership of original_stdout_fd on success */ - original_stdout = fdopen (original_stdout_fd, "w"); - - if (original_stdout == NULL) - { - int saved_errno = errno; - - close (original_stdout_fd); - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno), - "Unable to create a stdio wrapper for fd %d: %s", - original_stdout_fd, g_strerror (saved_errno)); - return NULL; - } - - return original_stdout; -} - static gboolean check_x86_features (SrtX86FeatureFlags features) { @@ -180,7 +130,7 @@ main (int argc, /* stdout is reserved for machine-readable output, so avoid having * things like g_debug() pollute it. */ - original_stdout = divert_stdout_to_stderr (&error); + original_stdout = _srt_divert_stdout_to_stderr (&error); if (original_stdout == NULL) { diff --git a/bin/system-info.c b/bin/system-info.c index e4a7bce33..9034e28a1 100644 --- a/bin/system-info.c +++ b/bin/system-info.c @@ -166,56 +166,6 @@ usage (int code) exit (code); } -static FILE * -divert_stdout_to_stderr (GError **error) -{ - int original_stdout_fd; - FILE *original_stdout; - - /* Duplicate the original stdout so that we still have a way to write - * machine-readable output. */ - original_stdout_fd = dup (STDOUT_FILENO); - - if (original_stdout_fd < 0) - { - int saved_errno = errno; - - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno), - "Unable to duplicate fd %d: %s", - STDOUT_FILENO, g_strerror (saved_errno)); - return NULL; - } - - /* If something like g_debug writes to stdout, make it come out of - * our original stderr. */ - if (dup2 (STDERR_FILENO, STDOUT_FILENO) != STDOUT_FILENO) - { - int saved_errno = errno; - - close (original_stdout_fd); - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno), - "Unable to make fd %d a copy of fd %d: %s", - STDOUT_FILENO, STDERR_FILENO, g_strerror (saved_errno)); - return NULL; - } - - /* original_stdout takes ownership of original_stdout_fd on success */ - original_stdout = fdopen (original_stdout_fd, "w"); - - if (original_stdout == NULL) - { - int saved_errno = errno; - - close (original_stdout_fd); - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno), - "Unable to create a stdio wrapper for fd %d: %s", - original_stdout_fd, g_strerror (saved_errno)); - return NULL; - } - - return original_stdout; -} - static void jsonify_flags (JsonBuilder *builder, GType flags_type, @@ -895,7 +845,7 @@ main (int argc, /* stdout is reserved for machine-readable output, so avoid having * things like g_debug() pollute it. */ - original_stdout = divert_stdout_to_stderr (&error); + original_stdout = _srt_divert_stdout_to_stderr (&error); if (original_stdout == NULL) { diff --git a/pressure-vessel/adverb.c b/pressure-vessel/adverb.c index acfc40bd8..7a1e7a201 100644 --- a/pressure-vessel/adverb.c +++ b/pressure-vessel/adverb.c @@ -678,7 +678,7 @@ main (int argc, G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO, cli_log_func, (void *) g_get_prgname ()); - original_stdout = pv_divert_stdout_to_stderr (error); + original_stdout = _srt_divert_stdout_to_stderr (error); if (original_stdout == NULL) { diff --git a/pressure-vessel/launch.c b/pressure-vessel/launch.c index 7cdbe216a..0015de161 100644 --- a/pressure-vessel/launch.c +++ b/pressure-vessel/launch.c @@ -40,6 +40,7 @@ #include <gio/gunixfdlist.h> #include "steam-runtime-tools/glib-backports-internal.h" +#include "steam-runtime-tools/utils-internal.h" #include "libglnx/libglnx.h" #include "launcher.h" @@ -516,7 +517,7 @@ main (int argc, G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO, cli_log_func, (void *) g_get_prgname ()); - original_stdout = pv_divert_stdout_to_stderr (error); + original_stdout = _srt_divert_stdout_to_stderr (error); if (original_stdout == NULL) { diff --git a/pressure-vessel/launcher.c b/pressure-vessel/launcher.c index a30cdee0f..dfc3af2ba 100644 --- a/pressure-vessel/launcher.c +++ b/pressure-vessel/launcher.c @@ -41,6 +41,7 @@ #include <gio/gunixfdlist.h> #include "steam-runtime-tools/glib-backports-internal.h" +#include "steam-runtime-tools/utils-internal.h" #include "libglnx/libglnx.h" #include "flatpak-utils-base-private.h" @@ -1089,7 +1090,7 @@ main (int argc, G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO, cli_log_func, (void *) g_get_prgname ()); - original_stdout = pv_divert_stdout_to_stderr (error); + original_stdout = _srt_divert_stdout_to_stderr (error); if (original_stdout == NULL) { diff --git a/pressure-vessel/meson.build b/pressure-vessel/meson.build index ca2d1cc86..8281b56dd 100644 --- a/pressure-vessel/meson.build +++ b/pressure-vessel/meson.build @@ -157,6 +157,7 @@ executable( threads, gio_unix, libglnx_dep, + json_glib, ], include_directories : pv_include_dirs, install : true, @@ -177,6 +178,7 @@ executable( threads, gio_unix, libglnx_dep, + json_glib, ], include_directories : pv_include_dirs, install : true, @@ -207,6 +209,7 @@ executable( gio_unix, xau, libglnx_dep, + json_glib, ], include_directories : pv_include_dirs, install : true, diff --git a/pressure-vessel/utils.c b/pressure-vessel/utils.c index ad256557f..4236f3328 100644 --- a/pressure-vessel/utils.c +++ b/pressure-vessel/utils.c @@ -306,63 +306,6 @@ pv_boolean_environment (const gchar *name, return def; } -/** - * pv_divert_stdout_to_stderr: - * @error: Used to raise an error on failure - * - * Duplicate file descriptors so that functions that would write to - * `stdout` instead write to a copy of the original `stderr`. Return - * a file handle that can be used to print structured output to the - * original `stdout`. - * - * Returns: (transfer full): A libc file handle for the original `stdout`, - * or %NULL on error. Free with `fclose()`. - */ -FILE * -pv_divert_stdout_to_stderr (GError **error) -{ - g_autoptr(FILE) original_stdout = NULL; - glnx_autofd int original_stdout_fd = -1; - int flags; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* Duplicate the original stdout so that we still have a way to write - * machine-readable output. */ - original_stdout_fd = dup (STDOUT_FILENO); - - if (original_stdout_fd < 0) - return glnx_null_throw_errno_prefix (error, - "Unable to duplicate fd %d", - STDOUT_FILENO); - - flags = fcntl (original_stdout_fd, F_GETFD, 0); - - if (flags < 0) - return glnx_null_throw_errno_prefix (error, - "Unable to get flags of new fd"); - - fcntl (original_stdout_fd, F_SETFD, flags|FD_CLOEXEC); - - /* If something like g_debug writes to stdout, make it come out of - * our original stderr. */ - if (dup2 (STDERR_FILENO, STDOUT_FILENO) != STDOUT_FILENO) - return glnx_null_throw_errno_prefix (error, - "Unable to make fd %d a copy of fd %d", - STDOUT_FILENO, STDERR_FILENO); - - original_stdout = fdopen (original_stdout_fd, "w"); - - if (original_stdout == NULL) - return glnx_null_throw_errno_prefix (error, - "Unable to create a stdio wrapper for fd %d", - original_stdout_fd); - else - original_stdout_fd = -1; /* ownership taken, do not close */ - - return g_steal_pointer (&original_stdout); -} - /** * pv_async_signal_safe_error: * @message: A human-readable message diff --git a/pressure-vessel/utils.h b/pressure-vessel/utils.h index 2e8ec6744..380910472 100644 --- a/pressure-vessel/utils.h +++ b/pressure-vessel/utils.h @@ -57,8 +57,6 @@ gpointer pv_hash_table_get_arbitrary_key (GHashTable *table); gboolean pv_boolean_environment (const gchar *name, gboolean def); -FILE *pv_divert_stdout_to_stderr (GError **error); - void pv_async_signal_safe_error (const char *message, int exit_status) G_GNUC_NORETURN; diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c index 831dabca3..471560de1 100644 --- a/pressure-vessel/wrap.c +++ b/pressure-vessel/wrap.c @@ -30,6 +30,7 @@ #include <stdlib.h> #include "steam-runtime-tools/glib-backports-internal.h" +#include "steam-runtime-tools/utils-internal.h" #include "libglnx/libglnx.h" #include "bwrap.h" @@ -1277,7 +1278,7 @@ main (int argc, goto out; } - original_stdout = pv_divert_stdout_to_stderr (error); + original_stdout = _srt_divert_stdout_to_stderr (error); if (original_stdout == NULL) { diff --git a/steam-runtime-tools/meson.build b/steam-runtime-tools/meson.build index eec30738c..86e8b85cc 100644 --- a/steam-runtime-tools/meson.build +++ b/steam-runtime-tools/meson.build @@ -105,6 +105,7 @@ libsteamrt = library( gio_unix, glib, gobject, + libglnx_dep, json_glib, ], objects : [libsteamrt_static.extract_all_objects()], diff --git a/steam-runtime-tools/utils-internal.h b/steam-runtime-tools/utils-internal.h index 16bfa423f..308e60a1b 100644 --- a/steam-runtime-tools/utils-internal.h +++ b/steam-runtime-tools/utils-internal.h @@ -26,6 +26,8 @@ #pragma once +#include <stdio.h> + #include <glib.h> #include <json-glib/json-glib.h> @@ -83,3 +85,5 @@ gchar ** _srt_json_array_to_strv (JsonObject *json_obj, const gchar *array_member); gboolean _srt_rm_rf (const char *directory); + +FILE *_srt_divert_stdout_to_stderr (GError **error); diff --git a/steam-runtime-tools/utils.c b/steam-runtime-tools/utils.c index 425de4faa..cd059711b 100644 --- a/steam-runtime-tools/utils.c +++ b/steam-runtime-tools/utils.c @@ -805,3 +805,60 @@ _srt_json_array_to_strv (JsonObject *json_obj, return ret; } + +/* + * _srt_divert_stdout_to_stderr: + * @error: Used to raise an error on failure + * + * Duplicate file descriptors so that functions that would write to + * `stdout` instead write to a copy of the original `stderr`. Return + * a file handle that can be used to print structured output to the + * original `stdout`. + * + * Returns: (transfer full): A libc file handle for the original `stdout`, + * or %NULL on error. Free with `fclose()`. + */ +FILE * +_srt_divert_stdout_to_stderr (GError **error) +{ + g_autoptr(FILE) original_stdout = NULL; + glnx_autofd int original_stdout_fd = -1; + int flags; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* Duplicate the original stdout so that we still have a way to write + * machine-readable output. */ + original_stdout_fd = dup (STDOUT_FILENO); + + if (original_stdout_fd < 0) + return glnx_null_throw_errno_prefix (error, + "Unable to duplicate fd %d", + STDOUT_FILENO); + + flags = fcntl (original_stdout_fd, F_GETFD, 0); + + if (flags < 0) + return glnx_null_throw_errno_prefix (error, + "Unable to get flags of new fd"); + + fcntl (original_stdout_fd, F_SETFD, flags|FD_CLOEXEC); + + /* If something like g_debug writes to stdout, make it come out of + * our original stderr. */ + if (dup2 (STDERR_FILENO, STDOUT_FILENO) != STDOUT_FILENO) + return glnx_null_throw_errno_prefix (error, + "Unable to make fd %d a copy of fd %d", + STDOUT_FILENO, STDERR_FILENO); + + original_stdout = fdopen (original_stdout_fd, "w"); + + if (original_stdout == NULL) + return glnx_null_throw_errno_prefix (error, + "Unable to create a stdio wrapper for fd %d", + original_stdout_fd); + else + original_stdout_fd = -1; /* ownership taken, do not close */ + + return g_steal_pointer (&original_stdout); +} diff --git a/tests/adverb.c b/tests/adverb.c index 3928eda84..134c0849e 100644 --- a/tests/adverb.c +++ b/tests/adverb.c @@ -34,6 +34,7 @@ #include <gio/gio.h> #include "steam-runtime-tools/glib-backports-internal.h" +#include "steam-runtime-tools/utils-internal.h" static gboolean opt_print_version = FALSE; static gboolean opt_ignore_sigchld = FALSE; @@ -65,56 +66,20 @@ static GOptionEntry options[] = { NULL } }; -/* Return the original stdout fd. */ -static int -divert_stdout_to_stderr (GError **error) +static gboolean +put_back_original_stdout (FILE *original_stdout, + GError **error) { - int original_stdout_fd; - - /* Duplicate the original stdout so that we still have a way to write - * machine-readable output. */ - original_stdout_fd = dup (STDOUT_FILENO); + int original_stdout_fd = fileno (original_stdout); if (original_stdout_fd < 0) - { - int saved_errno = errno; - - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno), - "Unable to duplicate fd %d: %s", - STDOUT_FILENO, g_strerror (saved_errno)); - return -1; - } - - /* If something like g_debug writes to stdout, make it come out of - * our original stderr. */ - if (dup2 (STDERR_FILENO, STDOUT_FILENO) != STDOUT_FILENO) - { - int saved_errno = errno; - - close (original_stdout_fd); - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno), - "Unable to make fd %d a copy of fd %d: %s", - STDOUT_FILENO, STDERR_FILENO, g_strerror (saved_errno)); - return -1; - } + return glnx_throw_errno_prefix (error, + "Unable to get fileno of original stdout"); - return original_stdout_fd; -} - -static gboolean -put_back_original_stdout (int original_stdout_fd, - GError **error) -{ if (dup2 (original_stdout_fd, STDOUT_FILENO) != STDOUT_FILENO) - { - int saved_errno = errno; - - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno), - "Unable to make fd %d a copy of fd %d: %s", - STDOUT_FILENO, original_stdout_fd, - g_strerror (saved_errno)); - return FALSE; - } + return glnx_throw_errno_prefix (error, + "Unable to make fd %d a copy of fd %d", + STDOUT_FILENO, original_stdout_fd); return TRUE; } @@ -124,7 +89,7 @@ main (int argc, char *argv[]) { GError *local_error = NULL; - int original_stdout_fd; + FILE *original_stdout = NULL; int ret = EX_USAGE; char **command_and_args; int saved_errno; @@ -158,9 +123,9 @@ main (int argc, goto out; } - original_stdout_fd = divert_stdout_to_stderr (&local_error); + original_stdout = _srt_divert_stdout_to_stderr (&local_error); - if (original_stdout_fd < 0) + if (original_stdout == NULL) { ret = EX_OSERR; goto out; @@ -352,7 +317,7 @@ main (int argc, } } - if (!put_back_original_stdout (original_stdout_fd, &local_error)) + if (!put_back_original_stdout (original_stdout, &local_error)) goto out; if (command_and_args == NULL) diff --git a/tests/meson.build b/tests/meson.build index 6f08fa9dd..fbae1660f 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -125,7 +125,7 @@ endforeach executable( 'adverb', 'adverb.c', - dependencies : [glib, gio, gio_unix, libglnx_dep], + dependencies : [glib, gio, gio_unix, libglnx_dep, json_glib, libsteamrt_dep], include_directories : project_include_dirs, install : get_option('installed_tests'), install_dir : tests_dir, diff --git a/tests/pressure-vessel/helper.c b/tests/pressure-vessel/helper.c index 63ff8b58a..31a8de2f3 100644 --- a/tests/pressure-vessel/helper.c +++ b/tests/pressure-vessel/helper.c @@ -30,6 +30,7 @@ #include <glib/gstdio.h> #include "steam-runtime-tools/glib-backports-internal.h" +#include "steam-runtime-tools/utils-internal.h" #include "libglnx/libglnx.h" #include "utils.h" @@ -40,7 +41,7 @@ try_divert_stdout (void) g_autoptr(GError) error = NULL; g_autoptr(FILE) original_stdout = NULL; - original_stdout = pv_divert_stdout_to_stderr (&error); + original_stdout = _srt_divert_stdout_to_stderr (&error); g_assert_no_error (error); g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); diff --git a/tests/pressure-vessel/meson.build b/tests/pressure-vessel/meson.build index f60a2e77b..9fb290ce7 100644 --- a/tests/pressure-vessel/meson.build +++ b/tests/pressure-vessel/meson.build @@ -157,6 +157,7 @@ foreach helper : helpers ], dependencies : [ gio_unix, + json_glib, libglnx_dep, ], link_with : [ -- GitLab