From a6070f0221c0f4f2bb0fea518ea6e0b5e9497271 Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Wed, 16 Aug 2000 14:14:32 +0000 Subject: Revise the wrapper structure for the socket module: socket.py is used for all platforms, and it defines the additional classes and alternate socket() function for Windows and BeOS systems. The plat-*/socket.py files are no longer needed, since there is a shared socket.py. make_fqdn() is provided, but I decided to call it getfqdn() to be consistent with the other names in the socket module. Since it is really a "get" operation and does not create a new name, this is the right name to give it. Move the docstring here from the _socket module. --- Lib/plat-beos/socket.py | 133 --------------------------- Lib/plat-win/socket.py | 168 ---------------------------------- Lib/socket.py | 237 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 237 insertions(+), 301 deletions(-) delete mode 100644 Lib/plat-beos/socket.py delete mode 100755 Lib/plat-win/socket.py create mode 100644 Lib/socket.py diff --git a/Lib/plat-beos/socket.py b/Lib/plat-beos/socket.py deleted file mode 100644 index d3d26ed..0000000 --- a/Lib/plat-beos/socket.py +++ /dev/null @@ -1,133 +0,0 @@ -"Socket wrapper for BeOS, which does not support dup()." - -# (And hence, fromfd() and makefile() are unimplemented in C....) - -# XXX Living dangerously here -- close() is implemented by deleting a -# reference. Thus we rely on the real _socket module to close on -# deallocation, and also hope that nobody keeps a reference to our _sock -# member. - - - -try: - from _socket import * -except ImportError: - from socket import * - -_realsocketcall = socket - - -def socket(family, type, proto=0): - return _socketobject(_realsocketcall(family, type, proto)) - - -class _socketobject: - - def __init__(self, sock): - self._sock = sock - - def close(self): - self._sock = 0 - - def __del__(self): - self.close() - - def accept(self): - sock, addr = self._sock.accept() - return _socketobject(sock), addr - - def dup(self): - return _socketobject(self._sock) - - def makefile(self, mode='r', bufsize=-1): - return _fileobject(self._sock, mode, bufsize) - - _s = "def %s(self, *args): return apply(self._sock.%s, args)\n\n" - for _m in ('bind', 'connect', 'fileno', 'listen', - 'getpeername', 'getsockname', - 'getsockopt', 'setsockopt', - 'recv', 'recvfrom', 'send', 'sendto', - 'setblocking', - 'shutdown'): - exec _s % (_m, _m) - - -class _fileobject: - - def __init__(self, sock, mode, bufsize): - self._sock = sock - self._mode = mode - if bufsize < 0: - bufsize = 512 - self._rbufsize = max(1, bufsize) - self._wbufsize = bufsize - self._wbuf = self._rbuf = "" - - def close(self): - try: - if self._sock: - self.flush() - finally: - self._sock = 0 - - def __del__(self): - self.close() - - def flush(self): - if self._wbuf: - self._sock.send(self._wbuf) - self._wbuf = "" - - def fileno(self): - return self._sock.fileno() - - def write(self, data): - self._wbuf = self._wbuf + data - if self._wbufsize == 1: - if '\n' in data: - self.flush() - else: - if len(self._wbuf) >= self._wbufsize: - self.flush() - - def writelines(self, list): - filter(self._sock.send, list) - self.flush() - - def read(self, n=-1): - if n >= 0: - while len(self._rbuf) < n: - new = self._sock.recv(self._rbufsize) - if not new: break - self._rbuf = self._rbuf + new - data, self._rbuf = self._rbuf[:n], self._rbuf[n:] - return data - while 1: - new = self._sock.recv(self._rbufsize) - if not new: break - self._rbuf = self._rbuf + new - data, self._rbuf = self._rbuf, "" - return data - - def readline(self): - import string - data = "" - i = string.find(self._rbuf, '\n') - while i < 0: - new = self._sock.recv(self._rbufsize) - if not new: break - i = string.find(new, '\n') - if i >= 0: i = i + len(self._rbuf) - self._rbuf = self._rbuf + new - if i < 0: i = len(self._rbuf) - else: i = i+1 - data, self._rbuf = self._rbuf[:i], self._rbuf[i:] - return data - - def readlines(self): - list = [] - while 1: - line = self.readline() - if not line: break - list.append(line) - return list diff --git a/Lib/plat-win/socket.py b/Lib/plat-win/socket.py deleted file mode 100755 index 0410aa7..0000000 --- a/Lib/plat-win/socket.py +++ /dev/null @@ -1,168 +0,0 @@ -"Socket wrapper for Windows, which does not support dup()." - -# (And hence, fromfd() and makefile() are unimplemented in C....) - -# XXX Living dangerously here -- close() is implemented by deleting a -# reference. Thus we rely on the real _socket module to close on -# deallocation, and also hope that nobody keeps a reference to our _sock -# member. - - - -try: - from _socket import * -except ImportError: - from socket import * - -_realsocketcall = socket - - -def socket(family, type, proto=0): - return _socketobject(_realsocketcall(family, type, proto)) - - -class _socketobject: - - def __init__(self, sock): - self._sock = sock - - def close(self): - self._sock = 0 - - def __del__(self): - self.close() - - def accept(self): - sock, addr = self._sock.accept() - return _socketobject(sock), addr - - def dup(self): - return _socketobject(self._sock) - - def makefile(self, mode='r', bufsize=-1): - return _fileobject(self._sock, mode, bufsize) - - _s = "def %s(self, *args): return apply(self._sock.%s, args)\n\n" - for _m in ('bind', 'connect', 'connect_ex', 'fileno', 'listen', - 'getpeername', 'getsockname', - 'getsockopt', 'setsockopt', - 'recv', 'recvfrom', 'send', 'sendto', - 'setblocking', - 'shutdown'): - exec _s % (_m, _m) - - -class _fileobject: - - def __init__(self, sock, mode, bufsize): - self._sock = sock - self._mode = mode - if bufsize < 0: - bufsize = 512 - self._rbufsize = max(1, bufsize) - self._wbufsize = bufsize - self._wbuf = self._rbuf = "" - - def close(self): - try: - if self._sock: - self.flush() - finally: - self._sock = 0 - - def __del__(self): - self.close() - - def flush(self): - if self._wbuf: - self._sock.send(self._wbuf) - self._wbuf = "" - - def fileno(self): - return self._sock.fileno() - - def write(self, data): - self._wbuf = self._wbuf + data - if self._wbufsize == 1: - if '\n' in data: - self.flush() - else: - if len(self._wbuf) >= self._wbufsize: - self.flush() - - def writelines(self, list): - filter(self._sock.send, list) - self.flush() - - def read(self, n=-1): - if n >= 0: - k = len(self._rbuf) - if n <= k: - data = self._rbuf[:n] - self._rbuf = self._rbuf[n:] - return data - n = n - k - l = [self._rbuf] - self._rbuf = "" - while n > 0: - new = self._sock.recv(max(n, self._rbufsize)) - if not new: break - k = len(new) - if k > n: - l.append(new[:n]) - self._rbuf = new[n:] - break - l.append(new) - n = n - k - return "".join(l) - k = max(512, self._rbufsize) - l = [self._rbuf] - self._rbuf = "" - while 1: - new = self._sock.recv(k) - if not new: break - l.append(new) - k = min(k*2, 1024**2) - return "".join(l) - - def readline(self, limit=-1): - data = "" - i = self._rbuf.find('\n') - while i < 0 and not (0 < limit <= len(self._rbuf)): - new = self._sock.recv(self._rbufsize) - if not new: break - i = new.find('\n') - if i >= 0: i = i + len(self._rbuf) - self._rbuf = self._rbuf + new - if i < 0: i = len(self._rbuf) - else: i = i+1 - if 0 <= limit < len(self._rbuf): i = limit - data, self._rbuf = self._rbuf[:i], self._rbuf[i:] - return data - - def readlines(self): - list = [] - while 1: - line = self.readline() - if not line: break - list.append(line) - return list - - -# WSA error codes -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." diff --git a/Lib/socket.py b/Lib/socket.py new file mode 100644 index 0000000..3cc8d91 --- /dev/null +++ b/Lib/socket.py @@ -0,0 +1,237 @@ +# 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: + +socket() -- create a new socket object +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) +ssl() -- secure socket layer support (only available if configured) + + [*] not available on all platforms! + +Special objects: + +SocketType -- type object for socket objects +error -- exception raised for I/O errors + +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. +""" + +from _socket import * + +import os, sys + +if (sys.platform.lower().startswith("win") + or os.uname()[0] == "BeOS"): + + # be sure this happens only once, even in the face of reload(): + try: + _realsocketcall + except NameError: + _realsocketcall = socket + + def socket(family, type, proto=0): + return _socketobject(_realsocketcall(family, type, proto)) + + +# 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." +del os, sys + + +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 + is returned. + """ + name = name.strip() + if len(name) == 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 + + +# +# These classes are used by the socket() defined on Windows and BeOS +# platforms to provide a best-effort implementation of the cleanup +# semantics needed when sockets can't be dup()ed. +# +# These are not actually used on other platforms. +# + +class _socketobject: + + def __init__(self, sock): + self._sock = sock + + def close(self): + self._sock = 0 + + def __del__(self): + self.close() + + def accept(self): + sock, addr = self._sock.accept() + return _socketobject(sock), addr + + def dup(self): + return _socketobject(self._sock) + + def makefile(self, mode='r', bufsize=-1): + return _fileobject(self._sock, mode, bufsize) + + _s = "def %s(self, *args): return apply(self._sock.%s, args)\n\n" + for _m in ('bind', 'connect', 'connect_ex', 'fileno', 'listen', + 'getpeername', 'getsockname', + 'getsockopt', 'setsockopt', + 'recv', 'recvfrom', 'send', 'sendto', + 'setblocking', + 'shutdown'): + exec _s % (_m, _m) + + +class _fileobject: + + def __init__(self, sock, mode, bufsize): + self._sock = sock + self._mode = mode + if bufsize < 0: + bufsize = 512 + self._rbufsize = max(1, bufsize) + self._wbufsize = bufsize + self._wbuf = self._rbuf = "" + + def close(self): + try: + if self._sock: + self.flush() + finally: + self._sock = 0 + + def __del__(self): + self.close() + + def flush(self): + if self._wbuf: + self._sock.send(self._wbuf) + self._wbuf = "" + + def fileno(self): + return self._sock.fileno() + + def write(self, data): + self._wbuf = self._wbuf + data + if self._wbufsize == 1: + if '\n' in data: + self.flush() + else: + if len(self._wbuf) >= self._wbufsize: + self.flush() + + def writelines(self, list): + filter(self._sock.send, list) + self.flush() + + def read(self, n=-1): + if n >= 0: + k = len(self._rbuf) + if n <= k: + data = self._rbuf[:n] + self._rbuf = self._rbuf[n:] + return data + n = n - k + L = [self._rbuf] + self._rbuf = "" + while n > 0: + new = self._sock.recv(max(n, self._rbufsize)) + if not new: break + k = len(new) + if k > n: + L.append(new[:n]) + self._rbuf = new[n:] + break + L.append(new) + n = n - k + return "".join(L) + k = max(512, self._rbufsize) + L = [self._rbuf] + self._rbuf = "" + while 1: + new = self._sock.recv(k) + if not new: break + L.append(new) + k = min(k*2, 1024**2) + return "".join(L) + + def readline(self, limit=-1): + data = "" + i = self._rbuf.find('\n') + while i < 0 and not (0 < limit <= len(self._rbuf)): + new = self._sock.recv(self._rbufsize) + if not new: break + i = new.find('\n') + if i >= 0: i = i + len(self._rbuf) + self._rbuf = self._rbuf + new + if i < 0: i = len(self._rbuf) + else: i = i+1 + if 0 <= limit < len(self._rbuf): i = limit + data, self._rbuf = self._rbuf[:i], self._rbuf[i:] + return data + + def readlines(self): + list = [] + while 1: + line = self.readline() + if not line: break + list.append(line) + return list -- cgit v0.12