use Bugzilla::DB;
use Bugzilla::Install::Localconfig qw(read_localconfig);
use Bugzilla::Install::Requirements qw(OPTIONAL_MODULES);
-use Bugzilla::Install::Util;
+use Bugzilla::Install::Util qw(init_console);
use Bugzilla::Template;
use Bugzilla::User;
use Bugzilla::Error;
# Note that this is a raw subroutine, not a method, so $class isn't available.
sub init_page {
- (binmode STDOUT, ':utf8') if Bugzilla->params->{'utf8'};
+ if (Bugzilla->usage_mode == USAGE_MODE_CMDLINE) {
+ init_console();
+ }
+ elsif (Bugzilla->params->{'utf8'}) {
+ binmode STDOUT, ':utf8';
+ }
if (${^TAINT}) {
# Some environment variables are not taint safe
my $wanted = $params->{version};
eval "require $module;";
+ # Don't let loading a module change the output-encoding of STDOUT
+ # or STDERR. (CGI.pm tries to set "binmode" on these file handles when
+ # it's loaded, and other modules may do the same in the future.)
+ Bugzilla::Install::Util::set_output_encoding();
# VERSION is provided by UNIVERSAL::, and can be called even if
# the module isn't loaded.
use Bugzilla::Constants;
+use Encode;
use File::Basename;
use POSIX qw(setlocale LC_CTYPE);
use Safe;
use Scalar::Util qw(tainted);
use Term::ANSIColor qw(colored);
+use PerlIO;
use base qw(Exporter);
our @EXPORT_OK = qw(
include_languages
template_include_path
vers_cmp
- get_console_locale
init_console
);
return $locale;
}
+sub set_output_encoding {
+ # If we've already set an encoding layer on STDOUT, don't
+ # add another one.
+ my @stdout_layers = PerlIO::get_layers(STDOUT);
+ return if grep(/^encoding/, @stdout_layers);
+
+ my $encoding;
+ if (ON_WINDOWS and eval { require Win32::Console }) {
+ # Although setlocale() works on Windows, it doesn't always return
+ # the current *console's* encoding. So we use OutputCP here instead,
+ # when we can.
+ $encoding = Win32::Console::OutputCP();
+ }
+ else {
+ my $locale = setlocale(LC_CTYPE);
+ if ($locale =~ /\.([^\.]+)$/) {
+ $encoding = $1;
+ }
+ }
+ $encoding = "cp$encoding" if ON_WINDOWS;
+
+ $encoding = Encode::resolve_alias($encoding) if $encoding;
+ if ($encoding and $encoding !~ /utf-8/i) {
+ binmode STDOUT, ":encoding($encoding)";
+ binmode STDERR, ":encoding($encoding)";
+ }
+ else {
+ binmode STDOUT, ':utf8';
+ binmode STDERR, ':utf8';
+ }
+}
+
sub init_console {
eval { ON_WINDOWS && require Win32::Console::ANSI; };
$ENV{'ANSI_COLORS_DISABLED'} = 1 if ($@ || !-t *STDOUT);
$SIG{__DIE__} = \&_console_die;
prevent_windows_dialog_boxes();
+ set_output_encoding();
}
sub _console_die {
# When we're running at the command line, we need to pick the right
# language before ever displaying any string.
init_console();
-# Required for displaying strings from install_string, which are always
-# in UTF-8, in every language. For other scripts, Bugzilla::init_page
-# handles this, but here we just need to assume that checksetup.pl output
-# is always UTF-8 in order for install_string to work properly in other
-# languages.
-binmode STDOUT, ':utf8';
my %switch;
GetOptions(\%switch, 'help|h|?', 'check-modules', 'no-templates|t',