mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			959 lines
		
	
	
	
		
			36 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			959 lines
		
	
	
	
		
			36 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
# Wrapper module for _socket, providing some additional facilities
 | 
						|
# implemented in Python.
 | 
						|
 | 
						|
"""\
 | 
						|
This module provides socket operations and some related functions.
 | 
						|
On Unix, it supports IP (Internet Protocol) and Unix domain sockets.
 | 
						|
On other systems, it only supports IP. Functions specific for a
 | 
						|
socket are available as methods of the socket object.
 | 
						|
 | 
						|
Functions:
 | 
						|
 | 
						|
socket() -- create a new socket object
 | 
						|
socketpair() -- create a pair of new socket objects [*]
 | 
						|
fromfd() -- create a socket object from an open file descriptor [*]
 | 
						|
send_fds() -- Send file descriptor to the socket.
 | 
						|
recv_fds() -- Receive file descriptors from the socket.
 | 
						|
fromshare() -- create a socket object from data received from socket.share() [*]
 | 
						|
gethostname() -- return the current hostname
 | 
						|
gethostbyname() -- map a hostname to its IP number
 | 
						|
gethostbyaddr() -- map an IP number or hostname to DNS info
 | 
						|
getservbyname() -- map a service name and a protocol name to a port number
 | 
						|
getprotobyname() -- map a protocol name (e.g. 'tcp') to a number
 | 
						|
ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
 | 
						|
htons(), htonl() -- convert 16, 32 bit int from host to network byte order
 | 
						|
inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
 | 
						|
inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
 | 
						|
socket.getdefaulttimeout() -- get the default timeout value
 | 
						|
socket.setdefaulttimeout() -- set the default timeout value
 | 
						|
create_connection() -- connects to an address, with an optional timeout and
 | 
						|
                       optional source address.
 | 
						|
 | 
						|
 [*] not available on all platforms!
 | 
						|
 | 
						|
Special objects:
 | 
						|
 | 
						|
SocketType -- type object for socket objects
 | 
						|
error -- exception raised for I/O errors
 | 
						|
has_ipv6 -- boolean value indicating if IPv6 is supported
 | 
						|
 | 
						|
IntEnum constants:
 | 
						|
 | 
						|
AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
 | 
						|
SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
 | 
						|
 | 
						|
Integer constants:
 | 
						|
 | 
						|
Many other constants may be defined; these may be used in calls to
 | 
						|
the setsockopt() and getsockopt() methods.
 | 
						|
"""
 | 
						|
 | 
						|
import _socket
 | 
						|
from _socket import *
 | 
						|
 | 
						|
import os, sys, io, selectors
 | 
						|
from enum import IntEnum, IntFlag
 | 
						|
 | 
						|
try:
 | 
						|
    import errno
 | 
						|
except ImportError:
 | 
						|
    errno = None
 | 
						|
EBADF = getattr(errno, 'EBADF', 9)
 | 
						|
EAGAIN = getattr(errno, 'EAGAIN', 11)
 | 
						|
EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11)
 | 
						|
 | 
						|
__all__ = ["fromfd", "getfqdn", "create_connection", "create_server",
 | 
						|
           "has_dualstack_ipv6", "AddressFamily", "SocketKind"]
 | 
						|
__all__.extend(os._get_exports_list(_socket))
 | 
						|
 | 
						|
# Set up the socket.AF_* socket.SOCK_* constants as members of IntEnums for
 | 
						|
# nicer string representations.
 | 
						|
# Note that _socket only knows about the integer values. The public interface
 | 
						|
# in this module understands the enums and translates them back from integers
 | 
						|
# where needed (e.g. .family property of a socket object).
 | 
						|
 | 
						|
IntEnum._convert_(
 | 
						|
        'AddressFamily',
 | 
						|
        __name__,
 | 
						|
        lambda C: C.isupper() and C.startswith('AF_'))
 | 
						|
 | 
						|
IntEnum._convert_(
 | 
						|
        'SocketKind',
 | 
						|
        __name__,
 | 
						|
        lambda C: C.isupper() and C.startswith('SOCK_'))
 | 
						|
 | 
						|
IntFlag._convert_(
 | 
						|
        'MsgFlag',
 | 
						|
        __name__,
 | 
						|
        lambda C: C.isupper() and C.startswith('MSG_'))
 | 
						|
 | 
						|
IntFlag._convert_(
 | 
						|
        'AddressInfo',
 | 
						|
        __name__,
 | 
						|
        lambda C: C.isupper() and C.startswith('AI_'))
 | 
						|
 | 
						|
_LOCALHOST    = '127.0.0.1'
 | 
						|
_LOCALHOST_V6 = '::1'
 | 
						|
 | 
						|
 | 
						|
def _intenum_converter(value, enum_klass):
 | 
						|
    """Convert a numeric family value to an IntEnum member.
 | 
						|
 | 
						|
    If it's not a known member, return the numeric value itself.
 | 
						|
    """
 | 
						|
    try:
 | 
						|
        return enum_klass(value)
 | 
						|
    except ValueError:
 | 
						|
        return value
 | 
						|
 | 
						|
 | 
						|
# WSA error codes
 | 
						|
