Change to flush and close logic to fix #1760556.
[python.git] / Lib / socket.py
blob30be5c5324c37c197a9201ebe24b325c157b26e2
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 socketpair() -- create a pair of new socket objects [*]
14 fromfd() -- create a socket object from an open file descriptor [*]
15 gethostname() -- return the current hostname
16 gethostbyname() -- map a hostname to its IP number
17 gethostbyaddr() -- map an IP number or hostname to DNS info
18 getservbyname() -- map a service name and a protocol name to a port number
19 getprotobyname() -- mape a protocol name (e.g. 'tcp') to a number
20 ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
21 htons(), htonl() -- convert 16, 32 bit int from host to network byte order
22 inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
23 inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
24 ssl() -- secure socket layer support (only available if configured)
25 socket.getdefaulttimeout() -- get the default timeout value
26 socket.setdefaulttimeout() -- set the default timeout value
27 create_connection() -- connects to an address, with an optional timeout
29 [*] not available on all platforms!
31 Special objects:
33 SocketType -- type object for socket objects
34 error -- exception raised for I/O errors
35 has_ipv6 -- boolean value indicating if IPv6 is supported
37 Integer constants:
39 AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
40 SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
42 Many other constants may be defined; these may be used in calls to
43 the setsockopt() and getsockopt() methods.
44 """
46 import _socket
47 from _socket import *
49 try:
50 import _ssl
51 except ImportError:
52 # no SSL support
53 pass
54 else:
55 def ssl(sock, keyfile=None, certfile=None):
56 # we do an internal import here because the ssl
57 # module imports the socket module
58 import ssl as _realssl
59 warnings.warn("socket.ssl() is deprecated. Use ssl.wrap_socket() instead.",
60 DeprecationWarning, stacklevel=2)
61 return _realssl.sslwrap_simple(sock, keyfile, certfile)
63 # we need to import the same constants we used to...
64 from _ssl import SSLError as sslerror
65 from _ssl import \
66 RAND_add, \
67 RAND_egd, \
68 RAND_status, \
69 SSL_ERROR_ZERO_RETURN, \
70 SSL_ERROR_WANT_READ, \
71 SSL_ERROR_WANT_WRITE, \
72 SSL_ERROR_WANT_X509_LOOKUP, \
73 SSL_ERROR_SYSCALL, \
74 SSL_ERROR_SSL, \
75 SSL_ERROR_WANT_CONNECT, \
76 SSL_ERROR_EOF, \
77 SSL_ERROR_INVALID_ERROR_CODE
79 import os, sys, warnings
81 try:
82 from errno import EBADF
83 except ImportError:
84 EBADF = 9
86 __all__ = ["getfqdn"]
87 __all__.extend(os._get_exports_list(_socket))
90 _realsocket = socket
92 # WSA error codes
93 if sys.platform.lower().startswith("win"):
94 errorTab = {}
95 errorTab[10004] = "The operation was interrupted."
96 errorTab[10009] = "A bad file handle was passed."
97 errorTab[10013] = "Permission denied."
98 errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
99 errorTab[10022] = "An invalid operation was attempted."
100 errorTab[10035] = "The socket operation would block"
101 errorTab[10036] = "A blocking operation is already in progress."
102 errorTab[10048] = "The network address is in use."
103 errorTab[10054] = "The connection has been reset."
104 errorTab[10058] = "The network has been shut down."
105 errorTab[10060] = "The operation timed out."
106 errorTab[10061] = "Connection refused."
107 errorTab[10063] = "The name is too long."
108 errorTab[10064] = "The host is down."
109 errorTab[10065] = "The host is unreachable."
110 __all__.append("errorTab")
114 def getfqdn(name=''):
115 """Get fully qualified domain name from name.
117 An empty argument is interpreted as meaning the local host.
119 First the hostname returned by gethostbyaddr() is checked, then
120 possibly existing aliases. In case no FQDN is available, hostname
121 from gethostname() is returned.
123 name = name.strip()
124 if not name or name == '0.0.0.0':
125 name = gethostname()
126 try:
127 hostname, aliases, ipaddrs = gethostbyaddr(name)
128 except error:
129 pass
130 else:
131 aliases.insert(0, hostname)
132 for name in aliases:
133 if '.' in name:
134 break
135 else:
136 name = hostname
137 return name
140 _socketmethods = (
141 'bind', 'connect', 'connect_ex', 'fileno', 'listen',
142 'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
143 'sendall', 'setblocking',
144 'settimeout', 'gettimeout', 'shutdown')
146 if sys.platform == "riscos":
147 _socketmethods = _socketmethods + ('sleeptaskw',)
149 # All the method names that must be delegated to either the real socket
150 # object or the _closedsocket object.
151 _delegate_methods = ("recv", "recvfrom", "recv_into", "recvfrom_into",
152 "send", "sendto")
154 class _closedsocket(object):
155 __slots__ = []
156 def _dummy(*args):
157 raise error(EBADF, 'Bad file descriptor')
158 # All _delegate_methods must also be initialized here.
159 send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
160 __getattr__ = _dummy
162 # Wrapper around platform socket objects. This implements
163 # a platform-independent dup() functionality. The
164 # implementation currently relies on reference counting
165 # to close the underlying socket object.
166 class _socketobject(object):
168 __doc__ = _realsocket.__doc__
170 __slots__ = ["_sock", "__weakref__"] + list(_delegate_methods)
172 def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
173 if _sock is None:
174 _sock = _realsocket(family, type, proto)
175 self._sock = _sock
176 for method in _delegate_methods:
177 setattr(self, method, getattr(_sock, method))
179 def close(self):
180 self._sock = _closedsocket()
181 dummy = self._sock._dummy
182 for method in _delegate_methods:
183 setattr(self, method, dummy)
184 close.__doc__ = _realsocket.close.__doc__
186 def accept(self):
187 sock, addr = self._sock.accept()
188 return _socketobject(_sock=sock), addr
189 accept.__doc__ = _realsocket.accept.__doc__
191 def dup(self):
192 """dup() -> socket object
194 Return a new socket object connected to the same system resource."""
195 return _socketobject(_sock=self._sock)
197 def makefile(self, mode='r', bufsize=-1):
198 """makefile([mode[, bufsize]]) -> file object
200 Return a regular file object corresponding to the socket. The mode
201 and bufsize arguments are as for the built-in open() function."""
202 return _fileobject(self._sock, mode, bufsize)
204 family = property(lambda self: self._sock.family, doc="the socket family")
205 type = property(lambda self: self._sock.type, doc="the socket type")
206 proto = property(lambda self: self._sock.proto, doc="the socket protocol")
208 _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n"
209 "%s.__doc__ = _realsocket.%s.__doc__\n")
210 for _m in _socketmethods:
211 exec _s % (_m, _m, _m, _m)
212 del _m, _s
214 socket = SocketType = _socketobject
216 class _fileobject(object):
217 """Faux file object attached to a socket object."""
219 default_bufsize = 8192
220 name = "<socket>"
222 __slots__ = ["mode", "bufsize", "softspace",
223 # "closed" is a property, see below
224 "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf",
225 "_close"]
227 def __init__(self, sock, mode='rb', bufsize=-1, close=False):
228 self._sock = sock
229 self.mode = mode # Not actually used in this version
230 if bufsize < 0:
231 bufsize = self.default_bufsize
232 self.bufsize = bufsize
233 self.softspace = False
234 if bufsize == 0:
235 self._rbufsize = 1
236 elif bufsize == 1:
237 self._rbufsize = self.default_bufsize
238 else:
239 self._rbufsize = bufsize
240 self._wbufsize = bufsize
241 self._rbuf = "" # A string
242 self._wbuf = [] # A list of strings
243 self._close = close
245 def _getclosed(self):
246 return self._sock is None
247 closed = property(_getclosed, doc="True if the file is closed")
249 def close(self):
250 try:
251 if self._sock:
252 self.flush()
253 finally:
254 if self._close:
255 self._sock.close()
256 self._sock = None
258 def __del__(self):
259 try:
260 self.close()
261 except:
262 # close() may fail if __init__ didn't complete
263 pass
265 def flush(self):
266 if self._wbuf:
267 buffer = "".join(self._wbuf)
268 self._wbuf = []
269 self._sock.sendall(buffer)
271 def fileno(self):
272 return self._sock.fileno()
274 def write(self, data):
275 data = str(data) # XXX Should really reject non-string non-buffers
276 if not data:
277 return
278 self._wbuf.append(data)
279 if (self._wbufsize == 0 or
280 self._wbufsize == 1 and '\n' in data or
281 self._get_wbuf_len() >= self._wbufsize):
282 self.flush()
284 def writelines(self, list):
285 # XXX We could do better here for very long lists
286 # XXX Should really reject non-string non-buffers
287 self._wbuf.extend(filter(None, map(str, list)))
288 if (self._wbufsize <= 1 or
289 self._get_wbuf_len() >= self._wbufsize):
290 self.flush()
292 def _get_wbuf_len(self):
293 buf_len = 0
294 for x in self._wbuf:
295 buf_len += len(x)
296 return buf_len
298 def read(self, size=-1):
299 data = self._rbuf
300 if size < 0:
301 # Read until EOF
302 buffers = []
303 if data:
304 buffers.append(data)
305 self._rbuf = ""
306 if self._rbufsize <= 1:
307 recv_size = self.default_bufsize
308 else:
309 recv_size = self._rbufsize
310 while True:
311 data = self._sock.recv(recv_size)
312 if not data:
313 break
314 buffers.append(data)
315 return "".join(buffers)
316 else:
317 # Read until size bytes or EOF seen, whichever comes first
318 buf_len = len(data)
319 if buf_len >= size:
320 self._rbuf = data[size:]
321 return data[:size]
322 buffers = []
323 if data:
324 buffers.append(data)
325 self._rbuf = ""
326 while True:
327 left = size - buf_len
328 recv_size = max(self._rbufsize, left)
329 data = self._sock.recv(recv_size)
330 if not data:
331 break
332 buffers.append(data)
333 n = len(data)
334 if n >= left:
335 self._rbuf = data[left:]
336 buffers[-1] = data[:left]
337 break
338 buf_len += n
339 return "".join(buffers)
341 def readline(self, size=-1):
342 data = self._rbuf
343 if size < 0:
344 # Read until \n or EOF, whichever comes first
345 if self._rbufsize <= 1:
346 # Speed up unbuffered case
347 assert data == ""
348 buffers = []
349 recv = self._sock.recv
350 while data != "\n":
351 data = recv(1)
352 if not data:
353 break
354 buffers.append(data)
355 return "".join(buffers)
356 nl = data.find('\n')
357 if nl >= 0:
358 nl += 1
359 self._rbuf = data[nl:]
360 return data[:nl]
361 buffers = []
362 if data:
363 buffers.append(data)
364 self._rbuf = ""
365 while True:
366 data = self._sock.recv(self._rbufsize)
367 if not data:
368 break
369 buffers.append(data)
370 nl = data.find('\n')
371 if nl >= 0:
372 nl += 1
373 self._rbuf = data[nl:]
374 buffers[-1] = data[:nl]
375 break
376 return "".join(buffers)
377 else:
378 # Read until size bytes or \n or EOF seen, whichever comes first
379 nl = data.find('\n', 0, size)
380 if nl >= 0:
381 nl += 1
382 self._rbuf = data[nl:]
383 return data[:nl]
384 buf_len = len(data)
385 if buf_len >= size:
386 self._rbuf = data[size:]
387 return data[:size]
388 buffers = []
389 if data:
390 buffers.append(data)
391 self._rbuf = ""
392 while True:
393 data = self._sock.recv(self._rbufsize)
394 if not data:
395 break
396 buffers.append(data)
397 left = size - buf_len
398 nl = data.find('\n', 0, left)
399 if nl >= 0:
400 nl += 1
401 self._rbuf = data[nl:]
402 buffers[-1] = data[:nl]
403 break
404 n = len(data)
405 if n >= left:
406 self._rbuf = data[left:]
407 buffers[-1] = data[:left]
408 break
409 buf_len += n
410 return "".join(buffers)
412 def readlines(self, sizehint=0):
413 total = 0
414 list = []
415 while True:
416 line = self.readline()
417 if not line:
418 break
419 list.append(line)
420 total += len(line)
421 if sizehint and total >= sizehint:
422 break
423 return list
425 # Iterator protocols
427 def __iter__(self):
428 return self
430 def next(self):
431 line = self.readline()
432 if not line:
433 raise StopIteration
434 return line
437 def create_connection(address, timeout=None):
438 """Connect to address (host, port) with an optional timeout.
440 Provides access to socketobject timeout for higher-level
441 protocols. Passing a timeout will set the timeout on the
442 socket instance (if not present, or passed as None, the
443 default global timeout setting will be used).
446 msg = "getaddrinfo returns an empty list"
447 host, port = address
448 for res in getaddrinfo(host, port, 0, SOCK_STREAM):
449 af, socktype, proto, canonname, sa = res
450 sock = None
451 try:
452 sock = socket(af, socktype, proto)
453 if timeout is not None:
454 sock.settimeout(timeout)
455 sock.connect(sa)
456 return sock
458 except error, msg:
459 if sock is not None:
460 sock.close()
462 raise error, msg