Merged release21-maint changes.
[python/dscho.git] / Lib / socket.py
blobd0f09111a9e6a35b3aab6bf3e08d2f3a5dbb9936
1 # Wrapper module for _socket, providing some additional facilities
2 # implemented in Python.
4 """\
5 This module provides socket operations and some related functions.
6 On Unix, it supports IP (Internet Protocol) and Unix domain sockets.
7 On other systems, it only supports IP. Functions specific for a
8 socket are available as methods of the socket object.
10 Functions:
12 socket() -- create a new socket object
13 fromfd() -- create a socket object from an open file descriptor [*]
14 gethostname() -- return the current hostname
15 gethostbyname() -- map a hostname to its IP number
16 gethostbyaddr() -- map an IP number or hostname to DNS info
17 getservbyname() -- map a service name and a protocol name to a port number
18 getprotobyname() -- mape a protocol name (e.g. 'tcp') to a number
19 ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
20 htons(), htonl() -- convert 16, 32 bit int from host to network byte order
21 inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
22 inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
23 ssl() -- secure socket layer support (only available if configured)
25 [*] not available on all platforms!
27 Special objects:
29 SocketType -- type object for socket objects
30 error -- exception raised for I/O errors
32 Integer constants:
34 AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
35 SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
37 Many other constants may be defined; these may be used in calls to
38 the setsockopt() and getsockopt() methods.
39 """
41 from _socket import *
43 import os, sys
45 __all__ = ["getfqdn"]
46 import _socket
47 __all__.extend(os._get_exports_list(_socket))
49 if (sys.platform.lower().startswith("win")
50 or (hasattr(os, 'uname') and os.uname()[0] == "BeOS")
51 or (sys.platform=="RISCOS")):
53 _realsocketcall = _socket.socket
55 def socket(family, type, proto=0):
56 return _socketobject(_realsocketcall(family, type, proto))
58 try:
59 _realsslcall = _socket.ssl
60 except AttributeError:
61 pass # No ssl
62 else:
63 def ssl(sock, keyfile=None, certfile=None):
64 if hasattr(sock, "_sock"):
65 sock = sock._sock
66 return _realsslcall(sock, keyfile, certfile)
69 # WSA error codes
70 if sys.platform.lower().startswith("win"):
71 errorTab = {}
72 errorTab[10004] = "The operation was interrupted."
73 errorTab[10009] = "A bad file handle was passed."
74 errorTab[10013] = "Permission denied."
75 errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
76 errorTab[10022] = "An invalid operation was attempted."
77 errorTab[10035] = "The socket operation would block"
78 errorTab[10036] = "A blocking operation is already in progress."
79 errorTab[10048] = "The network address is in use."
80 errorTab[10054] = "The connection has been reset."
81 errorTab[10058] = "The network has been shut down."
82 errorTab[10060] = "The operation timed out."
83 errorTab[10061] = "Connection refused."
84 errorTab[10063] = "The name is too long."
85 errorTab[10064] = "The host is down."
86 errorTab[10065] = "The host is unreachable."
87 __all__.append("errorTab")
88 del os, sys
91 def getfqdn(name=''):
92 """Get fully qualified domain name from name.
94 An empty argument is interpreted as meaning the local host.
96 First the hostname returned by gethostbyaddr() is checked, then
97 possibly existing aliases. In case no FQDN is available, hostname
98 is returned.
99 """
100 name = name.strip()
101 if not name or name == '0.0.0.0':
102 name = gethostname()
103 try:
104 hostname, aliases, ipaddrs = gethostbyaddr(name)
105 except error:
106 pass
107 else:
108 aliases.insert(0, hostname)
109 for name in aliases:
110 if '.' in name:
111 break
112 else:
113 name = hostname
114 return name
118 # These classes are used by the socket() defined on Windows and BeOS
119 # platforms to provide a best-effort implementation of the cleanup
120 # semantics needed when sockets can't be dup()ed.
122 # These are not actually used on other platforms.
125 class _socketobject:
127 def __init__(self, sock):
128 self._sock = sock
130 def close(self):
131 self._sock = 0
133 def __del__(self):
134 self.close()
136 def accept(self):
137 sock, addr = self._sock.accept()
138 return _socketobject(sock), addr
140 def dup(self):
141 return _socketobject(self._sock)
143 def makefile(self, mode='r', bufsize=-1):
144 return _fileobject(self._sock, mode, bufsize)
146 _s = "def %s(self, *args): return apply(self._sock.%s, args)\n\n"
147 for _m in ('bind', 'connect', 'connect_ex', 'fileno', 'listen',
148 'getpeername', 'getsockname',
149 'getsockopt', 'setsockopt',
150 'recv', 'recvfrom', 'send', 'sendto',
151 'setblocking',
152 'shutdown'):
153 exec _s % (_m, _m)
156 class _fileobject:
158 def __init__(self, sock, mode, bufsize):
159 self._sock = sock
160 self._mode = mode
161 if bufsize < 0:
162 bufsize = 512
163 self._rbufsize = max(1, bufsize)
164 self._wbufsize = bufsize
165 self._wbuf = self._rbuf = ""
167 def close(self):
168 try:
169 if self._sock:
170 self.flush()
171 finally:
172 self._sock = 0
174 def __del__(self):
175 self.close()
177 def flush(self):
178 if self._wbuf:
179 self._sock.send(self._wbuf)
180 self._wbuf = ""
182 def fileno(self):
183 return self._sock.fileno()
185 def write(self, data):
186 self._wbuf = self._wbuf + data
187 if self._wbufsize == 1:
188 if '\n' in data:
189 self.flush()
190 else:
191 if len(self._wbuf) >= self._wbufsize:
192 self.flush()
194 def writelines(self, list):
195 filter(self._sock.send, list)
196 self.flush()
198 def read(self, n=-1):
199 if n >= 0:
200 k = len(self._rbuf)
201 if n <= k:
202 data = self._rbuf[:n]
203 self._rbuf = self._rbuf[n:]
204 return data
205 n = n - k
206 L = [self._rbuf]
207 self._rbuf = ""
208 while n > 0:
209 new = self._sock.recv(max(n, self._rbufsize))
210 if not new: break
211 k = len(new)
212 if k > n:
213 L.append(new[:n])
214 self._rbuf = new[n:]
215 break
216 L.append(new)
217 n = n - k
218 return "".join(L)
219 k = max(512, self._rbufsize)
220 L = [self._rbuf]
221 self._rbuf = ""
222 while 1:
223 new = self._sock.recv(k)
224 if not new: break
225 L.append(new)
226 k = min(k*2, 1024**2)
227 return "".join(L)
229 def readline(self, limit=-1):
230 data = ""
231 i = self._rbuf.find('\n')
232 while i < 0 and not (0 < limit <= len(self._rbuf)):
233 new = self._sock.recv(self._rbufsize)
234 if not new: break
235 i = new.find('\n')
236 if i >= 0: i = i + len(self._rbuf)
237 self._rbuf = self._rbuf + new
238 if i < 0: i = len(self._rbuf)
239 else: i = i+1
240 if 0 <= limit < len(self._rbuf): i = limit
241 data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
242 return data
244 def readlines(self, sizehint = 0):
245 total = 0
246 list = []
247 while 1:
248 line = self.readline()
249 if not line: break
250 list.append(line)
251 total += len(line)
252 if sizehint and total >= sizehint:
253 break
254 return list