if sys.platform.lower().startswith("win"):
 | 
						|
    errorTab = {}
 | 
						|
    errorTab[6] = "Specified event object handle is invalid."
 | 
						|
    errorTab[8] = "Insufficient memory available."
 | 
						|
    errorTab[87] = "One or more parameters are invalid."
 | 
						|
    errorTab[995] = "Overlapped operation aborted."
 | 
						|
    errorTab[996] = "Overlapped I/O event object not in signaled state."
 | 
						|
    errorTab[997] = "Overlapped operation will complete later."
 | 
						|
    errorTab[10004] = "The operation was interrupted."
 | 
						|
    errorTab[10009] = "A bad file handle was passed."
 | 
						|
    errorTab[10013] = "Permission denied."
 | 
						|
    errorTab[10014] = "A fault occurred on the network??"  # WSAEFAULT
 | 
						|
    errorTab[10022] = "An invalid operation was attempted."
 | 
						|
    errorTab[10024] = "Too many open files."
 | 
						|
    errorTab[10035] = "The socket operation would block"
 | 
						|
    errorTab[10036] = "A blocking operation is already in progress."
 | 
						|
    errorTab[10037] = "Operation already in progress."
 | 
						|
    errorTab[10038] = "Socket operation on nonsocket."
 | 
						|
    errorTab[10039] = "Destination address required."
 | 
						|
    errorTab[10040] = "Message too long."
 | 
						|
    errorTab[10041] = "Protocol wrong type for socket."
 | 
						|
    errorTab[10042] = "Bad protocol option."
 | 
						|
    errorTab[10043] = "Protocol not supported."
 | 
						|
    errorTab[10044] = "Socket type not supported."
 | 
						|
    errorTab[10045] = "Operation not supported."
 | 
						|
    errorTab[10046] = "Protocol family not supported."
 | 
						|
    errorTab[10047] = "Address family not supported by protocol family."
 | 
						|
    errorTab[10048] = "The network address is in use."
 | 
						|
    errorTab[10049] = "Cannot assign requested address."
 | 
						|
    errorTab[10050] = "Network is down."
 | 
						|
    errorTab[10051] = "Network is unreachable."
 | 
						|
    errorTab[10052] = "Network dropped connection on reset."
 | 
						|
    errorTab[10053] = "Software caused connection abort."
 | 
						|
    errorTab[10054] = "The connection has been reset."
 | 
						|
    errorTab[10055] = "No buffer space available."
 | 
						|
    errorTab[10056] = "Socket is already connected."
 | 
						|
    errorTab[10057] = "Socket is not connected."
 | 
						|
    errorTab[10058] = "The network has been shut down."
 | 
						|
    errorTab[10059] = "Too many references."
 | 
						|
    errorTab[10060] = "The operation timed out."
 | 
						|
    errorTab[10061] = "Connection refused."
 | 
						|
    errorTab[10062] = "Cannot translate name."
 | 
						|
    errorTab[10063] = "The name is too long."
 | 
						|
    errorTab[10064] = "The host is down."
 | 
						|
    errorTab[10065] = "The host is unreachable."
 | 
						|
    errorTab[10066] = "Directory not empty."
 | 
						|
    errorTab[10067] = "Too many processes."
 | 
						|
    errorTab[10068] = "User quota exceeded."
 | 
						|
    errorTab[10069] = "Disk quota exceeded."
 | 
						|
    errorTab[10070] = "Stale file handle reference."
 | 
						|
    errorTab[10071] = "Item is remote."
 | 
						|
    errorTab[10091] = "Network subsystem is unavailable."
 | 
						|
    errorTab[10092] = "Winsock.dll version out of range."
 | 
						|
    errorTab[10093] = "Successful WSAStartup not yet performed."
 | 
						|
    errorTab[10101] = "Graceful shutdown in progress."
 | 
						|
    errorTab[10102] = "No more results from WSALookupServiceNext."
 | 
						|
    errorTab[10103] = "Call has been canceled."
 | 
						|
    errorTab[10104] = "Procedure call table is invalid."
 | 
						|
    errorTab[10105] = "Service provider is invalid."
 | 
						|
    errorTab[10106] = "Service provider failed to initialize."
 | 
						|
    errorTab[10107] = "System call failure."
 | 
						|
    errorTab[10108] = "Service not found."
 | 
						|
    errorTab[10109] = "Class type not found."
 | 
						|
    errorTab[10110] = "No more results from WSALookupServiceNext."
 | 
						|
    errorTab[10111] = "Call was canceled."
 | 
						|
    errorTab[10112] = "Database query was refused."
 | 
						|
    errorTab[11001] = "Host not found."
 | 
						|
    errorTab[11002] = "Nonauthoritative host not found."
 | 
						|
    errorTab[11003] = "This is a nonrecoverable error."
 | 
						|
    errorTab[11004] = "Valid name, no data record requested type."
 | 
						|
    errorTab[11005] = "QoS receivers."
 | 
						|
    errorTab[11006] = "QoS senders."
 | 
						|
    errorTab[11007] = "No QoS senders."
 | 
						|
    errorTab[11008] = "QoS no receivers."
 | 
						|
    errorTab[11009] = "QoS request confirmed."
 | 
						|
    errorTab[11010] = "QoS admission error."
 | 
						|
    errorTab[11011] = "QoS policy failure."
 | 
						|
    errorTab[11012] = "QoS bad style."
 | 
						|
    errorTab[11013] = "QoS bad object."
 | 
						|
    errorTab[11014] = "QoS traffic control error."
 | 
						|
    errorTab[11015] = "QoS generic error."
 | 
						|
    errorTab[11016] = "QoS service type error."
 | 
						|
    errorTab[11017] = "QoS flowspec error."
 | 
						|
    errorTab[11018] = "Invalid QoS provider buffer."
 | 
						|
    errorTab[11019] = "Invalid QoS filter style."
 | 
						|
    errorTab[11020] = "Invalid QoS filter style."
 | 
						|
    errorTab[11021] = "Incorrect QoS filter count."
 | 
						|
    errorTab[11022] = "Invalid QoS object length."
 | 
						|
    errorTab[11023] = "Incorrect QoS flow count."
 | 
						|
    errorTab[11024] = "Unrecognized QoS object."
 | 
						|
    errorTab[11025] = "Invalid QoS policy object."
 | 
						|
    errorTab[11026] = "Invalid QoS flow descriptor."
 | 
						|
    errorTab[11027] = "Invalid QoS provider-specific flowspec."
 | 
						|
    errorTab[11028] = "Invalid QoS provider-specific filterspec."
 | 
						|
    errorTab[11029] = "Invalid QoS shape discard mode object."
 | 
						|
    errorTab[11030] = "Invalid QoS shaping rate object."
 | 
						|
    errorTab[11031] = "Reserved policy QoS element type."
 | 
						|
    __all__.append("errorTab")
 | 
						|
 | 
						|
 | 
						|
