neil / rpms / libblockdev

Forked from rpms/libblockdev a year ago
Clone

Blame 0002-Fix-setting-locale-for-util-calls.patch

Petr Šabata 9a038e
From a29d25fdfdcd7b133052eab1a3d1defe12c1733f Mon Sep 17 00:00:00 2001
Petr Šabata 9a038e
From: Vojtech Trefny <vtrefny@redhat.com>
Petr Šabata 9a038e
Date: Wed, 10 Jun 2020 17:03:28 +0200
Petr Šabata 9a038e
Subject: [PATCH] exec: Fix setting locale for util calls
Petr Šabata 9a038e
Petr Šabata 9a038e
This actually fixes two issue. The _utils_exec_and_report_progress
Petr Šabata 9a038e
function didn't set the LC_ALL=C environment variable to make sure
Petr Šabata 9a038e
we get output in English. And also we shouldn't use setenv in the
Petr Šabata 9a038e
GSpawnChildSetupFunc, it's actually example of what not to do in
Petr Šabata 9a038e
g_spawn_async documentation. This fix uses g_environ_setenv and
Petr Šabata 9a038e
passes the new environment to the g_spawn call.
Petr Šabata 9a038e
---
Petr Šabata 9a038e
 src/utils/exec.c    | 26 +++++++++++++++++---------
Petr Šabata 9a038e
 tests/utils_test.py |  7 +++++++
Petr Šabata 9a038e
 2 files changed, 24 insertions(+), 9 deletions(-)
Petr Šabata 9a038e
Petr Šabata 9a038e
diff --git a/src/utils/exec.c b/src/utils/exec.c
Petr Šabata 9a038e
index 9293930..37bd960 100644
Petr Šabata 9a038e
--- a/src/utils/exec.c
Petr Šabata 9a038e
+++ b/src/utils/exec.c
Petr Šabata 9a038e
@@ -140,11 +140,6 @@ static void log_done (guint64 task_id, gint exit_code) {
Petr Šabata 9a038e
     return;
Petr Šabata 9a038e
 }
Petr Šabata 9a038e
 
Petr Šabata 9a038e
-static void set_c_locale(gpointer user_data __attribute__((unused))) {
Petr Šabata 9a038e
-    if (setenv ("LC_ALL", "C", 1) != 0)
Petr Šabata 9a038e
-        g_warning ("Failed to set LC_ALL=C for a child process!");
Petr Šabata 9a038e
-}
Petr Šabata 9a038e
-
Petr Šabata 9a038e
 /**
Petr Šabata 9a038e
  * bd_utils_exec_and_report_error:
Petr Šabata 9a038e
  * @argv: (array zero-terminated=1): the argv array for the call
Petr Šabata 9a038e
@@ -194,6 +189,8 @@ gboolean bd_utils_exec_and_report_status_error (const gchar **argv, const BDExtr
Petr Šabata 9a038e
     const BDExtraArg **extra_p = NULL;
Petr Šabata 9a038e
     gint exit_status = 0;
Petr Šabata 9a038e
     guint i = 0;
Petr Šabata 9a038e
+    gchar **old_env = NULL;
Petr Šabata 9a038e
+    gchar **new_env = NULL;
Petr Šabata 9a038e
 
Petr Šabata 9a038e
     if (extra) {
Petr Šabata 9a038e
         args_len = g_strv_length ((gchar **) argv);
Petr Šabata 9a038e
@@ -219,16 +216,20 @@ gboolean bd_utils_exec_and_report_status_error (const gchar **argv, const BDExtr
Petr Šabata 9a038e
         args[i] = NULL;
Petr Šabata 9a038e
     }
Petr Šabata 9a038e
 
Petr Šabata 9a038e
+    old_env = g_get_environ ();
Petr Šabata 9a038e
+    new_env = g_environ_setenv (old_env, "LC_ALL", "C", TRUE);
Petr Šabata 9a038e
+
Petr Šabata 9a038e
     task_id = log_running (args ? args : argv);
Petr Šabata 9a038e
-    success = g_spawn_sync (NULL, args ? (gchar **) args : (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH,
Petr Šabata 9a038e
-                            (GSpawnChildSetupFunc) set_c_locale, NULL,
Petr Šabata 9a038e
-                            &stdout_data, &stderr_data, &exit_status, error);
Petr Šabata 9a038e
+    success = g_spawn_sync (NULL, args ? (gchar **) args : (gchar **) argv, new_env, G_SPAWN_SEARCH_PATH,
Petr Šabata 9a038e
+                            NULL, NULL, &stdout_data, &stderr_data, &exit_status, error);
Petr Šabata 9a038e
     if (!success) {
Petr Šabata 9a038e
         /* error is already populated from the call */
