python > 3.5: Issue with unix domain sockets

Mark Geisert
Thu May 6 09:24:56 GMT 2021

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 SOCK_DGRAM or SOCK_STREAM.

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?
Thank you for reviewing,


More information about the Cygwin-developers mailing list