Changeset 2756


Ignore:
Timestamp:
Jan 28, 2015, 1:39:20 PM (10 years ago)
Author:
bird
Message:

2nd attempt at the ENOSPC problem on windows.

Location:
trunk/src/kmk/kmkbuiltin
Files:
3 edited

Legend:

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

    r2466 r2756  
    221221                &&  memchr(pVar->value, '$', pVar->value_length))
    222222            {
     223                unsigned __int64 tsc_start = __rdtsc();
    223224                char *pszExpanded = allocated_variable_expand(pVar->value);
     225                tsc_ref_var += __rdtsc() - tsc_start;
    224226                fwrite(pszExpanded, 1, strlen(pszExpanded), pFile);
    225227                free(pszExpanded);
  • trunk/src/kmk/kmkbuiltin/echo.c

    r2591 r2756  
    7373{
    7474        char *errstr = strerror(errno);
     75#ifdef _MSC_VER
     76        int doserrno = _doserrno;
     77       char szDosErr[48];
     78       sprintf(szDosErr, " (doserrno=%d)", doserrno);
     79#endif
    7580        write(STDERR_FILENO, prog, strlen(prog));
    7681        write(STDERR_FILENO, ": ", 2);
     
    7883        write(STDERR_FILENO, ": ", 2);
    7984        write(STDERR_FILENO, errstr, strlen(errstr));
     85#ifdef _MSC_VER
     86        write(STDERR_FILENO, szDosErr, strlen(szDosErr));
     87#endif
    8088        write(STDERR_FILENO, "\n", 1);
    8189}
  • trunk/src/kmk/kmkbuiltin/mscfakes.c

    r2733 r2756  
    55
    66/*
    7  * Copyright (c) 2005-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
     7 * Copyright (c) 2005-2015 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
    88 *
    99 * This file is part of kBuild.
     
    2828*******************************************************************************/
    2929#include "config.h"
     30#include <assert.h>
    3031#include <stdarg.h>
    3132#include <stdio.h>
     
    4243#include <Windows.h>
    4344#undef timeval
     45
     46/*******************************************************************************
     47*   Internal Functions                                                         *
     48*******************************************************************************/
     49static BOOL isPipeFd(int fd);
    4450
    4551
     
    467473    for (i = 0; i < count; i++)
    468474    {
    469         int cb = (int)write(fd, vector[i].iov_base, (int)vector[i].iov_len);
     475        int cb = write(fd, vector[i].iov_base, (int)vector[i].iov_len);
    470476        if (cb < 0)
    471             return -1;
     477        {
     478            /* ENOSPC on pipe kludge. */
     479            char  *pbCur;
     480            size_t cbLeft;
     481            int    cbLimit;
     482            int    cSinceLastSuccess;
     483            int    iErr = errno;
     484
     485            if (errno != ENOSPC)
     486                return -1;
     487            if ((int)vector[i].iov_len == 0)
     488                continue;
     489            if (!isPipeFd(fd))
     490            {
     491                errno = ENOSPC;
     492                return -1;
     493            }
     494
     495            /* Likely a full pipe buffer, try write smaller amounts and do some
     496               sleeping inbetween each unsuccessful one. */
     497            pbCur = vector[i].iov_base;
     498            cbLeft = vector[i].iov_len;
     499            cbLimit = cbLeft / 4;
     500            if (cbLimit < 4)
     501                cbLimit = 4;
     502            else if (cbLimit > 512)
     503                cbLimit = 512;
     504            cSinceLastSuccess = 0;
     505
     506            while (cbLeft > 0)
     507            {
     508                int cbAttempt = cbLeft > cbLimit ? (int)cbLimit : (int)cbLeft;
     509                cb = write(fd, pbCur, cbAttempt);
     510                if (cb > 0)
     511                {
     512                    assert(cb <= cbAttempt);
     513                    pbCur  += cb;
     514                    cbLeft -= cb;
     515                    size   += cb;
     516                    if (cbLimit < 32)
     517                        cbLimit = 32;
     518                    cSinceLastSuccess = 0;
     519                }
     520                else if (errno != ENOSPC)
     521                    return -1;
     522                else
     523                {
     524                    /* Delay for about 30 seconds, then just give up. */
     525                    cSinceLastSuccess++;
     526                    if (cSinceLastSuccess > 1860)
     527                        return -1;
     528                    if (cSinceLastSuccess <= 2)
     529                        Sleep(0);
     530                    else if (cSinceLastSuccess <= 66)
     531                    {
     532                        if (cbLimit >= 8)
     533                            cbLimit /= 2; /* Just in case the pipe buffer is very very small. */
     534                        Sleep(1);
     535                    }
     536                    else
     537                        Sleep(16);
     538                }
     539            }
     540            cb = 0;
     541        }
    472542        size += cb;
    473543    }
     
    536606
    537607/**
     608 * Checks if the given file descriptor is a pipe or not.
     609 *
     610 * @returns TRUE if pipe, FALSE if not.
     611 * @param   fd                  The libc file descriptor number.
     612 */
     613static BOOL isPipeFd(int fd)
     614{
     615    /* Is pipe? */
     616    HANDLE hFile = (HANDLE)_get_osfhandle(fd);
     617    if (hFile != INVALID_HANDLE_VALUE)
     618    {
     619        DWORD fType = GetFileType(hFile);
     620        fType &= ~FILE_TYPE_REMOTE;
     621        if (fType == FILE_TYPE_PIPE)
     622            return TRUE;
     623    }
     624    return FALSE;
     625}
     626
     627
     628
     629/**
    538630 * This is a kludge to make pipe handles blocking.
    539631 *
     
    544636static BOOL makePipeBlocking(int fd)
    545637{
    546     /* Is pipe? */
    547     HANDLE hFile = (HANDLE)_get_osfhandle(fd);
    548     if (hFile != INVALID_HANDLE_VALUE)
    549     {
    550         DWORD fType = GetFileType(hFile);
    551         fType &= ~FILE_TYPE_REMOTE;
    552         if (fType == FILE_TYPE_PIPE)
    553         {
    554             /* Try fix it. */
    555             DWORD fState = 0;
    556             if (GetNamedPipeHandleState(hFile, &fState, NULL, NULL, NULL, NULL,  0))
    557             {
    558                 fState &= ~PIPE_NOWAIT;
    559                 fState |= PIPE_WAIT;
    560                 if (SetNamedPipeHandleState(hFile, &fState, NULL, NULL))
    561                     return TRUE;
    562             }
     638    if (isPipeFd(fd))
     639    {
     640        /* Try fix it. */
     641        HANDLE hFile = (HANDLE)_get_osfhandle(fd);
     642        DWORD fState = 0;
     643        if (GetNamedPipeHandleState(hFile, &fState, NULL, NULL, NULL, NULL,  0))
     644        {
     645            fState &= ~PIPE_NOWAIT;
     646            fState |= PIPE_WAIT;
     647            if (SetNamedPipeHandleState(hFile, &fState, NULL, NULL))
     648                return TRUE;
    563649        }
    564650    }
Note: See TracChangeset for help on using the changeset viewer.