File: socketpair_helper.py

package info (click to toggle)
python-urllib3 1.26.12-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 2,652 kB
  • sloc: python: 17,628; makefile: 130; sh: 18
file content (63 lines) | stat: -rw-r--r-- 2,422 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import socket

# Figuring out what errors could come out of a socket. There are three
# different situations. Python 3 post-PEP3151 will define and use
# BlockingIOError and InterruptedError from sockets. For Python pre-PEP3151
# both OSError and socket.error can be raised except on Windows where
# WindowsError can also be raised. We want to catch all of these possible
# exceptions so we catch WindowsError if it's defined.
try:
    _CONNECT_ERROR = (BlockingIOError, InterruptedError)
except NameError:
    try:
        _CONNECT_ERROR = (WindowsError, OSError, socket.error)  # noqa: F821
    except NameError:
        _CONNECT_ERROR = (OSError, socket.error)

if hasattr(socket, "socketpair"):
    # Since Python 3.5, socket.socketpair() is now also available on Windows
    socketpair = socket.socketpair
else:
    # Replacement for socket.socketpair()
    def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
        """A socket pair usable as a self-pipe, for Windows.

        Origin: https://gist.github.com/4325783, by Geert Jansen.
        Public domain.
        """
        if family == socket.AF_INET:
            host = "127.0.0.1"
        elif family == socket.AF_INET6:
            host = "::1"
        else:
            raise ValueError(
                "Only AF_INET and AF_INET6 socket address families are supported"
            )
        if type != socket.SOCK_STREAM:
            raise ValueError("Only SOCK_STREAM socket type is supported")
        if proto != 0:
            raise ValueError("Only protocol zero is supported")

        # We create a connected TCP socket. Note the trick with setblocking(0)
        # that prevents us from having to create a thread.
        lsock = socket.socket(family, type, proto)
        try:
            lsock.bind((host, 0))
            lsock.listen(1)
            # On IPv6, ignore flow_info and scope_id
            addr, port = lsock.getsockname()[:2]
            csock = socket.socket(family, type, proto)
            try:
                csock.setblocking(False)
                try:
                    csock.connect((addr, port))
                except _CONNECT_ERROR:
                    pass
                csock.setblocking(True)
                ssock, _ = lsock.accept()
            except Exception:
                csock.close()
                raise
        finally:
            lsock.close()
        return (ssock, csock)