On Jan 14, 2019, at 7:23 AM, Peter Westlake <peter.westlake@pobox.com> wrote:

An SSCCE:

from twisted.internet import error
from twisted.python import failure
from twisted.conch.ssh.session import SSHSessionProcessProtocol
from mock import MagicMock

err = error.ProcessTerminated(-1)
fail = failure.Failure(err)
session = MagicMock()
proto = SSHSessionProcessProtocol(session)
proto.processEnded(fail)


That fails with:

Traceback (most recent call last):
  File ".../negexit.py", line 10, in <module>
    proto.processEnded(fail)
  File "/usr/lib64/python2.7/site-packages/twisted/conch/ssh/session.py", line 279, in processEnded
    struct.pack('>L', err.exitCode))
struct.error: integer out of range for 'L' format code

I'm running an SSH server on Windows, where negative exit codes can happen.

Passing negative numbers to a ">L" format was allowed in Python before 2.6, where the number was treated as an unsigned int of the same bit pattern. It was deprecated in 2.6, and became an error in 2.7. It's only just become a problem for me because I'm updating a 10 year old SSH server that has been running under 2.4 all this time.

Presumably the fix is to bit-mask the exitCode? I was able to work around the error by doing that in a copy of _dumbwin32proc.py which was copied into the project (historical reasons, don't ask) but it would be nice to have a proper upstream fix. Not least because I want to purge the copied-in file, as you can imagine.

This is a great bug!  Thanks for raising it.  Sounds like the fix is to simply reinterpret it as unsigned.  https://en.wikipedia.org/wiki/Exit_status#Windows:

Windows uses 32-bit unsigned integers as exit codes,[11] although the command interpreter treats them as signed.[12] If a process fails initialization, a Windows system error code may be returned.[13][14]

Please do submit this fix upstream (file a ticket on Trac, open a PR, etc), it seems like one of the easier ones to integrate :-).

-g