diff options
author | Avi Halachmi (:avih) <avihpit@yahoo.com> | 2023-08-03 19:19:47 +0300 |
---|---|---|
committer | Avi Halachmi (:avih) <avihpit@yahoo.com> | 2023-08-03 21:09:01 +0300 |
commit | b8fff6b345d4b7e3f16227f65eecca1a0c88ab41 (patch) | |
tree | dd8ea10581be75ddee328aeb6aff88f02e9542f6 | |
parent | bf70275f786716546ec474caade0f16ec28da541 (diff) | |
download | busybox-w32-b8fff6b345d4b7e3f16227f65eecca1a0c88ab41.tar.gz busybox-w32-b8fff6b345d4b7e3f16227f65eecca1a0c88ab41.tar.bz2 busybox-w32-b8fff6b345d4b7e3f16227f65eecca1a0c88ab41.zip |
win32: disable console output conversion with LC_ALL=C
Previously, when writing to the console, the non-unicode build always
assumed the source data is in the ANSI codepage, and used charToCon
to convert it unconditionally to the console CP.
Similarly, the unicode build made the same assumption (where ANSI CP
is UTF8), and always tried to convert it so that it's printed
correctly (at least when FEATURE_UTF8_OUTPUT is enabled - which it is
by default at the unicode build).
However, there could be cases where this assumption is incorrect, for
instance if the data comes from a file encoded for some codepage X,
and after the user also changed the console CP to X does 'cat file.X'
This commit allows disabling this conversion, using the same env vars
which can be used to disable the locale/unicode elsewhere, (LANG,
LC_CTYPE, LC_ALL as "C") e.g. 'LC_ALL=C cat file.X' now doesn't
convert, and the console renders it according to its own codepage.
-rw-r--r-- | win32/winansi.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/win32/winansi.c b/win32/winansi.c index aaaa2fa50..c88c096d2 100644 --- a/win32/winansi.c +++ b/win32/winansi.c | |||
@@ -1534,6 +1534,25 @@ void console_write(const char *str, int len) | |||
1534 | free(buf); | 1534 | free(buf); |
1535 | } | 1535 | } |
1536 | 1536 | ||
1537 | // LC_ALL=C disables console output conversion, so that the source | ||
1538 | // data is interpreted only by the console according to its output CP. | ||
1539 | static int conout_conv_enabled(void) | ||
1540 | { | ||
1541 | static int enabled, tested; /* = 0 */ | ||
1542 | |||
1543 | if (!tested) { | ||
1544 | // keep in sync with [re]init_unicode at libbb/unicode.c | ||
1545 | char *s = getenv("LC_ALL"); | ||
1546 | if (!s) s = getenv("LC_CTYPE"); | ||
1547 | if (!s) s = getenv("LANG"); | ||
1548 | |||
1549 | enabled = !(s && s[0] == 'C' && s[1] == 0); | ||
1550 | tested = 1; | ||
1551 | } | ||
1552 | |||
1553 | return enabled; | ||
1554 | } | ||
1555 | |||
1537 | // TODO: improvements: | 1556 | // TODO: improvements: |
1538 | // | 1557 | // |
1539 | // 1. currently conv_[f]writeCon modify buf inplace, which means the caller | 1558 | // 1. currently conv_[f]writeCon modify buf inplace, which means the caller |
@@ -1554,12 +1573,14 @@ void console_write(const char *str, int len) | |||
1554 | // returns EOF on error, 0 on success | 1573 | // returns EOF on error, 0 on success |
1555 | static int conv_fwriteCon(FILE *stream, char *buf, size_t siz) | 1574 | static int conv_fwriteCon(FILE *stream, char *buf, size_t siz) |
1556 | { | 1575 | { |
1576 | if (conout_conv_enabled()) { | ||
1557 | #if ENABLE_FEATURE_UTF8_OUTPUT | 1577 | #if ENABLE_FEATURE_UTF8_OUTPUT |
1558 | if (GetConsoleOutputCP() != CP_UTF8) | 1578 | if (GetConsoleOutputCP() != CP_UTF8) |
1559 | return writeCon_utf8(fileno(stream), buf, siz) ? EOF : 0; | 1579 | return writeCon_utf8(fileno(stream), buf, siz) ? EOF : 0; |
1560 | #else | 1580 | #else |
1561 | charToConBuffA(buf, siz); | 1581 | charToConBuffA(buf, siz); |
1562 | #endif | 1582 | #endif |
1583 | } | ||
1563 | return fwrite(buf, 1, siz, stream) < siz ? EOF : 0; | 1584 | return fwrite(buf, 1, siz, stream) < siz ? EOF : 0; |
1564 | } | 1585 | } |
1565 | 1586 | ||
@@ -1567,11 +1588,13 @@ static int conv_fwriteCon(FILE *stream, char *buf, size_t siz) | |||
1567 | // returns -1 on error, actually-written bytes on suceess | 1588 | // returns -1 on error, actually-written bytes on suceess |
1568 | static int conv_writeCon(int fd, char *buf, size_t siz) | 1589 | static int conv_writeCon(int fd, char *buf, size_t siz) |
1569 | { | 1590 | { |
1591 | if (conout_conv_enabled()) { | ||
1570 | #if ENABLE_FEATURE_UTF8_OUTPUT | 1592 | #if ENABLE_FEATURE_UTF8_OUTPUT |
1571 | if (GetConsoleOutputCP() != CP_UTF8) | 1593 | if (GetConsoleOutputCP() != CP_UTF8) |
1572 | return writeCon_utf8(fd, buf, siz) ? -1 : siz; | 1594 | return writeCon_utf8(fd, buf, siz) ? -1 : siz; |
1573 | #else | 1595 | #else |
1574 | charToConBuffA(buf, siz); | 1596 | charToConBuffA(buf, siz); |
1575 | #endif | 1597 | #endif |
1598 | } | ||
1576 | return write(fd, buf, siz); | 1599 | return write(fd, buf, siz); |
1577 | } | 1600 | } |