mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	svn+ssh://pythondev@svn.python.org/python/trunk ........ r70980 | jack.diederich | 2009-04-01 15:26:13 -0500 (Wed, 01 Apr 2009) | 3 lines bounds check arguments to mmap.move(). All of them. Really. fixes crasher on OS X 10.5 ........ r71059 | mark.dickinson | 2009-04-02 13:39:37 -0500 (Thu, 02 Apr 2009) | 2 lines sys.long_info attributes should be ints, not longs ........ r71225 | georg.brandl | 2009-04-05 06:54:07 -0500 (Sun, 05 Apr 2009) | 1 line #5580: no need to use parentheses when converterr() argument is actually a type description. ........ r71234 | georg.brandl | 2009-04-05 08:16:35 -0500 (Sun, 05 Apr 2009) | 1 line Whitespace normalization. ........ r71241 | georg.brandl | 2009-04-05 09:48:49 -0500 (Sun, 05 Apr 2009) | 1 line #5471: fix expanduser() for $HOME set to "/". ........ r71243 | georg.brandl | 2009-04-05 10:14:29 -0500 (Sun, 05 Apr 2009) | 1 line #5432: make plistlib docstring a raw string, since it contains examples with backslash escapes. ........ r71249 | georg.brandl | 2009-04-05 11:30:43 -0500 (Sun, 05 Apr 2009) | 1 line #5444: adapt make.bat to new htmlhelp output file name. ........ r71251 | georg.brandl | 2009-04-05 12:17:42 -0500 (Sun, 05 Apr 2009) | 1 line #5298: clarify docs about GIL by using more consistent wording. ........ r71255 | georg.brandl | 2009-04-05 13:34:58 -0500 (Sun, 05 Apr 2009) | 1 line #602893: add indicator for current line in cgitb that doesnt rely on styling alone. ........ r71266 | georg.brandl | 2009-04-05 15:23:13 -0500 (Sun, 05 Apr 2009) | 1 line Normalize issue referencing style. ........ r71299 | gregory.p.smith | 2009-04-05 18:43:58 -0500 (Sun, 05 Apr 2009) | 3 lines Fixes issue5705: os.setuid() and friends did not accept the same range of values that pwd.getpwnam() returns. ........ r71329 | benjamin.peterson | 2009-04-06 16:53:33 -0500 (Mon, 06 Apr 2009) | 1 line add create_connection to __all__ #5711 ........ r71397 | georg.brandl | 2009-04-08 11:36:39 -0500 (Wed, 08 Apr 2009) | 1 line Remove redundant backtick. ........ r71398 | georg.brandl | 2009-04-08 11:39:04 -0500 (Wed, 08 Apr 2009) | 1 line Update ignore file for suspicious builder. ........ r71486 | andrew.kuchling | 2009-04-11 11:18:14 -0500 (Sat, 11 Apr 2009) | 1 line Re-word ........
		
			
				
	
	
		
			307 lines
		
	
	
	
		
			9.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			307 lines
		
	
	
	
		
			9.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# 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 [*]
 | 
						|
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() -- mape 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
 | 
						|
 | 
						|
 [*] 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
 | 
						|
 | 
						|
Integer constants:
 | 
						|
 | 
						|
AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
 | 
						|
SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
 | 
						|
 | 
						|
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
 | 
						|
 | 
						|
try:
 | 
						|
    from errno import EBADF
 | 
						|
except ImportError:
 | 
						|
    EBADF = 9
 | 
						|
 | 
						|
__all__ = ["getfqdn", "create_connection"]
 | 
						|
__all__.extend(os._get_exports_list(_socket))
 | 
						|
 | 
						|
 | 
						|
_realsocket = socket
 | 
						|
 | 
						|
# WSA error codes
 | 
						|
if sys.platform.lower().startswith("win"):
 | 
						|
    errorTab = {}
 | 
						|
    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[10035] = "The socket operation would block"
 | 
						|
    errorTab[10036] = "A blocking operation is already in progress."
 | 
						|
    errorTab[10048] = "The network address is in use."
 | 
						|
    errorTab[10054] = "The connection has been reset."
 | 
						|
    errorTab[10058] = "The network has been shut down."
 | 
						|
    errorTab[10060] = "The operation timed out."
 | 
						|
    errorTab[10061] = "Connection refused."
 | 
						|
    errorTab[10063] = "The name is too long."
 | 
						|
    errorTab[10064] = "The host is down."
 | 
						|
    errorTab[10065] = "The host is unreachable."
 | 
						|
    __all__.append("errorTab")
 | 
						|
 | 
						|
 | 
						|
