diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b8ab0d57..1eb12bdd5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,11 +91,13 @@ jobs: # On Windows, a non-blocking pipe might respond (when emulating Unix-y # API) with ENOSPC to indicate buffer full. Trial doesn't handle this - # well. So, we pipe the output through cat to make buffer handling someone - # else's problem. + # well. So, we pipe the output through pipethrough that will hopefully be + # able to do the right thing by using Windows APIs. - name: Run tox for corresponding Python version if: ${{ contains(matrix.os, 'windows') }} - run: python -m tox | cat + run: | + pip install twisted + python -m tox | python misc/windows-enospc/passthrough.py - name: Upload eliot.log uses: actions/upload-artifact@v3 diff --git a/misc/windows-enospc/passthrough.py b/misc/windows-enospc/passthrough.py new file mode 100644 index 000000000..6be3d7dbe --- /dev/null +++ b/misc/windows-enospc/passthrough.py @@ -0,0 +1,38 @@ +""" +Writing to non-blocking pipe can result in ENOSPC when using Unix APIs on +Windows. So, this program passes through data from stdin to stdout, using +Windows APIs instead of Unix-y APIs. +""" + +import sys + +from twisted.internet.stdio import StandardIO +from twisted.internet import reactor +from twisted.internet.protocol import Protocol +from twisted.internet.interfaces import IHalfCloseableProtocol +from twisted.internet.error import ReactorNotRunning +from zope.interface import implementer + +@implementer(IHalfCloseableProtocol) +class Passthrough(Protocol): + def readConnectionLost(self): + self.transport.loseConnection() + + def writeConnectionLost(self): + try: + reactor.stop() + except ReactorNotRunning: + pass + + def dataReceived(self, data): + self.transport.write(data) + + def connectionLost(self, reason): + try: + reactor.stop() + except ReactorNotRunning: + pass + + +std = StandardIO(Passthrough()) +reactor.run()