class _GiveupOnSendfile(Exception): pass
 | 
						|
 | 
						|
 | 
						|
class socket(_socket.socket):
 | 
						|
 | 
						|
    """A subclass of _socket.socket adding the makefile() method."""
 | 
						|
 | 
						|
    __slots__ = ["__weakref__", "_io_refs", "_closed"]
 | 
						|
 | 
						|
    def __init__(self, family=-1, type=-1, proto=-1, fileno=None):
 | 
						|
        # For user code address family and type values are IntEnum members, but
 | 
						|
        # for the underlying _socket.socket they're just integers. The
 | 
						|
        # constructor of _socket.socket converts the given argument to an
 | 
						|
        # integer automatically.
 | 
						|
        if fileno is None:
 | 
						|
            if family == -1:
 | 
						|
                family = AF_INET
 | 
						|
            if type == -1:
 | 
						|
                type = SOCK_STREAM
 | 
						|
            if proto == -1:
 | 
						|
                proto = 0
 | 
						|
        _socket.socket.__init__(self, family, type, proto, fileno)
 | 
						|
        self._io_refs = 0
 | 
						|
        self._closed = False
 | 
						|
 | 
						|
    def __enter__(self):
 | 
						|
        return self
 | 
						|
 | 
						|
    def __exit__(self, *args):
 | 
						|
        if not self._closed:
 | 
						|
            self.close()
 | 
						|
 | 
						|
    def __repr__(self):
 | 
						|
        """Wrap __repr__() to reveal the real class name and socket
 | 
						|
        address(es).
 | 
						|
        """
 | 
						|
        closed = getattr(self, '_closed', False)
 | 
						|
        s = "<%s.%s%s fd=%i, family=%s, type=%s, proto=%i" \
 | 
						|
            % (self.__class__.__module__,
 | 
						|
               self.__class__.__qualname__,
 | 
						|
               " [closed]" if closed else "",
 | 
						|
               self.fileno(),
 | 
						|
               self.family,
 | 
						|
               self.type,
 | 
						|
               self.proto)
 | 
						|
        if not closed:
 | 
						|
            try:
 | 
						|
                laddr = self.getsockname()
 | 
						|
                if laddr:
 | 
						|
                    s += ", laddr=%s" % str(laddr)
 | 
						|
            except error:
 | 
						|
                pass
 | 
						|
            try:
 | 
						|
                raddr = self.getpeername()
 | 
						|
                if raddr:
 | 
						|
                    s += ", raddr=%s" % str(raddr)
 | 
						|
            except error:
 | 
						|
                pass
 | 
						|
        s += '>'
 | 
						|
        return s
 | 
						|
 | 
						|
    def __getstate__(self):
 | 
						|
        raise TypeError(f"cannot pickle {self.__class__.__name__!r} object")
 | 
						|
 | 
						|
    def dup(self):
 | 
						|
        """dup() -> socket object
 | 
						|
 | 
						|
        Duplicate the socket. Return a new socket object connected to the same
 | 
						|
        system resource. The new socket is non-inheritable.
 | 
						|
        """
 | 
						|
        fd = dup(self.fileno())
 | 
						|
        sock = self.__class__(self.family, self.type, self.proto, fileno=fd)
 | 
						|
        sock.settimeout(self.gettimeout())
 | 
						|
        return sock
 | 
						|
 | 
						|
    def accept(self):
 | 
						|
        """accept() -> (socket object, address info)
 | 
						|
 | 
						|
        Wait for an incoming connection.  Return a new socket
 | 
						|
        representing the connection, and the address of the client.
 | 
						|
        For IP sockets, the address info is a pair (hostaddr, port).
 | 
						|
        """
 | 
						|
        fd, addr = self._accept()
 | 
						|
        sock = socket(self.family, self.type, self.proto, fileno=fd)
 | 
						|
        # Issue #7995: if no default timeout is set and the listening
 | 
						|
        # socket had a (non-zero) timeout, force the new socket in blocking
 | 
						|
        # mode to override platform-specific socket flags inheritance.
 | 
						|
        if getdefaulttimeout() is None and self.gettimeout():
 | 
						|
            sock.setblocking(True)
 | 
						|
        return sock, addr
 | 
						|
 | 
						|
    def makefile(self, mode="r", buffering=None, *,
 | 
						|
                 encoding=None, errors=None, newline=None):
 | 
						|
        """makefile(...) -> an I/O stream connected to the socket
 | 
						|
 | 
						|
        The arguments are as for io.open() after the filename, except the only
 | 
						|
        supported mode values are 'r' (default), 'w' and 'b'.
 | 
						|
        """
 | 
						|
        # XXX refactor to share code?
 | 
						|
        if not set(mode) <= {"r", "w", "b"}:
 | 
						|
            raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,))
 | 
						|
        writing = "w" in mode
 | 
						|
        reading = "r" in mode or not writing
 | 
						|
        assert reading or writing
 | 
						|
        binary = "b" in mode
 | 
						|
        rawmode = ""
 | 
						|
        if reading:
 | 
						|
            rawmode += "r"
 | 
						|
        if writing:
 | 
						|
            rawmode += "w"
 | 
						|
        raw = SocketIO(self, rawmode)
 | 
						|
        self._io_refs += 1
 | 
						|
        if buffering is None:
 | 
						|
            buffering = -1
 | 
						|
        if buffering < 0:
 | 
						|
            buffering = io.DEFAULT_BUFFER_SIZE
 | 
						|
        if buffering == 0:
 | 
						|
            if not binary:
 | 
						|
                raise ValueError("unbuffered streams must be binary")
 | 
						|
            return raw
 | 
						|
        if reading and writing:
 | 
						|
            buffer = io.BufferedRWPair(raw, raw, buffering)
 | 
						|
        elif reading:
 | 
						|
            buffer = io.BufferedReader(raw, buffering)
 | 
						|
        else:
 | 
						|
            assert writing
 | 
						|
            buffer = io.BufferedWriter(raw, buffering)
 | 
						|
        if binary:
 | 
						|
            return buffer
 | 
						|
        encoding = io.text_encoding(encoding)
 | 
						|
        text = io.TextIOWrapper(buffer, encoding, errors, newline)
 | 
						|
        text.mode = mode
 | 
						|
        return text
 | 
						|
 | 
						|
    if hasattr(os, 'sendfile'):
 | 
						|
 | 
						|
        def _sendfile_use_sendfile(self, file, offset=0, count=None):
 | 
						|
            self._check_sendfile_params(file, offset, count)
 | 
						|
            sockno = self.fileno()
 | 
						|
            try:
 | 
						|
                fileno = file.fileno()
 | 
						|
            except (AttributeError, io.UnsupportedOperation) as err:
 | 
						|
                raise _GiveupOnSendfile(err)  # not a regular file
 | 
						|
            try:
 | 
						|
                fsize = os.fstat(fileno).st_size
 | 
						|
            except OSError as err:
 | 
						|
                raise _GiveupOnSendfile(err)  # not a regular file
 | 
						|
            if not fsize:
 | 
						|
                return 0  # empty file
 | 
						|
            # Truncate to 1GiB to avoid OverflowError, see bpo-38319.
 | 
						|
            blocksize = min(count or fsize, 2 ** 30)
 | 
						|
            timeout = self.gettimeout()
 | 
						|
            if timeout == 0:
 | 
						|
                raise ValueError("non-blocking sockets are not supported")
 | 
						|
            # poll/select have the advantage of not requiring any
 | 
						|
            # extra file descriptor, contrarily to epoll/kqueue
 | 
						|
            # (also, they require a single syscall).
 | 
						|
            if hasattr(selectors, 'PollSelector'):
 | 
						|
                selector = selectors.PollSelector()
 | 
						|
            else:
 | 
						|
                selector = selectors.SelectSelector()
 | 
						|
            selector.register(sockno, selectors.EVENT_WRITE)
 | 
						|
 | 
						|
            total_sent = 0
 | 
						|
            # localize variable access to minimize overhead
 | 
						|
            selector_select = selector.select
 | 
						|
            os_sendfile = os.sendfile
 | 
						|
            try:
 | 
						|
                while True:
 | 
						|
                    if timeout and not selector_select(timeout):
 | 
						|
                        raise TimeoutError('timed out')
 | 
						|
                    if count:
 | 
						|
                        blocksize = count - total_sent
 | 
						|
                        if blocksize <= 0:
 | 
						|
                            break
 | 
						|
                    try:
 | 
						|
                        sent = os_sendfile(sockno, fileno, offset, blocksize)
 | 
						|
                    except BlockingIOError:
 | 
						|
                        if not timeout:
 | 
						|
                            # Block until the socket is ready to send some
 | 
						|
                            # data; avoids hogging CPU resources.
 | 
						|
                            selector_select()
 | 
						|
                        continue
 | 
						|
                    except OSError as err:
 | 
						|
                        if total_sent == 0:
 | 
						|
                            # We can get here for different reasons, the main
 | 
						|
                            # one being 'file' is not a regular mmap(2)-like
 | 
						|
                            # file, in which case we'll fall back on using
 | 
						|
                            # plain send().
 | 
						|
                            raise _GiveupOnSendfile(err)
 | 
						|
                        raise err from None
 | 
						|
                    else:
 | 
						|
                        if sent == 0:
 | 
						|
                            break  # EOF
 | 
						|
                        offset += sent
 | 
						|
                        total_sent += sent
 | 
						|
                return total_sent
 | 
						|
            finally:
 | 
						|
                if total_sent > 0 and hasattr(file, 'seek'):
 | 
						|
                    file.seek(offset)
 | 
						|
    else:
 | 
						|
        def _sendfile_use_sendfile(self, file, offset=0, count=None):
 | 
						|
            raise _GiveupOnSendfile(
 | 
						|
                "os.sendfile() not available on this platform")
 | 
						|
 | 
						|
    def _sendfile_use_send(self, file, offset=0, count=None):
 | 
						|
        self._check_sendfile_params(file, offset, count)
 | 
						|
        if self.gettimeout() == 0:
 | 
						|
            raise ValueError("non-blocking sockets are not supported")
 | 
						|
        if offset:
 | 
						|
            file.seek(offset)
 | 
						|
        blocksize = min(count, 8192) if count else 8192
 | 
						|
        total_sent = 0
 | 
						|
        # localize variable access to minimize overhead
 | 
						|
        file_read = file.read
 | 
						|
        sock_send = self.send
 | 
						|
        try:
 | 
						|
            while True:
 | 
						|
                if count:
 | 
						|
                    blocksize = min(count - total_sent, blocksize)
 | 
						|
                    if blocksize <= 0:
 | 
						|
                        break
 | 
						|
                data = memoryview(file_read(blocksize))
 | 
						|
                if not data:
 | 
						|
                    break  # EOF
 | 
						|
                while True:
 | 
						|
                    try:
 | 
						|
                        sent = sock_send(data)
 | 
						|
                    except BlockingIOError:
 | 
						|
                        continue
 | 
						|
                    else:
 | 
						|
                        total_sent += sent
 | 
						|
                        if sent < len(data):
 | 
						|
                            data = data[sent:]
 | 
						|
                        else:
 | 
						|
                            break
 | 
						|
            return total_sent
 | 
						|
        finally:
 | 
						|
            if total_sent > 0 and hasattr(file, 'seek'):
 | 
						|
                file.seek(offset + total_sent)
 | 
						|
 | 
						|
    def _check_sendfile_params(self, file, offset, count):
 | 
						|
        if 'b' not in getattr(file, 'mode', 'b'):
 | 
						|
            raise ValueError("file should be opened in binary mode")
 | 
						|
        if not self.type & SOCK_STREAM:
 | 
						|
            raise ValueError("only SOCK_STREAM type sockets are supported")
 | 
						|
        if count is not None:
 | 
						|
            if not isinstance(count, int):
 | 
						|
                raise TypeError(
 | 
						|
                    "count must be a positive integer (got {!r})".format(count))
 | 
						|
            if count <= 0:
 | 
						|
                raise ValueError(
 | 
						|
                    "count must be a positive integer (got {!r})".format(count))
 | 
						|
 | 
						|
    def sendfile(self, file, offset=0, count=None):
 | 
						|
        """sendfile(file[, offset[, count]]) -> sent
 | 
						|
 | 
						|
        Send a file until EOF is reached by using high-performance
 | 
						|
        os.sendfile() and return the total number of bytes which
 | 
						|
        were sent.
 | 
						|
        *file* must be a regular file object opened in binary mode.
 | 
						|
        If os.sendfile() is not available (e.g. Windows) or file is
 | 
						|
        not a regular file socket.send() will be used instead.
 | 
						|
        *offset* tells from where to start reading the file.
 | 
						|
        If specified, *count* is the total number of bytes to transmit
 | 
						|
        as opposed to sending the file until EOF is reached.
 | 
						|
        File position is updated on return or also in case of error in
 | 
						|
        which case file.tell() can be used to figure out the number of
 | 
						|
        bytes which were sent.
 | 
						|
        The socket must be of SOCK_STREAM type.
 | 
						|
        Non-blocking sockets are not supported.
 | 
						|
        """
 | 
						|
        try:
 | 
						|
            return self._sendfile_use_sendfile(file, offset, count)
 | 
						|
        except _GiveupOnSendfile:
 | 
						|
            return self._sendfile_use_send(file, offset, count)
 | 
						|
 | 
						|
    def _decref_socketios(self):
 | 
						|
        if self._io_refs > 0:
 | 
						|
            self._io_refs -= 1
 | 
						|
        if self._closed:
 | 
						|
            self.close()
 | 
						|
 | 
						|
    def _real_close(self, _ss=_socket.socket):
 | 
						|
        # This function should not reference any globals. See issue #808164.
 | 
						|
        _ss.close(self)
 | 
						|
 | 
						|
    def close(self):
 | 
						|
        # This function should not reference any globals. See issue #808164.
 | 
						|
        self._closed = True
 | 
						|
        if self._io_refs <= 0:
 | 
						|
            self._real_close()
 | 
						|
 | 
						|
    def detach(self):
 | 
						|
        """detach() -> file descriptor
 | 
						|
 | 
						|
        Close the socket object without closing the underlying file descriptor.
 | 
						|
        The object cannot be used after this call, but the file descriptor
 | 
						|
        can be reused for other purposes.  The file descriptor is returned.
 | 
						|
        """
 | 
						|
        self._closed = True
 | 
						|
        return super().detach()
 | 
						|
 | 
						|
    @property
 | 
						|
    def family(self):
 | 
						|
        """Read-only access to the address family for this socket.
 | 
						|
        """
 | 
						|
        return _intenum_converter(super().family, AddressFamily)
 | 
						|
 | 
						|
    @property
 | 
						|
    def type(self):
 | 
						|
        """Read-only access to the socket type.
 | 
						|
        """
 | 
						|
        return _intenum_converter(super().type, SocketKind)
 | 
						|
 | 
						|
    if os.name == 'nt':
 | 
						|
        def get_inheritable(self):
 | 
						|
            return os.get_handle_inheritable(self.fileno())
 | 
						|
        def set_inheritable(self, inheritable):
 | 
						|
            os.set_handle_inheritable(self.fileno(), inheritable)
 | 
						|
    else:
 | 
						|
        def get_inheritable(self):
 | 
						|
            return os.get_inheritable(self.fileno())
 | 
						|
        def set_inheritable(self, inheritable):
 | 
						|
            os.set_inheritable(self.fileno(), inheritable)
 | 
						|
    get_inheritable.__doc__ = "Get the inheritable flag of the socket"
 | 
						|
    set_inheritable.__doc__ = "Set the inheritable flag of the socket"
 | 
						|
 | 
						|
