VirtualBox

Changeset 2759 in kBuild for trunk/src/kmk/kmkbuiltin/mscfakes.c


Ignore:
Timestamp:
Jan 28, 2015 4:14:00 PM (10 years ago)
Author:
bird
Message:

More generic ENOSPC workaround for windows.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kmkbuiltin/mscfakes.c

    r2756 r2759  
    467467
    468468
    469 int writev(int fd, const struct iovec *vector, int count)
    470 {
    471     int size = 0;
    472     int i;
    473     for (i = 0; i < count; i++)
    474     {
    475         int cb = write(fd, vector[i].iov_base, (int)vector[i].iov_len);
    476         if (cb < 0)
     469/* We override the libc write function (in our modules only, unfortunately) so
     470   we can kludge our way around a ENOSPC problem observed on build servers
     471   capturing STDOUT and STDERR via pipes.  Apparently this may happen when the
     472   pipe buffer is full, even with the mscfake_init hack in place.
     473
     474   XXX: Probably need to hook into fwrite as well. */
     475ssize_t msc_write(int fd, const void *pvSrc, size_t cbSrc)
     476{
     477    ssize_t cbRet;
     478    if (cbSrc < UINT_MAX / 4)
     479    {
     480#ifndef MSC_WRITE_TEST
     481        cbRet = _write(fd, pvSrc, (unsigned int)cbSrc);
     482#else
     483        cbRet = -1; errno = ENOSPC;
     484#endif
     485        if (cbRet < 0)
    477486        {
    478487            /* ENOSPC on pipe kludge. */
    479             char  *pbCur;
    480             size_t cbLeft;
    481             int    cbLimit;
    482             int    cSinceLastSuccess;
    483             int    iErr = errno;
    484 
     488            int cbLimit;
     489            int cSinceLastSuccess;
     490
     491            if (cbSrc == 0)
     492                return 0;
    485493            if (errno != ENOSPC)
    486494                return -1;
    487             if ((int)vector[i].iov_len == 0)
    488                 continue;
     495#ifndef MSC_WRITE_TEST
    489496            if (!isPipeFd(fd))
    490497            {
     
    492499                return -1;
    493500            }
     501#endif
    494502
    495503            /* Likely a full pipe buffer, try write smaller amounts and do some
    496504               sleeping inbetween each unsuccessful one. */
    497             pbCur = vector[i].iov_base;
    498             cbLeft = vector[i].iov_len;
    499             cbLimit = cbLeft / 4;
     505            cbLimit = cbSrc / 4;
    500506            if (cbLimit < 4)
    501507                cbLimit = 4;
     
    503509                cbLimit = 512;
    504510            cSinceLastSuccess = 0;
    505 
    506             while (cbLeft > 0)
     511            cbRet = 0;
     512#ifdef MSC_WRITE_TEST
     513            cbLimit = 4;
     514#endif
     515
     516            while (cbSrc > 0)
    507517            {
    508                 int cbAttempt = cbLeft > cbLimit ? (int)cbLimit : (int)cbLeft;
    509                 cb = write(fd, pbCur, cbAttempt);
    510                 if (cb > 0)
     518                unsigned int cbAttempt = cbSrc > cbLimit ? (int)cbLimit : (int)cbSrc;
     519                ssize_t cbActual = _write(fd, pvSrc, cbAttempt);
     520                if (cbActual > 0)
    511521                {
    512                     assert(cb <= cbAttempt);
    513                     pbCur  += cb;
    514                     cbLeft -= cb;
    515                     size   += cb;
     522                    assert(cbActual <= (ssize_t)cbAttempt);
     523                    pvSrc  = (char *)pvSrc + cbActual;
     524                    cbSrc -= cbActual;
     525                    cbRet += cbActual;
     526#ifndef MSC_WRITE_TEST
    516527                    if (cbLimit < 32)
    517528                        cbLimit = 32;
     529#endif
    518530                    cSinceLastSuccess = 0;
    519531                }
     
    538550                }
    539551            }
    540             cb = 0;
    541         }
     552        }
     553    }
     554    else
     555    {
     556        /*
     557         * Type limit exceeded. Split the job up.
     558         */
     559        cbRet = 0;
     560        while (cbSrc > 0)
     561        {
     562            size_t  cbToWrite = cbSrc > UINT_MAX / 4 ? UINT_MAX / 4 : cbSrc;
     563            ssize_t cbWritten = msc_write(fd, pvSrc, cbToWrite);
     564            if (cbWritten > 0)
     565            {
     566                pvSrc  = (char *)pvSrc + (size_t)cbWritten;
     567                cbSrc -= (size_t)cbWritten;
     568                cbRet += (size_t)cbWritten;
     569            }
     570            else if (cbWritten == 0 || cbRet > 0)
     571                break;
     572            else
     573                return -1;
     574        }
     575    }
     576    return cbRet;
     577}
     578
     579ssize_t writev(int fd, const struct iovec *vector, int count)
     580{
     581    int size = 0;
     582    int i;
     583    for (i = 0; i < count; i++)
     584    {
     585        int cb = msc_write(fd, vector[i].iov_base, (int)vector[i].iov_len);
     586        if (cb < 0)
     587            return cb;
    542588        size += cb;
    543589    }
     
    626672
    627673
    628 
    629674/**
    630675 * This is a kludge to make pipe handles blocking.
Note: See TracChangeset for help on using the changeset viewer.

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