Skip to content

Commit

Permalink
Set only LC_CTYPE according to env, keep the "C" locale for other loc…
Browse files Browse the repository at this point in the history
…ale categories

* Fixes #3512
  • Loading branch information
eregon committed Mar 28, 2024
1 parent cf76578 commit 36ade7c
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Bug fixes:
* Fix repeated calling of methods `Dir#{each,each_child,children}` (#3464, @andrykonchin).
* Fix `IO#{wait,wait_readable,wait_writable}` methods and switch the current thread into a sleep state (@andrykonchin).
* Fix `rb_global_variable()` for `Float` and bignum values during the `Init_` function (#3478, @eregon).
* Fix parsing literal floats when the locale does not use `.` for the decimal separator (e.g. `LANG=fr_FR.UTF-8`) (#3512, @eregon).

Compatibility:
* Move `IO#wait_readable`, `IO#wait_writable`, `IO#wait_priority` and `IO#wait` into core library (@andrykonchin).
Expand Down
6 changes: 6 additions & 0 deletions src/main/c/rubysignal/src/rubysignal.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@
* GNU Lesser General Public License version 2.1.
*/
#include "org_truffleruby_signal_LibRubySignal.h"
#include <locale.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <sys/syscall.h>

_Static_assert(sizeof(pthread_t) == sizeof(jlong), "Expected sizeof(pthread_t) == sizeof(jlong)");

JNIEXPORT void JNICALL Java_org_truffleruby_signal_LibRubySignal_setupLocale(JNIEnv *env, jclass clazz) {
setlocale(LC_ALL, "C");
setlocale(LC_CTYPE, "");
}

static void empty_handler(int sig) {
}

Expand Down
19 changes: 12 additions & 7 deletions src/main/java/org/truffleruby/core/encoding/EncodingManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.interop.InteropException;
import com.oracle.truffle.api.interop.InteropLibrary;
import org.graalvm.nativeimage.ImageInfo;
import org.graalvm.nativeimage.ProcessProperties;
import org.graalvm.shadowed.org.jcodings.Encoding;
import org.graalvm.shadowed.org.jcodings.EncodingDB;
import org.truffleruby.RubyContext;
Expand All @@ -39,6 +37,8 @@

import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import org.truffleruby.shared.Platform;
import org.truffleruby.signal.LibRubySignal;

import static org.truffleruby.core.encoding.Encodings.INITIAL_NUMBER_OF_ENCODINGS;

Expand Down Expand Up @@ -129,11 +129,16 @@ public void initializeDefaultEncodings(TruffleNFIPlatform nfi, NativeConfigurati
}

private void initializeLocaleEncoding(TruffleNFIPlatform nfi, NativeConfiguration nativeConfiguration) {
if (ImageInfo.inImageRuntimeCode()) {
// Call setlocale(LC_ALL, "") to ensure the locale is set to the environment's locale
// rather than the default "C" locale.
ProcessProperties.setLocale("LC_ALL", "");
}
// CRuby does setlocale(LC_CTYPE, "") because this is needed to get the locale encoding with nl_langinfo(CODESET).
// This means every locale category except LC_CTYPE remains the initial "C".
// LC_CTYPE is set according to environment variables (LC_ALL, LC_CTYPE, LANG).
// HotSpot does setlocale(LC_ALL, "") and Native Image does nothing.
// We match CRuby by doing setlocale(LC_ALL, "C") and setlocale(LC_CTYPE, "").
// This is notably important for Prism to be able to parse floating-point numbers:
// https://github.com/ruby/prism/issues/2638
// It also affects C functions that depend on the locale in C extensions, so best to follow CRuby here.
LibRubySignal.loadLibrary(language.getRubyHome(), Platform.LIB_SUFFIX);
LibRubySignal.setupLocale();

final String localeEncodingName;
final String detector;
Expand Down
2 changes: 2 additions & 0 deletions src/signal/java/org/truffleruby/signal/LibRubySignal.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public static void loadLibrary(String rubyHome, String libSuffix) {
System.load(path);
}

public static native void setupLocale();

public static native int setupSIGVTALRMEmptySignalHandler();

public static native long threadID();
Expand Down

0 comments on commit 36ade7c

Please sign in to comment.