python > 3.5: Issue with unix domain sockets

Marco Atzeri
Thu May 6 12:18:17 GMT 2021

On 06.05.2021 12:30, Corinna Vinschen wrote:
> On May  6 02:24, Mark Geisert wrote:
>> Corinna Vinschen wrote:
>>> On May  4 22:04, Mark Geisert wrote:
>>>> Corinna Vinschen wrote:
>>>>> On May  4 02:45, Mark Geisert wrote:
>>>>>> [blah blah...]
>>>>> You're supposed to call the special setsockopt(SO_PEERCRED) on the
>>>>> accepting socket.  The no_getpeereid property is inherited by the
>>>>> accepted socket.
>>>> Ah, of course.  Well, I couldn't figure out a way to do the setsockopt()
>>>> call some times but not others, because Python can't reach into the Cygwin
>>>> DLL.  Nor should it.
>>>> Since this Python patch is supposed to be a temporary workaround, I took the
>>>> tack that it should just ignore an error return from
>>>> setsockopt(SO_PEERCRED).  In this fashion the handshake will be turned off
>>>> when it can be, and when it can't (on the accepted socket) the attempt will
>>>> error but that error will be ignored.
>>> Sorry Mark, but I don't understand how you concluded that ignoring the
>>> error from setsockopt(SO_PEERCRED) is the solution I pointed out above.
>>> The right thing to do is to call setsockopt(SO_PEERCRED) (and check its
>>> return value) before calling listen() on the accepting socket.  The
>>> no_getpeereid property gets propagated to the accepted sockets and thus
>>> there's no need to call it again for these sockets.
>> The strategy requires more precise language than I used, sorry.  I do
>> understand what you're saying most recently, and have since my "of course"
>> statement.
>> Inside the Python runtime environment, I only get visibility to the socket
>> Cygwin has provided at one point, which is where Python inits its own
>> context for that socket.  I can't tell whether the socket is the result of a
>> socket() call or from an accept() call.  I can't even tell whether it's
>> connected.  I can tell that it's AF_UNIX and can tell whether it's
> Ah, ok.  Sounds like a shitty interface to me, but if that's what you
> have to work with...
>> So in this constrained situation, I decided to just call
>> setsockopt(SO_PEERCRED) and ignore any errors.  (Case 1:) If it doesn't
>> error, the socket came from socket() and now has the peer handshake turned
>> off.  (Case 2:) If it does error, the socket came from accept(), i.e. it's
>> an accepted socket, and though we couldn't turn off handshake here, it's
>> already turned off due to inheritance from the accepting socket.  The
>> accepting socket has it turned off already because it was earlier Case 1
>> (i.e. both ends of the connection get treated, as long as they are both
>> Python apps).
>> I know that in general it's poor practice to ignore errors but given the
>> constraints here and that the possible cases are (I believe) well known,
>> this is a solution that works to solve the most recent issue and the
>> original issue.  Now that I think about it, the patch could be tightened up
>> by only ignoring EALREADY rather than ignoring all errors.  Would you be
>> okay with that?
> Sounds good to me.
> Thanks for explaining the situation!
> Corinna

as general info with the current implementation
all the tests on


pass except one.
It is a huge improvement versus previous python packages

   $ mv
   $ pytest

   Results (102.08s):
       1939 passed
         31 skipped is still frozing

(most recent call last):
   File "", line 725, in <module>
   File "/usr/lib/python3.8/unittest/", line 101, in __init__
   File "/usr/lib/python3.8/unittest/", line 271, in runTests
     self.result =
   File "/usr/lib/python3.8/unittest/", line 176, in run
   File "/usr/lib/python3.8/unittest/", line 84, in __call__
     return*args, **kwds)
   File "/usr/lib/python3.8/unittest/", line 122, in run
   File "/usr/lib/python3.8/unittest/", line 84, in __call__
     return*args, **kwds)
   File "/usr/lib/python3.8/unittest/", line 122, in run
   File "/usr/lib/python3.8/unittest/", line 736, in __call__
     return*args, **kwds)
   File "/usr/lib/python3.8/unittest/", line 676, in run
   File "/usr/lib/python3.8/unittest/", line 633, in _callTestMethod
   File "", line 175, in test_kill
     returncode = self.loop.run_until_complete(proc.wait())
   File "/usr/lib/python3.8/asyncio/", line 603, in 
   File "/usr/lib/python3.8/asyncio/", line 570, in 
   File "/usr/lib/python3.8/asyncio/", line 1823, in _run_once
     event_list =
   File "/usr/lib/python3.8/", line 415, in select
     fd_event_list = self._selector.poll(timeout)


More information about the Cygwin-developers mailing list