aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Halachmi (:avih) <avihpit@yahoo.com>2023-08-03 19:19:47 +0300
committerAvi Halachmi (:avih) <avihpit@yahoo.com>2023-08-03 21:09:01 +0300
commitb8fff6b345d4b7e3f16227f65eecca1a0c88ab41 (patch)
treedd8ea10581be75ddee328aeb6aff88f02e9542f6
parentbf70275f786716546ec474caade0f16ec28da541 (diff)
downloadbusybox-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.c35
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.
1539static 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
1555static int conv_fwriteCon(FILE *stream, char *buf, size_t siz) 1574static 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
1568static int conv_writeCon(int fd, char *buf, size_t siz) 1589static 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}