def fromfd(fd, family, type, proto=0):
 | 
						|
    """ fromfd(fd, family, type[, proto]) -> socket object
 | 
						|
 | 
						|
    Create a socket object from a duplicate of the given file
 | 
						|
    descriptor.  The remaining arguments are the same as for socket().
 | 
						|
    """
 | 
						|
    nfd = dup(fd)
 | 
						|
    return socket(family, type, proto, nfd)
 | 
						|
 | 
						|
if hasattr(_socket.socket, "sendmsg"):
 | 
						|
    import array
 | 
						|
 | 
						|
    def send_fds(sock, buffers, fds, flags=0, address=None):
 | 
						|
        """ send_fds(sock, buffers, fds[, flags[, address]]) -> integer
 | 
						|
 | 
						|
        Send the list of file descriptors fds over an AF_UNIX socket.
 | 
						|
        """
 | 
						|
        return sock.sendmsg(buffers, [(_socket.SOL_SOCKET,
 | 
						|
            _socket.SCM_RIGHTS, array.array("i", fds))])
 | 
						|
    __all__.append("send_fds")
 | 
						|
 | 
						|
if hasattr(_socket.socket, "recvmsg"):
 | 
						|
    import array
 | 
						|
 | 
						|
    def recv_fds(sock, bufsize, maxfds, flags=0):
 | 
						|
        """ recv_fds(sock, bufsize, maxfds[, flags]) -> (data, list of file
 | 
						|
        descriptors, msg_flags, address)
 | 
						|
 | 
						|
        Receive up to maxfds file descriptors returning the message
 | 
						|
        data and a list containing the descriptors.
 | 
						|
        """
 | 
						|
        # Array of ints
 | 
						|
        fds = array.array("i")
 | 
						|
        msg, ancdata, flags, addr = sock.recvmsg(bufsize,
 | 
						|
            _socket.CMSG_LEN(maxfds * fds.itemsize))
 | 
						|
        for cmsg_level, cmsg_type, cmsg_data in ancdata:
 | 
						|
            if (cmsg_level == _socket.SOL_SOCKET and cmsg_type == _socket.SCM_RIGHTS):
 | 
						|
                fds.frombytes(cmsg_data[:
 | 
						|
                        len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
 | 
						|
 | 
						|
        return msg, list(fds), flags, addr
 | 
						|
    __all__.append("recv_fds")
 | 
						|
 | 
						|
if hasattr(_socket.socket, "share"):
 | 
						|
    def fromshare(info):
 | 
						|
        """ fromshare(info) -> socket object
 | 
						|
 | 
						|
        Create a socket object from the bytes object returned by
 | 
						|
        socket.share(pid).
 | 
						|
        """
 | 
						|
        return socket(0, 0, 0, info)
 | 
						|
    __all__.append("fromshare")
 | 
						|
 | 
						|
if hasattr(_socket, "socketpair"):
 | 
						|
 | 
						|
    def socketpair(family=None, type=SOCK_STREAM, proto=0):
 | 
						|
        """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
 | 
						|
 | 
						|
        Create a pair of socket objects from the sockets returned by the platform
 | 
						|
        socketpair() function.
 | 
						|
        The arguments are the same as for socket() except the default family is
 | 
						|
        AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
 | 
						|
        """
 | 
						|
        if family is None:
 | 
						|
            try:
 | 
						|
                family = AF_UNIX
 | 
						|
            except NameError:
 | 
						|
                family = AF_INET
 | 
						|
        a, b = _socket.socketpair(family, type, proto)
 | 
						|
        a = socket(family, type, proto, a.detach())
 | 
						|
        b = socket(family, type, proto, b.detach())
 | 
						|
        return a, b
 | 
						|
 | 
						|
else:
 | 
						|
 | 
						|
    # Origin: https://gist.github.com/4325783, by Geert Jansen.  Public domain.
 | 
						|
    def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
 | 
						|
        if family == AF_INET:
 | 
						|
            host = _LOCALHOST
 | 
						|
        elif family == AF_INET6:
 | 
						|
            host = _LOCALHOST_V6
 | 
						|
        else:
 | 
						|
            raise ValueError("Only AF_INET and AF_INET6 socket address families "
 | 
						|
                             "are supported")
 | 
						|
        if type != 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(False) that prevents us from having to create a thread.
 | 
						|
        lsock = socket(family, type, proto)
 | 
						|
        try:
 | 
						|
            lsock.bind((host, 0))
 | 
						|
            lsock.listen()
 | 
						|
            # On IPv6, ignore flow_info and scope_id
 | 
						|
            addr, port = lsock.getsockname()[:2]
 | 
						|
            csock = socket(family, type, proto)
 | 
						|
            try:
 | 
						|
                csock.setblocking(False)
 | 
						|
                try:
 | 
						|
                    csock.connect((addr, port))
 | 
						|
                except (BlockingIOError, InterruptedError):
 | 
						|
                    pass
 | 
						|
                csock.setblocking(True)
 | 
						|
                ssock, _ = lsock.accept()
 | 
						|
            except:
 | 
						|
                csock.close()
 | 
						|
                raise
 | 
						|
        finally:
 | 
						|
            lsock.close()
 | 
						|
        return (ssock, csock)
 | 
						|
    __all__.append("socketpair")
 | 
						|
 | 
						|
socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
 | 
						|
Create a pair of socket objects from the sockets returned by the platform
 | 
						|
socketpair() function.
 | 
						|
The arguments are the same as for socket() except the default family is AF_UNIX
 | 
						|
if defined on the platform; otherwise, the default is AF_INET.
 | 
						|
"""
 | 
						|
 | 
						|
_blocking_errnos = { EAGAIN, EWOULDBLOCK }
 | 
						|
 | 
						|
class SocketIO(io.RawIOBase):
 | 
						|
 | 
						|
    """Raw I/O implementation for stream sockets.
 | 
						|
 | 
						|
    This class supports the makefile() method on sockets.  It provides
 | 
						|
    the raw I/O interface on top of a socket object.
 | 
						|
    """
 | 
						|
 | 
						|
    # One might wonder why not let FileIO do the job instead.  There are two
 | 
						|
    # main reasons why FileIO is not adapted:
 | 
						|
    # - it wouldn't work under Windows (where you can't used read() and
 | 
						|
    #   write() on a socket handle)
 | 
						|
    # - it wouldn't work with socket timeouts (FileIO would ignore the
 | 
						|
    #   timeout and consider the socket non-blocking)
 | 
						|
 | 
						|
    # XXX More docs
 | 
						|
 | 
						|
    def __init__(self, sock, mode):
 | 
						|
        if mode not in ("r", "w", "rw", "rb", "wb", "rwb"):
 | 
						|
            raise ValueError("invalid mode: %r" % mode)
 | 
						|
        io.RawIOBase.__init__(self)
 | 
						|
        self._sock = sock
 | 
						|
        if "b" not in mode:
 | 
						|
            mode += "b"
 | 
						|
        self._mode = mode
 | 
						|
        self._reading = "r" in mode
 | 
						|
        self._writing = "w" in mode
 | 
						|
        self._timeout_occurred = False
 | 
						|
 | 
						|
    def readinto(self, b):
 | 
						|
        """Read up to len(b) bytes into the writable buffer *b* and return
 | 
						|
        the number of bytes read.  If the socket is non-blocking and no bytes
 | 
						|
        are available, None is returned.
 | 
						|
 | 
						|
        If *b* is non-empty, a 0 return value indicates that the connection
 | 
						|
        was shutdown at the other end.
 | 
						|
        """
 | 
						|
        self._checkClosed()
 | 
						|
        self._checkReadable()
 | 
						|
        if self._timeout_occurred:
 | 
						|
            raise OSError("cannot read from timed out object")
 | 
						|
        while True:
 | 
						|
            try:
 | 
						|
                return self._sock.recv_into(b)
 | 
						|
            except timeout:
 | 
						|
                self._timeout_occurred = True
 | 
						|
                raise
 | 
						|
            except error as e:
 | 
						|
                if e.errno in _blocking_errnos:
 | 
						|
                    return None
 | 
						|
                raise
 | 
						|
 | 
						|
    def write(self, b):
 | 
						|
        """Write the given bytes or bytearray object *b* to the socket
 | 
						|
        and return the number of bytes written.  This can be less than
 | 
						|
        len(b) if not all data could be written.  If the socket is
 | 
						|
        non-blocking and no bytes could be written None is returned.
 | 
						|
        """
 | 
						|
        self._checkClosed()
 | 
						|
        self._checkWritable()
 | 
						|
        try:
 | 
						|
            return self._sock.send(b)
 | 
						|
        except error as e:
 | 
						|
            # XXX what about EINTR?
 | 
						|
            if e.errno in _blocking_errnos:
 | 
						|
                return None
 | 
						|
            raise
 | 
						|
 | 
						|
    def readable(self):
 | 
						|
        """True if the SocketIO is open for reading.
 | 
						|
        """
 | 
						|
        if self.closed:
 | 
						|
            raise ValueError("I/O operation on closed socket.")
 | 
						|
        return self._reading
 | 
						|
 | 
						|
    def writable(self):
 | 
						|
        """True if the SocketIO is open for writing.
 | 
						|
        """
 | 
						|
        if self.closed:
 | 
						|
            raise ValueError("I/O operation on closed socket.")
 | 
						|
        return self._writing
 | 
						|
 | 
						|
    def seekable(self):
 | 
						|
        """True if the SocketIO is open for seeking.
 | 
						|
        """
 | 
						|
        if self.closed:
 | 
						|
            raise ValueError("I/O operation on closed socket.")
 | 
						|
        return super().seekable()
 | 
						|
 | 
						|
    def fileno(self):
 | 
						|
        """Return the file descriptor of the underlying socket.
 | 
						|
        """
 | 
						|
        self._checkClosed()
 | 
						|
        return self._sock.fileno()
 | 
						|
 | 
						|
    @property
 | 
						|
    def name(self):
 | 
						|
        if not self.closed:
 | 
						|
            return self.fileno()
 | 
						|
        else:
 | 
						|
            return -1
 | 
						|
 | 
						|
    @property
 | 
						|
    def mode(self):
 | 
						|
        return self._mode
 | 
						|
 | 
						|
    def close(self):
 | 
						|
        """Close the SocketIO object.  This doesn't close the underlying
 | 
						|
        socket, except if all references to it have disappeared.
 | 
						|
        """
 | 
						|
        if self.closed:
 | 
						|
            return
 | 
						|
        io.RawIOBase.close(self)
 | 
						|
        self._sock._decref_socketios()
 | 
						|
        self._sock = None
 | 
						|
 | 
						|
 | 
						|
def getfqdn(name=''):
 | 
						|
    """Get fully qualified domain name from name.
 | 
						|
 | 
						|
    An empty argument is interpreted as meaning the local host.
 | 
						|
 | 
						|
    First the hostname returned by gethostbyaddr() is checked, then
 | 
						|
    possibly existing aliases. In case no FQDN is available, hostname
 | 
						|
    from gethostname() is returned.
 | 
						|
    """
 | 
						|
    name = name.strip()
 | 
						|
    if not name or name == '0.0.0.0':
 | 
						|
        name = gethostname()
 | 
						|
    try:
 | 
						|
        hostname, aliases, ipaddrs = gethostbyaddr(name)
 | 
						|
    except error:
 | 
						|
        pass
 | 
						|
    else:
 | 
						|
        aliases.insert(0, hostname)
 | 
						|
        for name in aliases:
 | 
						|
            if '.' in name:
 | 
						|
                break
 | 
						|
        else:
 | 
						|
            name = hostname
 | 
						|
    return name
 | 
						|
 | 
						|
 | 
						|
_GLOBAL_DEFAULT_TIMEOUT = object()
 | 
						|
 | 
						|
def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
 | 
						|
                      source_address=None):
 | 
						|
    """Connect to *address* and return the socket object.
 | 
						|
 | 
						|
    Convenience function.  Connect to *address* (a 2-tuple ``(host,
 | 
						|
    port)``) and return the socket object.  Passing the optional
 | 
						|
    *timeout* parameter will set the timeout on the socket instance
 | 
						|
    before attempting to connect.  If no *timeout* is supplied, the
 | 
						|
    global default timeout setting returned by :func:`getdefaulttimeout`
 | 
						|
    is used.  If *source_address* is set it must be a tuple of (host, port)
 | 
						|
    for the socket to bind as a source address before making the connection.
 | 
						|
    A host of '' or port 0 tells the OS to use the default.
 | 
						|
    """
 | 
						|
 | 
						|
    host, port = address
 | 
						|
    err = None
 | 
						|
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
 | 
						|
        af, socktype, proto, canonname, sa = res
 | 
						|
        sock = None
 | 
						|
        try:
 | 
						|
            sock = socket(af, socktype, proto)
 | 
						|
            if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
 | 
						|
                sock.settimeout(timeout)
 | 
						|
            if source_address:
 | 
						|
                sock.bind(source_address)
 | 
						|
            sock.connect(sa)
 | 
						|
            # Break explicitly a reference cycle
 | 
						|
            err = None
 | 
						|
            return sock
 | 
						|
 | 
						|
        except error as _:
 | 
						|
            err = _
 | 
						|
            if sock is not None:
 | 
						|
                sock.close()
 | 
						|
 | 
						|
    if err is not None:
 | 
						|
        try:
 | 
						|
            raise err
 | 
						|
        finally:
 | 
						|
            # Break explicitly a reference cycle
 | 
						|
            err = None
 | 
						|
    else:
 | 
						|
        raise error("getaddrinfo returns an empty list")
 | 
						|
 | 
						|
 | 
						|
def has_dualstack_ipv6():
 | 
						|
    """Return True if the platform supports creating a SOCK_STREAM socket
 | 
						|
    which can handle both AF_INET and AF_INET6 (IPv4 / IPv6) connections.
 | 
						|
    """
 | 
						|
    if not has_ipv6 \
 | 
						|
            or not hasattr(_socket, 'IPPROTO_IPV6') \
 | 
						|
            or not hasattr(_socket, 'IPV6_V6ONLY'):
 | 
						|
        return False
 | 
						|
    try:
 | 
						|
        with socket(AF_INET6, SOCK_STREAM) as sock:
 | 
						|
            sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0)
 | 
						|
            return True
 | 
						|
    except error:
 | 
						|
        return False
 | 
						|
 | 
						|
 | 
						|
def create_server(address, *, family=AF_INET, backlog=None, reuse_port=False,
 | 
						|
                  dualstack_ipv6=False):
 | 
						|
    """Convenience function which creates a SOCK_STREAM type socket
 | 
						|
    bound to *address* (a 2-tuple (host, port)) and return the socket
 | 
						|
    object.
 | 
						|
 | 
						|
    *family* should be either AF_INET or AF_INET6.
 | 
						|
    *backlog* is the queue size passed to socket.listen().
 | 
						|
    *reuse_port* dictates whether to use the SO_REUSEPORT socket option.
 | 
						|
    *dualstack_ipv6*: if true and the platform supports it, it will
 | 
						|
    create an AF_INET6 socket able to accept both IPv4 or IPv6
 | 
						|
    connections. When false it will explicitly disable this option on
 | 
						|
    platforms that enable it by default (e.g. Linux).
 | 
						|
 | 
						|
    >>> with create_server(('', 8000)) as server:
 | 
						|
    ...     while True:
 | 
						|
    ...         conn, addr = server.accept()
 | 
						|
    ...         # handle new connection
 | 
						|
    """
 | 
						|
    if reuse_port and not hasattr(_socket, "SO_REUSEPORT"):
 | 
						|
        raise ValueError("SO_REUSEPORT not supported on this platform")
 | 
						|
    if dualstack_ipv6:
 | 
						|
        if not has_dualstack_ipv6():
 | 
						|
            raise ValueError("dualstack_ipv6 not supported on this platform")
 | 
						|
        if family != AF_INET6:
 | 
						|
            raise ValueError("dualstack_ipv6 requires AF_INET6 family")
 | 
						|
    sock = socket(family, SOCK_STREAM)
 | 
						|
    try:
 | 
						|
        # Note about Windows. We don't set SO_REUSEADDR because:
 | 
						|
        # 1) It's unnecessary: bind() will succeed even in case of a
 | 
						|
        # previous closed socket on the same address and still in
 | 
						|
        # TIME_WAIT state.
 | 
						|
        # 2) If set, another socket is free to bind() on the same
 | 
						|
        # address, effectively preventing this one from accepting
 | 
						|
        # connections. Also, it may set the process in a state where
 | 
						|
        # it'll no longer respond to any signals or graceful kills.
 | 
						|
        # See: msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx
 | 
						|
        if os.name not in ('nt', 'cygwin') and \
 | 
						|
                hasattr(_socket, 'SO_REUSEADDR'):
 | 
						|
            try:
 | 
						|
                sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
 | 
						|
            except error:
 | 
						|
                # Fail later on bind(), for platforms which may not
 | 
						|
                # support this option.
 | 
						|
                pass
 | 
						|
        if reuse_port:
 | 
						|
            sock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
 | 
						|
        if has_ipv6 and family == AF_INET6:
 | 
						|
            if dualstack_ipv6:
 | 
						|
                sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0)
 | 
						|
            elif hasattr(_socket, "IPV6_V6ONLY") and \
 | 
						|
                    hasattr(_socket, "IPPROTO_IPV6"):
 | 
						|
                sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 1)
 | 
						|
        try:
 | 
						|
            sock.bind(address)
 | 
						|
        except error as err:
 | 
						|
            msg = '%s (while attempting to bind on address %r)' % \
 | 
						|
                (err.strerror, address)
 | 
						|
            raise error(err.errno, msg) from None
 | 
						|
        if backlog is None:
 | 
						|
            sock.listen()
 | 
						|
        else:
 | 
						|
            sock.listen(backlog)
 | 
						|
        return sock
 | 
						|
    except error:
 | 
						|
        sock.close()
 | 
						|
        raise
 | 
						|
 | 
						|
 | 
						|
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
 | 
						|
    """Resolve host and port into list of address info entries.
 | 
						|
 | 
						|
    Translate the host/port argument into a sequence of 5-tuples that contain
 | 
						|
    all the necessary arguments for creating a socket connected to that service.
 | 
						|
    host is a domain name, a string representation of an IPv4/v6 address or
 | 
						|
    None. port is a string service name such as 'http', a numeric port number or
 | 
						|
    None. By passing None as the value of host and port, you can pass NULL to
 | 
						|
    the underlying C API.
 | 
						|
 | 
						|
    The family, type and proto arguments can be optionally specified in order to
 | 
						|
    narrow the list of addresses returned. Passing zero as a value for each of
 | 
						|
    these arguments selects the full range of results.
 | 
						|
    """
 | 
						|
    # We override this function since we want to translate the numeric family
 | 
						|
    # and socket type values to enum constants.
 | 
						|
    addrlist = []
 | 
						|
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
 | 
						|
        af, socktype, proto, canonname, sa = res
 | 
						|
        addrlist.append((_intenum_converter(af, AddressFamily),
 | 
						|
                         _intenum_converter(socktype, SocketKind),
 | 
						|
                         proto, canonname, sa))
 | 
						|
    return addrlist
 |