VirtualBox

Changeset 3547 in kBuild for trunk


Ignore:
Timestamp:
Jan 29, 2022 2:39:47 AM (3 years ago)
Author:
bird
Message:

lib: Changed the console-optimization wrappers to use the get_crt_codepage() function as that's more appropriate than GetConsoleCP() for use with _cputws(). Also made them avoid the heap for smaller writes that could fit into a reasonable (2KiB) stack buffer.

Location:
trunk/src/lib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/console.h

    r3188 r3547  
    4141# include <unistd.h>
    4242#endif
     43#ifdef KBUILD_OS_WINDOWS
     44# include "get_codepage.h"
     45#endif
    4346
    4447
     
    4952extern ssize_t  maybe_con_write(int fd, void const *pvBuf, size_t cbToWrite);
    5053extern size_t   maybe_con_fwrite(void const *pvBuf, size_t cbUnit, size_t cUnits, FILE *pFile);
    51 
    5254#endif
    5355
  • trunk/src/lib/maybe_con_fwrite.c

    r3188 r3547  
    5757#ifdef KBUILD_OS_WINDOWS
    5858    /*
    59      * If it's a TTY, do our own conversion to wide char and
    60      * call WriteConsoleW directly.
     59     * If it's a TTY, do our own conversion to wide char and call _cputws.
    6160     */
    6261    if (   cbUnit > 0
    6362        && cUnits > 0
     63        && cbUnit < (unsigned)INT_MAX / 4
     64        && cUnits < (unsigned)INT_MAX / 4
    6465        && (pFile == stdout || pFile == stderr))
    6566    {
     
    7374                if (is_console_handle((intptr_t)hCon))
    7475                {
    75                     size_t   cbToWrite = cbUnit * cUnits;
    76                     size_t   cwcTmp    = cbToWrite * 2 + 16;
    77                     wchar_t *pawcTmp   = (wchar_t *)malloc(cwcTmp * sizeof(wchar_t));
    78                     if (pawcTmp)
     76                    /* Use a stack buffer if we can, falling back on the heap for larger writes: */
     77                    wchar_t  awcBuf[1024];
     78                    wchar_t *pawcBuf;
     79                    wchar_t *pawcBufFree = NULL;
     80                    size_t   cbToWrite   = cbUnit * cUnits;
     81                    size_t   cwcBuf      = cbToWrite * 2 + 16;
     82                    if (cwcBuf < sizeof(awcBuf) / sizeof(awcBuf[0]))
    7983                    {
    80                         int           cwcToWrite;
    81                         static UINT s_uConsoleCp = 0;
    82                         if (s_uConsoleCp == 0)
    83                             s_uConsoleCp = GetConsoleCP();
    84 
    85                         cwcToWrite = MultiByteToWideChar(s_uConsoleCp, 0 /*dwFlags*/, pvBuf, (int)cbToWrite,
    86                                                          pawcTmp, (int)(cwcTmp - 1));
     84                        pawcBuf = awcBuf;
     85                        cwcBuf  = sizeof(awcBuf) / sizeof(awcBuf[0]);
     86                    }
     87                    else
     88                        pawcBufFree = pawcBuf = (wchar_t *)malloc(cwcBuf * sizeof(wchar_t));
     89                    if (pawcBuf)
     90                    {
     91                        int cwcToWrite = MultiByteToWideChar(get_crt_codepage(), 0 /*dwFlags*/,
     92                                                             pvBuf, (int)cbToWrite,
     93                                                             pawcBuf, (int)(cwcBuf - 1));
    8794                        if (cwcToWrite > 0)
    8895                        {
    8996                            int rc;
    90                             pawcTmp[cwcToWrite] = '\0';
     97                            pawcBuf[cwcToWrite] = '\0';
    9198
    9299                            /* Let the CRT do the rest.  At least the Visual C++ 2010 CRT
    93100                               sources indicates _cputws will do the right thing.  */
    94101                            fflush(pFile);
    95                             rc = _cputws(pawcTmp);
    96                             free(pawcTmp);
     102                            rc = _cputws(pawcBuf);
     103                            if (pawcBufFree)
     104                                free(pawcBufFree);
    97105                            if (rc >= 0)
    98106                                return cUnits;
    99107                            return 0;
    100108                        }
    101                         free(pawcTmp);
     109                        free(pawcBufFree);
    102110                    }
    103111                }
  • trunk/src/lib/maybe_con_write.c

    r3188 r3547  
    6363     * call WriteConsoleW directly.
    6464     */
    65     if (cbToWrite > 0)
     65    if (cbToWrite > 0 && cbToWrite < INT_MAX / 2)
    6666    {
    6767        HANDLE hCon = (HANDLE)_get_osfhandle(fd);
     
    7171            if (is_console_handle((intptr_t)hCon))
    7272            {
    73                 size_t   cwcTmp  = cbToWrite * 2 + 16;
    74                 wchar_t *pawcTmp = (wchar_t *)malloc(cwcTmp * sizeof(wchar_t));
    75                 if (pawcTmp)
     73                wchar_t  awcBuf[1024];
     74                wchar_t *pawcBuf;
     75                wchar_t *pawcBufFree = NULL;
     76                size_t   cwcBuf      = cbToWrite * 2 + 16;
     77                if (cwcBuf < sizeof(awcBuf) / sizeof(awcBuf[0]))
    7678                {
    77                     int           cwcToWrite;
    78                     static UINT s_uConsoleCp = 0;
    79                     if (s_uConsoleCp == 0)
    80                         s_uConsoleCp = GetConsoleCP();
    81 
    82                     cwcToWrite = MultiByteToWideChar(s_uConsoleCp, 0 /*dwFlags*/, pvBuf, (int)cbToWrite,
    83                                                      pawcTmp, (int)(cwcTmp - 1));
     79                    pawcBuf = awcBuf;
     80                    cwcBuf  = sizeof(awcBuf) / sizeof(awcBuf[0]);
     81                }
     82                else
     83                    pawcBufFree = pawcBuf = (wchar_t *)malloc(cwcBuf * sizeof(wchar_t));
     84                if (pawcBuf)
     85                {
     86                    int cwcToWrite = MultiByteToWideChar(get_crt_codepage(), 0 /*dwFlags*/,
     87                                                         pvBuf, (int)cbToWrite,
     88                                                         pawcBuf, (int)(cwcBuf - 1));
    8489                    if (cwcToWrite > 0)
    8590                    {
     91                        int rc;
     92                        pawcBuf[cwcToWrite] = '\0';
     93
    8694                        /* Let the CRT do the rest.  At least the Visual C++ 2010 CRT
    8795                           sources indicates _cputws will do the right thing.  */
    88                         pawcTmp[cwcToWrite] = '\0';
    89                         if (_cputws(pawcTmp) >= 0)
     96                        rc = _cputws(pawcBuf);
     97                        if (pawcBufFree)
     98                            free(pawcBufFree);
     99                        if (rc >= 0)
    90100                            return cbToWrite;
    91101                        return -1;
    92102                    }
     103                    free(pawcBufFree);
    93104                }
    94105            }
  • trunk/src/lib/msc_buffered_printf.c

    r3188 r3547  
    3939#include <conio.h>
    4040#include <malloc.h>
     41#include <locale.h>
    4142#include "console.h"
    4243
     
    169170int __cdecl puts(const char *pszString)
    170171{
    171     size_t cchString = strlen(pszString);
    172     size_t cch;
    173 
    174172    /*
    175173     * If it's a TTY, we convert it to a wide char string with a newline
     
    177175     * buffering due to the added newline.
    178176     */
    179     if (*pszString != '\0')
     177    size_t cchString = strlen(pszString);
     178    size_t cch;
     179    if (cchString > 0 && cchString < INT_MAX / 2)
    180180    {
    181181        int fd = fileno(stdout);
     
    188188                    && hCon != NULL)
    189189                {
    190                     /* We need to append a newline, so we can just as well do the conversion here. */
    191                     size_t   cwcTmp  = cchString * 2 + 16 + 2;
    192                     wchar_t *pawcTmp = (wchar_t *)malloc(cwcTmp * sizeof(wchar_t));
    193                     if (pawcTmp)
     190                    wchar_t  awcBuf[1024];
     191                    wchar_t *pawcBuf;
     192                    wchar_t *pawcBufFree = NULL;
     193                    size_t   cwcBuf      = cchString * 2 + 16 + 1; /* +1 for added newline */
     194                    if (cwcBuf < sizeof(awcBuf) / sizeof(awcBuf[0]))
    194195                    {
    195                         int           cwcToWrite;
    196                         static UINT s_uConsoleCp = 0;
    197                         if (s_uConsoleCp == 0)
    198                             s_uConsoleCp = GetConsoleCP();
    199 
    200                         cwcToWrite = MultiByteToWideChar(s_uConsoleCp, 0 /*dwFlags*/, pszString, (int)cchString, pawcTmp,
    201                                                          (int)(cwcTmp - 2));
     196                        pawcBuf = awcBuf;
     197                        cwcBuf  = sizeof(awcBuf) / sizeof(awcBuf[0]);
     198                    }
     199                    else
     200                        pawcBufFree = pawcBuf = (wchar_t *)malloc(cwcBuf * sizeof(wchar_t));
     201                    if (pawcBuf)
     202                    {
     203                        int cwcToWrite = MultiByteToWideChar(get_crt_codepage(), 0 /*dwFlags*/,
     204                                                             pszString, (int)cchString,
     205                                                             pawcBuf, (int)(cwcBuf - 1));
    202206                        if (cwcToWrite > 0)
    203207                        {
    204208                            int rc;
    205 
    206                             pawcTmp[cwcToWrite++] = '\n';
    207                             pawcTmp[cwcToWrite]   = '\0';
     209                            pawcBuf[cwcToWrite++] = '\n';
     210                            pawcBuf[cwcToWrite]   = '\0';
    208211
    209212                            /* Let the CRT do the rest.  At least the Visual C++ 2010 CRT
    210                                sources indicates _cputws will do the right thing we want.  */
     213                               sources indicates _cputws will do the right thing.  */
    211214                            fflush(stdout);
    212                             rc = _cputws(pawcTmp);
    213                             free(pawcTmp);
    214                             return rc;
     215                            rc = _cputws(pawcBuf);
     216                            if (pawcBufFree)
     217                                free(pawcBufFree);
     218                            if (rc >= 0)
     219                                return 0;
     220                            return -1;
    215221                        }
    216                         free(pawcTmp);
     222                        free(pawcBufFree);
    217223                    }
    218224                }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette