1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import os
18 from twisted.internet import process
19 from twisted.python import log
20
22 log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/4881")
23 process._listOpenFDs = _listOpenFDs
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
97 """
98 This class contains the logic necessary to decide which of the available
99 system techniques should be used to detect the open file descriptors for
100 the current process. The chosen technique gets monkey-patched into the
101 _listOpenFDs method of this class so that the detection only needs to occur
102 once.
103
104 @ivars listdir: The implementation of listdir to use. This gets overwritten
105 by the test cases.
106 @ivars getpid: The implementation of getpid to use, returns the PID of the
107 running process.
108 @ivars openfile: The implementation of open() to use, by default the Python
109 builtin.
110 """
111
112 listdir = os.listdir
113 getpid = os.getpid
114 openfile = open
115
116
118 """
119 Figure out which implementation to use, then run it.
120 """
121 self._listOpenFDs = self._getImplementation()
122 return self._listOpenFDs()
123
124
126 """
127 Check if /dev/fd works, if so, use that. Otherwise, check if
128 /proc/%d/fd exists, if so use that.
129
130 Otherwise, ask resource.getrlimit, if that throws an exception, then
131 fallback to _fallbackFDImplementation.
132 """
133 try:
134 self.listdir("/dev/fd")
135 if self._checkDevFDSanity():
136 return self._devFDImplementation
137 else:
138 return self._fallbackFDImplementation
139 except:
140 try:
141 self.listdir("/proc/%d/fd" % (self.getpid(),))
142 return self._procFDImplementation
143 except:
144 try:
145 self._resourceFDImplementation()
146 return self._resourceFDImplementation
147 except:
148 return self._fallbackFDImplementation
149
150
152 """
153 Returns true iff opening a file modifies the fds visible
154 in /dev/fd, as it should on a sane platform.
155 """
156 start = self.listdir("/dev/fd")
157 self.openfile("/dev/null", "r")
158 end = self.listdir("/dev/fd")
159 return start != end
160
161
163 """
164 Simple implementation for systems where /dev/fd actually works.
165 See: http://www.freebsd.org/cgi/man.cgi?fdescfs
166 """
167 dname = "/dev/fd"
168 result = [int(fd) for fd in os.listdir(dname)]
169 return result
170
171
173 """
174 Simple implementation for systems where /proc/pid/fd exists (we assume
175 it works).
176 """
177 dname = "/proc/%d/fd" % (os.getpid(),)
178 return [int(fd) for fd in os.listdir(dname)]
179
180
182 """
183 Fallback implementation where the resource module can inform us about
184 how many FDs we can expect.
185
186 Note that on OS-X we expect to be using the /dev/fd implementation.
187 """
188 import resource
189 maxfds = resource.getrlimit(resource.RLIMIT_NOFILE)[1] + 1
190
191
192 if maxfds > 1024:
193 maxfds = 1024
194 return xrange(maxfds)
195
196
198 """
199 Fallback-fallback implementation where we just assume that we need to
200 close 256 FDs.
201 """
202 maxfds = 256
203 return xrange(maxfds)
204
205
206 detector = _FDDetector()
207
209 """
210 Use the global detector object to figure out which FD implementation to
211 use.
212 """
213 return detector._listOpenFDs()
214