]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
localedata: Avoid concurrently written locales in gen-locale.sh
authorFlorian Weimer <fweimer@redhat.com>
Wed, 8 Jul 2026 15:38:42 +0000 (17:38 +0200)
committerFlorian Weimer <fweimer@redhat.com>
Thu, 9 Jul 2026 08:34:10 +0000 (10:34 +0200)
There is no cross-directory exclusion of concurrent $(gen-locales)
usage.  Parallel localedef calls can clobber locale data as it is
being loaded by tests.

With the separate staging areas, there are no peer directories,
so hard-linking no longer happens.  The touch command is therefore
unnecessary.

Reviewed-by: Sam James <sam@gentoo.org>
localedata/gen-locale.sh

index 4762c04284e41942e3395b2fc0e149cda76967fe..c449efe1258c4bc5034e16bbedd172b89d2e6226 100644 (file)
@@ -32,17 +32,25 @@ generate_locale ()
   out=$3
   flags=$4
   ret=0
+
+  # Use a staging area to avoid writing to locales concurrently.
+  # While this process is running, $$ is sufficiently unique.
+  stage="${common_objpfx}localedata/gen-locale.$$.tmp"
+  mkdir "$stage" 2>/dev/null || true
+
   ${localedef_before_env} ${run_program_env} I18NPATH=../localedata \
        ${localedef_after_env} $flags -f $charmap -i $input \
-       ${common_objpfx}localedata/$out || ret=$?
-  if [ $ret -eq 0 ]; then
-    # The makefile checks the timestamp of the LC_CTYPE file,
-    # but localedef won't have touched it if it was able to
-    # hard-link it to an existing file.
-    touch ${common_objpfx}localedata/$out/LC_CTYPE
+       $stage/$out || ret=$?
+  if [ $ret -eq 0 ] ; then
+      # Ignore errors in case some other process has created the same locale.
+      # This rename operation should be atomic, and it should fail if the
+      # $out locale already exists (rename fails with ENOTEMPTY).
+      mv $stage/$out ${common_objpfx}localedata/. 2>/dev/null || true
+      rm -rf $stage
   else
+    rm -rf $stage
     echo "Charmap: \"${charmap}\" Inputfile: \"${input}\"" \
-        "Outputdir: \"${out}\" failed"
+        "Outputdir: \"${out}\" failed (exit status $ret)"
     exit 1
   fi
 }