~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/internet/tcp.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20070117145235-btmig6qfmqfen0om
Tags: 2.5.0-0ubuntu1
New upstream version, compatible with python2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import select
23
23
import operator
24
24
import warnings
 
25
 
25
26
try:
26
27
    import fcntl
27
28
except ImportError:
35
36
 
36
37
from twisted.python.runtime import platform, platformType
37
38
 
 
39
 
38
40
if platformType == 'win32':
39
 
     # no such thing as WSAEPERM or error code 10001 according to winsock.h or MSDN
40
 
    EPERM=object()
 
41
    # no such thing as WSAEPERM or error code 10001 according to winsock.h or MSDN
 
42
    EPERM = object()
41
43
    from errno import WSAEINVAL as EINVAL
42
44
    from errno import WSAEWOULDBLOCK as EWOULDBLOCK
43
45
    from errno import WSAEINPROGRESS as EINPROGRESS
47
49
    from errno import WSAENOTCONN as ENOTCONN
48
50
    from errno import WSAEINTR as EINTR
49
51
    from errno import WSAENOBUFS as ENOBUFS
50
 
    EAGAIN=EWOULDBLOCK
 
52
    from errno import WSAEMFILE as EMFILE
 
53
    # No such thing as WSAENFILE, either.
 
54
    ENFILE = object()
 
55
    # Nor ENOMEM
 
56
    ENOMEM = object()
 
57
    EAGAIN = EWOULDBLOCK
 
58
    from errno import WSAECONNRESET as ECONNABORTED
51
59
else:
52
60
    from errno import EPERM
53
61
    from errno import EINVAL
59
67
    from errno import ENOTCONN
60
68
    from errno import EINTR
61
69
    from errno import ENOBUFS
 
70
    from errno import EMFILE
 
71
    from errno import ENFILE
 
72
    from errno import ENOMEM
62
73
    from errno import EAGAIN
 
74
    from errno import ECONNABORTED
 
75
 
 
76
from errno import errorcode
63
77
 
64
78
# Twisted Imports
65
79
from twisted.internet import protocol, defer, base, address
66
80
from twisted.persisted import styles
67
 
from twisted.python import log, failure, reflect, components
 
81
from twisted.python import log, failure, reflect
68
82
from twisted.python.util import unsignedID
69
83
from twisted.internet.error import CannotListenError
70
84
 
453
467
        self.failIfNotConnected(error.UserError())
454
468
 
455
469
    def failIfNotConnected(self, err):
 
470
        """
 
471
        Generic method called when the attemps to connect failed. It basically
 
472
        cleans everything it can: call connectionFailed, stop read and write,
 
473
        delete socket related members.
 
474
        """
456
475
        if (self.connected or self.disconnected or 
457
476
            not hasattr(self, "connector")):
458
477
            return
459
478
        
460
 
        try:
461
 
            self._closeSocket()
462
 
        except AttributeError:
463
 
            pass
464
 
        else:
465
 
            del self.socket, self.fileno
466
 
 
467
479
        self.connector.connectionFailed(failure.Failure(err))
468
480
        if hasattr(self, "reactor"):
469
481
            # this doesn't happen if we failed in __init__
471
483
            self.stopWriting()
472
484
            del self.connector
473
485
 
 
486
        try:
 
487
            self._closeSocket()
 
488
        except AttributeError:
 
489
            pass
 
490
        else:
 
491
            del self.socket, self.fileno
 
492
 
474
493
    def createInternetSocket(self):
475
494
        """(internal) Create a non-blocking socket using
476
495
        self.addressFamily, self.socketType.
482
501
            fcntl.fcntl(s.fileno(), fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
483
502
        return s
484
503
 
485
 
 
486
504
    def resolveAddress(self):
487
505
        if abstract.isIPAddress(self.addr[0]):
488
506
            self._setRealAddress(self.addr[0])
504
522
            # was scheduled via a callLater in self._finishInit
505
523
            return
506
524
 
507
 
        # on windows failed connects are reported on exception
508
 
        # list, not write or read list.
509
 
        if platformType == "win32" or sys.platform == "cygwin":
510
 
            r, w, e = select.select([], [], [self.fileno()], 0.0)
511
 
            if e:
512
 
                err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
513
 
                self.failIfNotConnected(error.getConnectError((err, os.strerror(err))))
514
 
                return
515
 
 
 
525
        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
 
526
        if err:
 
527
            self.failIfNotConnected(error.getConnectError((err, os.strerror(err))))
 
528
            return
 
529
 
 
530
 
 
531
        # doConnect gets called twice.  The first time we actually need to
 
532
        # start the connection attempt.  The second time we don't really
 
533
        # want to (SO_ERROR above will have taken care of any errors, and if
 
534
        # it reported none, the mere fact that doConnect was called again is
 
535
        # sufficient to indicate that the connection has succeeded), but it
 
536
        # is not /particularly/ detrimental to do so.  This should get
 
537
        # cleaned up some day, though.
516
538
        try:
517
539
            connectResult = self.socket.connect_ex(self.realAddress)
518
540
        except socket.error, se:
755
777
                        self.numberAccepts = i
756
778
                        break
757
779
                    elif e.args[0] == EPERM:
 
780
                        # Netfilter on Linux may have rejected the
 
781
                        # connection, but we get told to try to accept()
 
782
                        # anyway.
758
783
                        continue
 
784
                    elif e.args[0] in (EMFILE, ENOBUFS, ENFILE, ENOMEM, ECONNABORTED):
 
785
 
 
786
                        # Linux gives EMFILE when a process is not allowed
 
787
                        # to allocate any more file descriptors.  *BSD and
 
788
                        # Win32 give (WSA)ENOBUFS.  Linux can also give
 
789
                        # ENFILE if the system is out of inodes, or ENOMEM
 
790
                        # if there is insufficient memory to allocate a new
 
791
                        # dentry.  ECONNABORTED is documented as possible on
 
792
                        # both Linux and Windows, but it is not clear
 
793
                        # whether there are actually any circumstances under
 
794
                        # which it can happen (one might expect it to be
 
795
                        # possible if a client sends a FIN or RST after the
 
796
                        # server sends a SYN|ACK but before application code
 
797
                        # calls accept(2), however at least on Linux this
 
798
                        # _seems_ to be short-circuited by syncookies.
 
799
 
 
800
                        log.msg("Could not accept new connection (%s)" % (
 
801
                            errorcode[e.args[0]],))
 
802
                        break
759
803
                    raise
760
804
 
761
805
                protocol = self.factory.buildProtocol(self._buildAddr(addr))