Changeset 388 for python/vendor/current/Lib/socket.py
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Lib/socket.py
r2 r388 25 25 socket.getdefaulttimeout() -- get the default timeout value 26 26 socket.setdefaulttimeout() -- set the default timeout value 27 create_connection() -- connects to an address, with an optional timeout 27 create_connection() -- connects to an address, with an optional timeout and 28 optional source address. 28 29 29 30 [*] not available on all platforms! … … 46 47 import _socket 47 48 from _socket import * 49 from functools import partial 50 from types import MethodType 48 51 49 52 try: … … 85 88 86 89 try: 87 from errno import EBADF90 import errno 88 91 except ImportError: 89 EBADF = 9 92 errno = None 93 EBADF = getattr(errno, 'EBADF', 9) 94 EINTR = getattr(errno, 'EINTR', 4) 90 95 91 96 __all__ = ["getfqdn", "create_connection"] … … 185 190 setattr(self, method, getattr(_sock, method)) 186 191 187 def close(self): 192 def close(self, _closedsocket=_closedsocket, 193 _delegate_methods=_delegate_methods, setattr=setattr): 194 # This function should not reference any globals. See issue #808164. 188 195 self._sock = _closedsocket() 189 196 dummy = self._sock._dummy … … 214 221 proto = property(lambda self: self._sock.proto, doc="the socket protocol") 215 222 216 _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n" 217 "%s.__doc__ = _realsocket.%s.__doc__\n") 218 for _m in _socketmethods: 219 exec _s % (_m, _m, _m, _m) 220 del _m, _s 223 def meth(name,self,*args): 224 return getattr(self._sock,name)(*args) 225 226 for _m in _socketmethods: 227 p = partial(meth,_m) 228 p.__name__ = _m 229 p.__doc__ = getattr(_realsocket,_m).__doc__ 230 m = MethodType(p,None,_socketobject) 231 setattr(_socketobject,_m,m) 221 232 222 233 socket = SocketType = _socketobject … … 281 292 def flush(self): 282 293 if self._wbuf: 283 buffer= "".join(self._wbuf)294 data = "".join(self._wbuf) 284 295 self._wbuf = [] 285 296 self._wbuf_len = 0 286 self._sock.sendall(buffer) 297 buffer_size = max(self._rbufsize, self.default_bufsize) 298 data_size = len(data) 299 write_offset = 0 300 view = memoryview(data) 301 try: 302 while write_offset < data_size: 303 self._sock.sendall(view[write_offset:write_offset+buffer_size]) 304 write_offset += buffer_size 305 finally: 306 if write_offset < data_size: 307 remainder = data[write_offset:] 308 del view, data # explicit free 309 self._wbuf.append(remainder) 310 self._wbuf_len = len(remainder) 287 311 288 312 def fileno(self): … … 296 320 self._wbuf_len += len(data) 297 321 if (self._wbufsize == 0 or 298 self._wbufsize == 1 and '\n' in dataor299 self._wbuf_len >= self._wbufsize):322 (self._wbufsize == 1 and '\n' in data) or 323 (self._wbufsize > 1 and self._wbuf_len >= self._wbufsize)): 300 324 self.flush() 301 325 … … 309 333 self._wbuf_len >= self._wbufsize): 310 334 self.flush() 311 312 def _get_wbuf_len(self):313 return self._wbuf_len314 335 315 336 def read(self, size=-1): … … 327 348 self._rbuf = StringIO() # reset _rbuf. we consume it via buf. 328 349 while True: 329 data = self._sock.recv(rbufsize) 350 try: 351 data = self._sock.recv(rbufsize) 352 except error, e: 353 if e.args[0] == EINTR: 354 continue 355 raise 330 356 if not data: 331 357 break … … 351 377 # as we copy it into a StringIO and free it. This avoids 352 378 # fragmentation issues on many platforms. 353 data = self._sock.recv(left) 379 try: 380 data = self._sock.recv(left) 381 except error, e: 382 if e.args[0] == EINTR: 383 continue 384 raise 354 385 if not data: 355 386 break … … 394 425 data = None 395 426 recv = self._sock.recv 396 while data != "\n": 397 data = recv(1) 398 if not data: 399 break 400 buffers.append(data) 427 while True: 428 try: 429 while data != "\n": 430 data = recv(1) 431 if not data: 432 break 433 buffers.append(data) 434 except error, e: 435 # The try..except to catch EINTR was moved outside the 436 # recv loop to avoid the per byte overhead. 437 if e.args[0] == EINTR: 438 continue 439 raise 440 break 401 441 return "".join(buffers) 402 442 … … 404 444 self._rbuf = StringIO() # reset _rbuf. we consume it via buf. 405 445 while True: 406 data = self._sock.recv(self._rbufsize) 446 try: 447 data = self._sock.recv(self._rbufsize) 448 except error, e: 449 if e.args[0] == EINTR: 450 continue 451 raise 407 452 if not data: 408 453 break … … 428 473 self._rbuf = StringIO() # reset _rbuf. we consume it via buf. 429 474 while True: 430 data = self._sock.recv(self._rbufsize) 475 try: 476 data = self._sock.recv(self._rbufsize) 477 except error, e: 478 if e.args[0] == EINTR: 479 continue 480 raise 431 481 if not data: 432 482 break … … 485 535 _GLOBAL_DEFAULT_TIMEOUT = object() 486 536 487 def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT): 537 def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, 538 source_address=None): 488 539 """Connect to *address* and return the socket object. 489 540 … … 493 544 before attempting to connect. If no *timeout* is supplied, the 494 545 global default timeout setting returned by :func:`getdefaulttimeout` 495 is used. 546 is used. If *source_address* is set it must be a tuple of (host, port) 547 for the socket to bind as a source address before making the connection. 548 An host of '' or port 0 tells the OS to use the default. 496 549 """ 497 550 498 msg = "getaddrinfo returns an empty list"499 551 host, port = address 552 err = None 500 553 for res in getaddrinfo(host, port, 0, SOCK_STREAM): 501 554 af, socktype, proto, canonname, sa = res … … 505 558 if timeout is not _GLOBAL_DEFAULT_TIMEOUT: 506 559 sock.settimeout(timeout) 560 if source_address: 561 sock.bind(source_address) 507 562 sock.connect(sa) 508 563 return sock 509 564 510 except error, msg: 565 except error as _: 566 err = _ 511 567 if sock is not None: 512 568 sock.close() 513 569 514 raise error, msg 570 if err is not None: 571 raise err 572 else: 573 raise error("getaddrinfo returns an empty list")
Note:
See TracChangeset
for help on using the changeset viewer.