class socket(_socket.socket):
 | 
						|
 | 
						|
    """A subclass of _socket.socket adding the makefile() method."""
 | 
						|
 | 
						|
    __slots__ = ["__weakref__", "_io_refs", "_closed"]
 | 
						|
 | 
						|
    def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None):
 | 
						|
        _socket.socket.__init__(self, family, type, proto, fileno)
 | 
						|
        self._io_refs = 0
 | 
						|
        self._closed = False
 | 
						|
 | 
						|
    def __repr__(self):
 | 
						|
        """Wrap __repr__() to reveal the real class name."""
 | 
						|
        s = _socket.socket.__repr__(self)
 | 
						|
        if s.startswith("<socket object"):
 | 
						|
            s = "<%s.%s%s%s" % (self.__class__.__module__,
 | 
						|
                                self.__class__.__name__,
 | 
						|
                                (self._closed and " [closed] ") or "",
 | 
						|
                                s[7:])
 | 
						|
        return s
 | 
						|
 | 
						|
    def dup(self):
 | 
						|
        """dup() -> socket object
 | 
						|
 | 
						|
        Return a new socket object connected to the same system resource.
 | 
						|
        """
 | 
						|
        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()
 | 
						|
        return socket(self.family, self.type, self.proto, fileno=fd), addr
 | 
						|
 | 
						|
    def makefile(self, mode="r", buffering=None, *,
 | 
						|
                 encoding=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 mode characters supported are 'r', 'w' and 'b'.
 | 
						|
        The semantics are similar too.  (XXX refactor to share code?)
 | 
						|
        """
 | 
						|
        for c in mode:
 | 
						|
            if c not in {"r", "w", "b"}:
 | 
						|
                raise ValueError("invalid mode %r (only r, w, b allowed)")
 | 
						|
        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
 | 
						|
        text = io.TextIOWrapper(buffer, encoding, newline)
 | 
						|
        text.mode = mode
 | 
						|
        return text
 | 
						|
 | 
						|
    def _decref_socketios(self):
 | 
						|
        if self._io_refs > 0:
 | 
						|
            self._io_refs -= 1
 | 
						|
        if self._closed:
 | 
						|
            self.close()
 | 
						|
 | 
						|
    def _real_close(self):
 | 
						|
        _socket.socket.close(self)
 | 
						|
 | 
						|
    def close(self):
 | 
						|
        self._closed = True
 | 
						|
        if self._io_refs <= 0:
 | 
						|
            self._real_close()
 | 
						|
 | 
						|
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)
 | 
						|
 | 
						|
 | 
						|
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.
 | 
						|
    """
 | 
						|
 | 
						|
    # 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
 | 
						|
 | 
						|
    def readinto(self, b):
 | 
						|
        self._checkClosed()
 | 
						|
        self._checkReadable()
 | 
						|
        return self._sock.recv_into(b)
 | 
						|
 | 
						|
    def write(self, b):
 | 
						|
        self._checkClosed()
 | 
						|
        self._checkWritable()
 | 
						|
        return self._sock.send(b)
 | 
						|
 | 
						|
    def readable(self):
 | 
						|
        return self._reading and not self.closed
 | 
						|
 | 
						|
    def writable(self):
 | 
						|
        return self._writing and not self.closed
 | 
						|
 | 
						|
    def fileno(self):
 | 
						|
        self._checkClosed()
 | 
						|
        return self._sock.fileno()
 | 
						|
 | 
						|
    @property
 | 
						|
    def name(self):
 | 
						|
        return self.fileno()
 | 
						|
 | 
						|
    @property
 | 
						|
    def mode(self):
 | 
						|
        return self._mode
 | 
						|
 | 
						|
    def close(self):
 | 
						|
        if self.closed:
 | 
						|
            return
 | 
						|
        io.RawIOBase.close(self)
 | 
						|
        self._sock._decref_socketios()
 | 
						|
        self._sock = None
 | 
						|
 | 
						|
    def __del__(self):
 | 
						|
        if not self.closed:
 | 
						|
            self._sock._decref_socketios()
 | 
						|
 | 
						|
 | 
						|
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):
 | 
						|
    """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.
 | 
						|
    """
 | 
						|
 | 
						|
    msg = "getaddrinfo returns an empty list"
 | 
						|
    host, port = address
 | 
						|
    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)
 | 
						|
            sock.connect(sa)
 | 
						|
            return sock
 | 
						|
 | 
						|
        except error as err:
 | 
						|
            msg = err
 | 
						|
            if sock is not None:
 | 
						|
                sock.close()
 | 
						|
 | 
						|
    raise error(msg)
 |