Petr Šabata 9a038e
+        g_strfreev (new_env);
Petr Šabata 9a038e
         g_free (stdout_data);
Petr Šabata 9a038e
         g_free (stderr_data);
Petr Šabata 9a038e
         return FALSE;
Petr Šabata 9a038e
     }
Petr Šabata 9a038e
+    g_strfreev (new_env);
Petr Šabata 9a038e
 
Petr Šabata 9a038e
     /* g_spawn_sync set the status in the same way waitpid() does, we need
Petr Šabata 9a038e
        to get the process exit code manually (this is similar to calling
Petr Šabata 9a038e
@@ -297,6 +298,8 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt
Petr Šabata 9a038e
     gboolean err_done = FALSE;
Petr Šabata 9a038e
     GString *stdout_data = g_string_new (NULL);
Petr Šabata 9a038e
     GString *stderr_data = g_string_new (NULL);
Petr Šabata 9a038e
+    gchar **old_env = NULL;
Petr Šabata 9a038e
+    gchar **new_env = NULL;
Petr Šabata 9a038e
 
Petr Šabata 9a038e
     /* TODO: share this code between functions */
Petr Šabata 9a038e
     if (extra) {
Petr Šabata 9a038e
@@ -325,7 +328,10 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt
Petr Šabata 9a038e
 
Petr Šabata 9a038e
     task_id = log_running (args ? args : argv);
Petr Šabata 9a038e
 
Petr Šabata 9a038e
-    ret = g_spawn_async_with_pipes (NULL, args ? (gchar**) args : (gchar**) argv, NULL,
Petr Šabata 9a038e
+    old_env = g_get_environ ();
Petr Šabata 9a038e
+    new_env = g_environ_setenv (old_env, "LC_ALL", "C", TRUE);
Petr Šabata 9a038e
+
Petr Šabata 9a038e
+    ret = g_spawn_async_with_pipes (NULL, args ? (gchar**) args : (gchar**) argv, new_env,
Petr Šabata 9a038e
                                     G_SPAWN_DEFAULT|G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD,
Petr Šabata 9a038e
                                     NULL, NULL, &pid, NULL, &out_fd, &err_fd, error);
Petr Šabata 9a038e
 
Petr Šabata 9a038e
@@ -333,9 +339,11 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt
Petr Šabata 9a038e
         /* error is already populated */
Petr Šabata 9a038e
         g_string_free (stdout_data, TRUE);
Petr Šabata 9a038e
         g_string_free (stderr_data, TRUE);
Petr Šabata 9a038e
+        g_strfreev (new_env);
Petr Šabata 9a038e
         g_free (args);
Petr Šabata 9a038e
         return FALSE;
Petr Šabata 9a038e
     }
Petr Šabata 9a038e
+    g_strfreev (new_env);
Petr Šabata 9a038e
 
Petr Šabata 9a038e
     args_str = g_strjoinv (" ", args ? (gchar **) args : (gchar **) argv);
Petr Šabata 9a038e
     msg = g_strdup_printf ("Started '%s'", args_str);
Petr Šabata 9a038e
diff --git a/tests/utils_test.py b/tests/utils_test.py
Petr Šabata 9a038e
index 4bec3db..2bec5ed 100644
Petr Šabata 9a038e
--- a/tests/utils_test.py
Petr Šabata 9a038e
+++ b/tests/utils_test.py
Petr Šabata 9a038e
@@ -170,6 +170,13 @@ class UtilsExecLoggingTest(UtilsTestCase):
Petr Šabata 9a038e
             # exit code != 0
Petr Šabata 9a038e
             self.assertTrue(BlockDev.utils_check_util_version("libblockdev-fake-util-fail", "1.1", "version", "Version:\\s(.*)"))
Petr Šabata 9a038e
 
Petr Šabata 9a038e
+    @tag_test(TestTags.NOSTORAGE, TestTags.CORE)
Petr Šabata 9a038e
+    def test_exec_locale(self):
Petr Šabata 9a038e
+        """Verify that setting locale for exec functions works as expected"""
Petr Šabata 9a038e
+
Petr Šabata 9a038e
+        succ, out = BlockDev.utils_exec_and_capture_output(["locale"])
Petr Šabata 9a038e
+        self.assertTrue(succ)
Petr Šabata 9a038e
+        self.assertIn("LC_ALL=C", out)
Petr Šabata 9a038e
 
Petr Šabata 9a038e
 class UtilsDevUtilsTestCase(UtilsTestCase):
Petr Šabata 9a038e
     @tag_test(TestTags.NOSTORAGE, TestTags.CORE)
Petr Šabata 9a038e
-- 
Petr Šabata 9a038e
2.26.2
Petr Šabata 9a038e