@@ -590,16 +590,65 @@ def fromshare(info):
590
590
return socket (0 , 0 , 0 , info )
591
591
__all__ .append ("fromshare" )
592
592
593
- if hasattr (_socket , "socketpair" ):
593
+ # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
594
+ # This is used if _socket doesn't natively provide socketpair. It's
595
+ # always defined so that it can be patched in for testing purposes.
596
+ def _fallback_socketpair (family = AF_INET , type = SOCK_STREAM , proto = 0 ):
597
+ if family == AF_INET :
598
+ host = _LOCALHOST
599
+ elif family == AF_INET6 :
600
+ host = _LOCALHOST_V6
601
+ else :
602
+ raise ValueError ("Only AF_INET and AF_INET6 socket address families "
603
+ "are supported" )
604
+ if type != SOCK_STREAM :
605
+ raise ValueError ("Only SOCK_STREAM socket type is supported" )
606
+ if proto != 0 :
607
+ raise ValueError ("Only protocol zero is supported" )
608
+
609
+ # We create a connected TCP socket. Note the trick with
610
+ # setblocking(False) that prevents us from having to create a thread.
611
+ lsock = socket (family , type , proto )
612
+ try :
613
+ lsock .bind ((host , 0 ))
614
+ lsock .listen ()
615
+ # On IPv6, ignore flow_info and scope_id
616
+ addr , port = lsock .getsockname ()[:2 ]
617
+ csock = socket (family , type , proto )
618
+ try :
619
+ csock .setblocking (False )
620
+ try :
621
+ csock .connect ((addr , port ))
622
+ except (BlockingIOError , InterruptedError ):
623
+ pass
624
+ csock .setblocking (True )
625
+ ssock , _ = lsock .accept ()
626
+ except :
627
+ csock .close ()
628
+ raise
629
+ finally :
630
+ lsock .close ()
594
631
595
- def socketpair (family = None , type = SOCK_STREAM , proto = 0 ):
596
- """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
632
+ # Authenticating avoids using a connection from something else
633
+ # able to connect to {host}:{port} instead of us.
634
+ # We expect only AF_INET and AF_INET6 families.
635
+ try :
636
+ if (
637
+ ssock .getsockname () != csock .getpeername ()
638
+ or csock .getsockname () != ssock .getpeername ()
639
+ ):
640
+ raise ConnectionError ("Unexpected peer connection" )
641
+ except :
642
+ # getsockname() and getpeername() can fail
643
+ # if either socket isn't connected.
644
+ ssock .close ()
645
+ csock .close ()
646
+ raise
597
647
598
- Create a pair of socket objects from the sockets returned by the platform
599
- socketpair() function.
600
- The arguments are the same as for socket() except the default family is
601
- AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
602
- """
648
+ return (ssock , csock )
649
+
650
+ if hasattr (_socket , "socketpair" ):
651
+ def socketpair (family = None , type = SOCK_STREAM , proto = 0 ):
603
652
if family is None :
604
653
try :
605
654
family = AF_UNIX
@@ -611,61 +660,7 @@ def socketpair(family=None, type=SOCK_STREAM, proto=0):
611
660
return a , b
612
661
613
662
else :
614
-
615
- # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
616
- def socketpair (family = AF_INET , type = SOCK_STREAM , proto = 0 ):
617
- if family == AF_INET :
618
- host = _LOCALHOST
619
- elif family == AF_INET6 :
620
- host = _LOCALHOST_V6
621
- else :
622
- raise ValueError ("Only AF_INET and AF_INET6 socket address families "
623
- "are supported" )
624
- if type != SOCK_STREAM :
625
- raise ValueError ("Only SOCK_STREAM socket type is supported" )
626
- if proto != 0 :
627
- raise ValueError ("Only protocol zero is supported" )
628
-
629
- # We create a connected TCP socket. Note the trick with
630
- # setblocking(False) that prevents us from having to create a thread.
631
- lsock = socket (family , type , proto )
632
- try :
633
- lsock .bind ((host , 0 ))
634
- lsock .listen ()
635
- # On IPv6, ignore flow_info and scope_id
636
- addr , port = lsock .getsockname ()[:2 ]
637
- csock = socket (family , type , proto )
638
- try :
639
- csock .setblocking (False )
640
- try :
641
- csock .connect ((addr , port ))
642
- except (BlockingIOError , InterruptedError ):
643
- pass
644
- csock .setblocking (True )
645
- ssock , _ = lsock .accept ()
646
- except :
647
- csock .close ()
648
- raise
649
- finally :
650
- lsock .close ()
651
-
652
- # Authenticating avoids using a connection from something else
653
- # able to connect to {host}:{port} instead of us.
654
- # We expect only AF_INET and AF_INET6 families.
655
- try :
656
- if (
657
- ssock .getsockname () != csock .getpeername ()
658
- or csock .getsockname () != ssock .getpeername ()
659
- ):
660
- raise ConnectionError ("Unexpected peer connection" )
661
- except :
662
- # getsockname() and getpeername() can fail
663
- # if either socket isn't connected.
664
- ssock .close ()
665
- csock .close ()
666
- raise
667
-
668
- return (ssock , csock )
663
+ socketpair = _fallback_socketpair
669
664
__all__ .append ("socketpair" )
670
665
671
666
socketpair .__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
0 commit comments