~cbehrens/nova/lp844160-build-works-with-zones

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/internet/_posixstdio.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.test.test_stdio -*-
 
2
 
 
3
"""Standard input/out/err support.
 
4
 
 
5
Future Plans::
 
6
 
 
7
    support for stderr, perhaps
 
8
    Rewrite to use the reactor instead of an ad-hoc mechanism for connecting
 
9
        protocols to transport.
 
10
 
 
11
Maintainer: James Y Knight
 
12
"""
 
13
 
 
14
import warnings
 
15
from zope.interface import implements
 
16
 
 
17
from twisted.internet import process, error, interfaces
 
18
from twisted.python import log, failure
 
19
 
 
20
 
 
21
class PipeAddress(object):
 
22
    implements(interfaces.IAddress)
 
23
 
 
24
 
 
25
class StandardIO(object):
 
26
    implements(interfaces.ITransport, interfaces.IProducer, interfaces.IConsumer, interfaces.IHalfCloseableDescriptor)
 
27
    _reader = None
 
28
    _writer = None
 
29
    disconnected = False
 
30
    disconnecting = False
 
31
 
 
32
    def __init__(self, proto, stdin=0, stdout=1):
 
33
        from twisted.internet import reactor
 
34
        self.protocol = proto
 
35
 
 
36
        self._reader=process.ProcessReader(reactor, self, 'read', stdin)
 
37
        self._reader.startReading()
 
38
        self._writer=process.ProcessWriter(reactor, self, 'write', stdout)
 
39
        self._writer.startReading()
 
40
        self.protocol.makeConnection(self)
 
41
 
 
42
    # ITransport
 
43
 
 
44
    # XXX Actually, see #3597.
 
45
    def loseWriteConnection(self):
 
46
        if self._writer is not None:
 
47
            self._writer.loseConnection()
 
48
 
 
49
    def write(self, data):
 
50
        if self._writer is not None:
 
51
            self._writer.write(data)
 
52
 
 
53
    def writeSequence(self, data):
 
54
        if self._writer is not None:
 
55
            self._writer.writeSequence(data)
 
56
 
 
57
    def loseConnection(self):
 
58
        self.disconnecting = True
 
59
 
 
60
        if self._writer is not None:
 
61
            self._writer.loseConnection()
 
62
        if self._reader is not None:
 
63
            # Don't loseConnection, because we don't want to SIGPIPE it.
 
64
            self._reader.stopReading()
 
65
 
 
66
    def getPeer(self):
 
67
        return PipeAddress()
 
68
 
 
69
    def getHost(self):
 
70
        return PipeAddress()
 
71
 
 
72
 
 
73
    # Callbacks from process.ProcessReader/ProcessWriter
 
74
    def childDataReceived(self, fd, data):
 
75
        self.protocol.dataReceived(data)
 
76
 
 
77
    def childConnectionLost(self, fd, reason):
 
78
        if self.disconnected:
 
79
            return
 
80
 
 
81
        if reason.value.__class__ == error.ConnectionDone:
 
82
            # Normal close
 
83
            if fd == 'read':
 
84
                self._readConnectionLost(reason)
 
85
            else:
 
86
                self._writeConnectionLost(reason)
 
87
        else:
 
88
            self.connectionLost(reason)
 
89
 
 
90
    def connectionLost(self, reason):
 
91
        self.disconnected = True
 
92
 
 
93
        # Make sure to cleanup the other half
 
94
        _reader = self._reader
 
95
        _writer = self._writer
 
96
        protocol = self.protocol
 
97
        self._reader = self._writer = None
 
98
        self.protocol = None
 
99
 
 
100
        if _writer is not None and not _writer.disconnected:
 
101
            _writer.connectionLost(reason)
 
102
 
 
103
        if _reader is not None and not _reader.disconnected:
 
104
            _reader.connectionLost(reason)
 
105
 
 
106
        try:
 
107
            protocol.connectionLost(reason)
 
108
        except:
 
109
            log.err()
 
110
 
 
111
    def _writeConnectionLost(self, reason):
 
112
        self._writer=None
 
113
        if self.disconnecting:
 
114
            self.connectionLost(reason)
 
115
            return
 
116
 
 
117
        p = interfaces.IHalfCloseableProtocol(self.protocol, None)
 
118
        if p:
 
119
            try:
 
120
                p.writeConnectionLost()
 
121
            except:
 
122
                log.err()
 
123
                self.connectionLost(failure.Failure())
 
124
 
 
125
    def _readConnectionLost(self, reason):
 
126
        self._reader=None
 
127
        p = interfaces.IHalfCloseableProtocol(self.protocol, None)
 
128
        if p:
 
129
            try:
 
130
                p.readConnectionLost()
 
131
            except:
 
132
                log.err()
 
133
                self.connectionLost(failure.Failure())
 
134
        else:
 
135
            self.connectionLost(reason)
 
136
 
 
137
    # IConsumer
 
138
    def registerProducer(self, producer, streaming):
 
139
        if self._writer is None:
 
140
            producer.stopProducing()
 
141
        else:
 
142
            self._writer.registerProducer(producer, streaming)
 
143
 
 
144
    def unregisterProducer(self):
 
145
        if self._writer is not None:
 
146
            self._writer.unregisterProducer()
 
147
 
 
148
    # IProducer
 
149
    def stopProducing(self):
 
150
        self.loseConnection()
 
151
 
 
152
    def pauseProducing(self):
 
153
        if self._reader is not None:
 
154
            self._reader.pauseProducing()
 
155
 
 
156
    def resumeProducing(self):
 
157
        if self._reader is not None:
 
158
            self._reader.resumeProducing()
 
159
 
 
160
    # Stupid compatibility:
 
161
    def closeStdin(self):
 
162
        """Compatibility only, don't use. Same as loseWriteConnection."""
 
163
        warnings.warn("This function is deprecated, use loseWriteConnection instead.",
 
164
                      category=DeprecationWarning, stacklevel=2)
 
165
        self.loseWriteConnection()
 
166
 
 
167
    def stopReading(self):
 
168
        """Compatibility only, don't use. Call pauseProducing."""
 
169
        self.pauseProducing()
 
170
 
 
171
    def startReading(self):
 
172
        """Compatibility only, don't use. Call resumeProducing."""
 
173
        self.resumeProducing()