We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
asyncore: (9, 'Bad file descriptor')
```
Testing using /usr/bin/python2.6
Fail2ban 0.8.8 test suite. Python 2.6.8 (unknown, Jan 26 2013, 14:35:25) [GCC 4.7.2]. Please wait...
.........................................Exception in thread Thread-61:
Traceback (most recent call last):
  File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.6/threading.py", line 484, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/home/yoh/deb/gits/fail2ban/server/asyncserver.py", line 144, in start
    asyncore.loop(use_poll = False) # fixes the "Unexpected communication problem" issue on Python 2.6 and 3.0
  File "/usr/lib/python2.6/asyncore.py", line 210, in loop
    poll_fun(timeout, map)
  File "/usr/lib/python2.6/asyncore.py", line 140, in poll
    r, w, e = select.select(r, w, e, timeout)
error: (9, 'Bad file descriptor')

.....................................F....
```

Never ran into this one before (or at least not for a while ;) )


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `fail2ban/server/asyncserver.py`
Content:
```
1 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
2 # vi: set ft=python sts=4 ts=4 sw=4 noet :
3 
4 # This file is part of Fail2Ban.
5 #
6 # Fail2Ban is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # Fail2Ban is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Fail2Ban; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 
20 # Author: Cyril Jaquier
21 # 
22 
23 __author__ = "Cyril Jaquier"
24 __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
25 __license__ = "GPL"
26 
27 from pickle import dumps, loads, HIGHEST_PROTOCOL
28 import asyncore, asynchat, socket, os, sys, traceback, fcntl
29 
30 from ..helpers import getLogger,formatExceptionInfo
31 
32 # Gets the instance of the logger.
33 logSys = getLogger(__name__)
34 
35 if sys.version_info >= (3,):
36 	# b"" causes SyntaxError in python <= 2.5, so below implements equivalent
37 	EMPTY_BYTES = bytes("", encoding="ascii")
38 else:
39 	# python 2.x, string type is equivalent to bytes.
40 	EMPTY_BYTES = ""
41 
42 ##
43 # Request handler class.
44 #
45 # This class extends asynchat in order to provide a request handler for
46 # incoming query.
47 
48 class RequestHandler(asynchat.async_chat):
49 	
50 	if sys.version_info >= (3,):
51 		END_STRING = bytes("<F2B_END_COMMAND>", encoding="ascii")
52 	else:
53 		END_STRING = "<F2B_END_COMMAND>"
54 
55 	def __init__(self, conn, transmitter):
56 		asynchat.async_chat.__init__(self, conn)
57 		self.__transmitter = transmitter
58 		self.__buffer = []
59 		# Sets the terminator.
60 		self.set_terminator(RequestHandler.END_STRING)
61 
62 	def collect_incoming_data(self, data):
63 		#logSys.debug("Received raw data: " + str(data))
64 		self.__buffer.append(data)
65 
66 	##
67 	# Handles a new request.
68 	#
69 	# This method is called once we have a complete request.
70 
71 	def found_terminator(self):
72 		# Joins the buffer items.
73 		message = loads(EMPTY_BYTES.join(self.__buffer))
74 		# Gives the message to the transmitter.
75 		message = self.__transmitter.proceed(message)
76 		# Serializes the response.
77 		message = dumps(message, HIGHEST_PROTOCOL)
78 		# Sends the response to the client.
79 		self.push(message + RequestHandler.END_STRING)
80 		# Closes the channel.
81 		self.close_when_done()
82 		
83 	def handle_error(self):
84 		e1, e2 = formatExceptionInfo()
85 		logSys.error("Unexpected communication error: %s" % str(e2))
86 		logSys.error(traceback.format_exc().splitlines())
87 		self.close()
88 		
89 ##
90 # Asynchronous server class.
91 #
92 # This class extends asyncore and dispatches connection requests to
93 # RequestHandler.
94 
95 class AsyncServer(asyncore.dispatcher):
96 
97 	def __init__(self, transmitter):
98 		asyncore.dispatcher.__init__(self)
99 		self.__transmitter = transmitter
100 		self.__sock = "/var/run/fail2ban/fail2ban.sock"
101 		self.__init = False
102 
103 	##
104 	# Returns False as we only read the socket first.
105 
106 	def writable(self):
107 		return False
108 
109 	def handle_accept(self):
110 		try:
111 			conn, addr = self.accept()
112 		except socket.error:
113 			logSys.warning("Socket error")
114 			return
115 		except TypeError:
116 			logSys.warning("Type error")
117 			return
118 		AsyncServer.__markCloseOnExec(conn)
119 		# Creates an instance of the handler class to handle the
120 		# request/response on the incoming connection.
121 		RequestHandler(conn, self.__transmitter)
122 	
123 	##
124 	# Starts the communication server.
125 	#
126 	# @param sock: socket file.
127 	# @param force: remove the socket file if exists.
128 	
129 	def start(self, sock, force):
130 		self.__sock = sock
131 		# Remove socket
132 		if os.path.exists(sock):
133 			logSys.error("Fail2ban seems to be already running")
134 			if force:
135 				logSys.warning("Forcing execution of the server")
136 				os.remove(sock)
137 			else:
138 				raise AsyncServerException("Server already running")
139 		# Creates the socket.
140 		self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)
141 		self.set_reuse_addr()
142 		try:
143 			self.bind(sock)
144 		except Exception:
145 			raise AsyncServerException("Unable to bind socket %s" % self.__sock)
146 		AsyncServer.__markCloseOnExec(self.socket)
147 		self.listen(1)
148 		# Sets the init flag.
149 		self.__init = True
150 		# TODO Add try..catch
151 		# There's a bug report for Python 2.6/3.0 that use_poll=True yields some 2.5 incompatibilities:
152 		logSys.debug("Detected Python 2.6 or greater. asyncore.loop() not using poll")
153 		asyncore.loop(use_poll=False) # fixes the "Unexpected communication problem" issue on Python 2.6 and 3.0
154 	
155 	##
156 	# Stops the communication server.
157 	
158 	def stop(self):
159 		if self.__init:
160 			# Only closes the socket if it was initialized first.
161 			self.close()
162 		# Remove socket
163 		if os.path.exists(self.__sock):
164 			logSys.debug("Removed socket file " + self.__sock)
165 			os.remove(self.__sock)
166 		logSys.debug("Socket shutdown")
167 
168 	##
169 	# Marks socket as close-on-exec to avoid leaking file descriptors when
170 	# running actions involving command execution.
171 
172 	# @param sock: socket file.
173 	
174 	@staticmethod
175 	def __markCloseOnExec(sock):
176 		fd = sock.fileno()
177 		flags = fcntl.fcntl(fd, fcntl.F_GETFD)
178 		fcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC)
179 
180 ##
181 # AsyncServerException is used to wrap communication exceptions.
182 
183 class AsyncServerException(Exception):
184 	pass
185
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/fail2ban/server/asyncserver.py b/fail2ban/server/asyncserver.py
--- a/fail2ban/server/asyncserver.py
+++ b/fail2ban/server/asyncserver.py
@@ -149,8 +149,11 @@
 		self.__init = True
 		# TODO Add try..catch
 		# There's a bug report for Python 2.6/3.0 that use_poll=True yields some 2.5 incompatibilities:
-		logSys.debug("Detected Python 2.6 or greater. asyncore.loop() not using poll")
-		asyncore.loop(use_poll=False) # fixes the "Unexpected communication problem" issue on Python 2.6 and 3.0
+		if sys.version_info >= (2, 7) and sys.version_info < (2, 8): # if python 2.7 ...
+			logSys.debug("Detected Python 2.7. asyncore.loop() using poll")
+			asyncore.loop(use_poll=True) # workaround for the "Bad file descriptor" issue on Python 2.7, gh-161
+		else:
+			asyncore.loop(use_poll=False) # fixes the "Unexpected communication problem" issue on Python 2.6 and 3.0
 	
 	##
 	# Stops the communication server.

{"golden_diff": "diff --git a/fail2ban/server/asyncserver.py b/fail2ban/server/asyncserver.py\n--- a/fail2ban/server/asyncserver.py\n+++ b/fail2ban/server/asyncserver.py\n@@ -149,8 +149,11 @@\n \t\tself.__init = True\n \t\t# TODO Add try..catch\n \t\t# There's a bug report for Python 2.6/3.0 that use_poll=True yields some 2.5 incompatibilities:\n-\t\tlogSys.debug(\"Detected Python 2.6 or greater. asyncore.loop() not using poll\")\n-\t\tasyncore.loop(use_poll=False) # fixes the \"Unexpected communication problem\" issue on Python 2.6 and 3.0\n+\t\tif sys.version_info >= (2, 7) and sys.version_info < (2, 8): # if python 2.7 ...\n+\t\t\tlogSys.debug(\"Detected Python 2.7. asyncore.loop() using poll\")\n+\t\t\tasyncore.loop(use_poll=True) # workaround for the \"Bad file descriptor\" issue on Python 2.7, gh-161\n+\t\telse:\n+\t\t\tasyncore.loop(use_poll=False) # fixes the \"Unexpected communication problem\" issue on Python 2.6 and 3.0\n \t\n \t##\n \t# Stops the communication server.\n", "issue": "asyncore: (9, 'Bad file descriptor')\n```\nTesting using /usr/bin/python2.6\nFail2ban 0.8.8 test suite. Python 2.6.8 (unknown, Jan 26 2013, 14:35:25) [GCC 4.7.2]. Please wait...\n.........................................Exception in thread Thread-61:\nTraceback (most recent call last):\n  File \"/usr/lib/python2.6/threading.py\", line 532, in __bootstrap_inner\n    self.run()\n  File \"/usr/lib/python2.6/threading.py\", line 484, in run\n    self.__target(*self.__args, **self.__kwargs)\n  File \"/home/yoh/deb/gits/fail2ban/server/asyncserver.py\", line 144, in start\n    asyncore.loop(use_poll = False) # fixes the \"Unexpected communication problem\" issue on Python 2.6 and 3.0\n  File \"/usr/lib/python2.6/asyncore.py\", line 210, in loop\n    poll_fun(timeout, map)\n  File \"/usr/lib/python2.6/asyncore.py\", line 140, in poll\n    r, w, e = select.select(r, w, e, timeout)\nerror: (9, 'Bad file descriptor')\n\n.....................................F....\n```\n\nNever ran into this one before (or at least not for a while ;) )\n\n", "before_files": [{"content": "# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-\n# vi: set ft=python sts=4 ts=4 sw=4 noet :\n\n# This file is part of Fail2Ban.\n#\n# Fail2Ban is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# Fail2Ban is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Fail2Ban; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n\n# Author: Cyril Jaquier\n# \n\n__author__ = \"Cyril Jaquier\"\n__copyright__ = \"Copyright (c) 2004 Cyril Jaquier\"\n__license__ = \"GPL\"\n\nfrom pickle import dumps, loads, HIGHEST_PROTOCOL\nimport asyncore, asynchat, socket, os, sys, traceback, fcntl\n\nfrom ..helpers import getLogger,formatExceptionInfo\n\n# Gets the instance of the logger.\nlogSys = getLogger(__name__)\n\nif sys.version_info >= (3,):\n\t# b\"\" causes SyntaxError in python <= 2.5, so below implements equivalent\n\tEMPTY_BYTES = bytes(\"\", encoding=\"ascii\")\nelse:\n\t# python 2.x, string type is equivalent to bytes.\n\tEMPTY_BYTES = \"\"\n\n##\n# Request handler class.\n#\n# This class extends asynchat in order to provide a request handler for\n# incoming query.\n\nclass RequestHandler(asynchat.async_chat):\n\t\n\tif sys.version_info >= (3,):\n\t\tEND_STRING = bytes(\"<F2B_END_COMMAND>\", encoding=\"ascii\")\n\telse:\n\t\tEND_STRING = \"<F2B_END_COMMAND>\"\n\n\tdef __init__(self, conn, transmitter):\n\t\tasynchat.async_chat.__init__(self, conn)\n\t\tself.__transmitter = transmitter\n\t\tself.__buffer = []\n\t\t# Sets the terminator.\n\t\tself.set_terminator(RequestHandler.END_STRING)\n\n\tdef collect_incoming_data(self, data):\n\t\t#logSys.debug(\"Received raw data: \" + str(data))\n\t\tself.__buffer.append(data)\n\n\t##\n\t# Handles a new request.\n\t#\n\t# This method is called once we have a complete request.\n\n\tdef found_terminator(self):\n\t\t# Joins the buffer items.\n\t\tmessage = loads(EMPTY_BYTES.join(self.__buffer))\n\t\t# Gives the message to the transmitter.\n\t\tmessage = self.__transmitter.proceed(message)\n\t\t# Serializes the response.\n\t\tmessage = dumps(message, HIGHEST_PROTOCOL)\n\t\t# Sends the response to the client.\n\t\tself.push(message + RequestHandler.END_STRING)\n\t\t# Closes the channel.\n\t\tself.close_when_done()\n\t\t\n\tdef handle_error(self):\n\t\te1, e2 = formatExceptionInfo()\n\t\tlogSys.error(\"Unexpected communication error: %s\" % str(e2))\n\t\tlogSys.error(traceback.format_exc().splitlines())\n\t\tself.close()\n\t\t\n##\n# Asynchronous server class.\n#\n# This class extends asyncore and dispatches connection requests to\n# RequestHandler.\n\nclass AsyncServer(asyncore.dispatcher):\n\n\tdef __init__(self, transmitter):\n\t\tasyncore.dispatcher.__init__(self)\n\t\tself.__transmitter = transmitter\n\t\tself.__sock = \"/var/run/fail2ban/fail2ban.sock\"\n\t\tself.__init = False\n\n\t##\n\t# Returns False as we only read the socket first.\n\n\tdef writable(self):\n\t\treturn False\n\n\tdef handle_accept(self):\n\t\ttry:\n\t\t\tconn, addr = self.accept()\n\t\texcept socket.error:\n\t\t\tlogSys.warning(\"Socket error\")\n\t\t\treturn\n\t\texcept TypeError:\n\t\t\tlogSys.warning(\"Type error\")\n\t\t\treturn\n\t\tAsyncServer.__markCloseOnExec(conn)\n\t\t# Creates an instance of the handler class to handle the\n\t\t# request/response on the incoming connection.\n\t\tRequestHandler(conn, self.__transmitter)\n\t\n\t##\n\t# Starts the communication server.\n\t#\n\t# @param sock: socket file.\n\t# @param force: remove the socket file if exists.\n\t\n\tdef start(self, sock, force):\n\t\tself.__sock = sock\n\t\t# Remove socket\n\t\tif os.path.exists(sock):\n\t\t\tlogSys.error(\"Fail2ban seems to be already running\")\n\t\t\tif force:\n\t\t\t\tlogSys.warning(\"Forcing execution of the server\")\n\t\t\t\tos.remove(sock)\n\t\t\telse:\n\t\t\t\traise AsyncServerException(\"Server already running\")\n\t\t# Creates the socket.\n\t\tself.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)\n\t\tself.set_reuse_addr()\n\t\ttry:\n\t\t\tself.bind(sock)\n\t\texcept Exception:\n\t\t\traise AsyncServerException(\"Unable to bind socket %s\" % self.__sock)\n\t\tAsyncServer.__markCloseOnExec(self.socket)\n\t\tself.listen(1)\n\t\t# Sets the init flag.\n\t\tself.__init = True\n\t\t# TODO Add try..catch\n\t\t# There's a bug report for Python 2.6/3.0 that use_poll=True yields some 2.5 incompatibilities:\n\t\tlogSys.debug(\"Detected Python 2.6 or greater. asyncore.loop() not using poll\")\n\t\tasyncore.loop(use_poll=False) # fixes the \"Unexpected communication problem\" issue on Python 2.6 and 3.0\n\t\n\t##\n\t# Stops the communication server.\n\t\n\tdef stop(self):\n\t\tif self.__init:\n\t\t\t# Only closes the socket if it was initialized first.\n\t\t\tself.close()\n\t\t# Remove socket\n\t\tif os.path.exists(self.__sock):\n\t\t\tlogSys.debug(\"Removed socket file \" + self.__sock)\n\t\t\tos.remove(self.__sock)\n\t\tlogSys.debug(\"Socket shutdown\")\n\n\t##\n\t# Marks socket as close-on-exec to avoid leaking file descriptors when\n\t# running actions involving command execution.\n\n\t# @param sock: socket file.\n\t\n\t@staticmethod\n\tdef __markCloseOnExec(sock):\n\t\tfd = sock.fileno()\n\t\tflags = fcntl.fcntl(fd, fcntl.F_GETFD)\n\t\tfcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC)\n\n##\n# AsyncServerException is used to wrap communication exceptions.\n\nclass AsyncServerException(Exception):\n\tpass\n", "path": "fail2ban/server/asyncserver.py"}], "after_files": [{"content": "# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-\n# vi: set ft=python sts=4 ts=4 sw=4 noet :\n\n# This file is part of Fail2Ban.\n#\n# Fail2Ban is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# Fail2Ban is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Fail2Ban; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n\n# Author: Cyril Jaquier\n# \n\n__author__ = \"Cyril Jaquier\"\n__copyright__ = \"Copyright (c) 2004 Cyril Jaquier\"\n__license__ = \"GPL\"\n\nfrom pickle import dumps, loads, HIGHEST_PROTOCOL\nimport asyncore, asynchat, socket, os, sys, traceback, fcntl\n\nfrom ..helpers import getLogger,formatExceptionInfo\n\n# Gets the instance of the logger.\nlogSys = getLogger(__name__)\n\nif sys.version_info >= (3,):\n\t# b\"\" causes SyntaxError in python <= 2.5, so below implements equivalent\n\tEMPTY_BYTES = bytes(\"\", encoding=\"ascii\")\nelse:\n\t# python 2.x, string type is equivalent to bytes.\n\tEMPTY_BYTES = \"\"\n\n##\n# Request handler class.\n#\n# This class extends asynchat in order to provide a request handler for\n# incoming query.\n\nclass RequestHandler(asynchat.async_chat):\n\t\n\tif sys.version_info >= (3,):\n\t\tEND_STRING = bytes(\"<F2B_END_COMMAND>\", encoding=\"ascii\")\n\telse:\n\t\tEND_STRING = \"<F2B_END_COMMAND>\"\n\n\tdef __init__(self, conn, transmitter):\n\t\tasynchat.async_chat.__init__(self, conn)\n\t\tself.__transmitter = transmitter\n\t\tself.__buffer = []\n\t\t# Sets the terminator.\n\t\tself.set_terminator(RequestHandler.END_STRING)\n\n\tdef collect_incoming_data(self, data):\n\t\t#logSys.debug(\"Received raw data: \" + str(data))\n\t\tself.__buffer.append(data)\n\n\t##\n\t# Handles a new request.\n\t#\n\t# This method is called once we have a complete request.\n\n\tdef found_terminator(self):\n\t\t# Joins the buffer items.\n\t\tmessage = loads(EMPTY_BYTES.join(self.__buffer))\n\t\t# Gives the message to the transmitter.\n\t\tmessage = self.__transmitter.proceed(message)\n\t\t# Serializes the response.\n\t\tmessage = dumps(message, HIGHEST_PROTOCOL)\n\t\t# Sends the response to the client.\n\t\tself.push(message + RequestHandler.END_STRING)\n\t\t# Closes the channel.\n\t\tself.close_when_done()\n\t\t\n\tdef handle_error(self):\n\t\te1, e2 = formatExceptionInfo()\n\t\tlogSys.error(\"Unexpected communication error: %s\" % str(e2))\n\t\tlogSys.error(traceback.format_exc().splitlines())\n\t\tself.close()\n\t\t\n##\n# Asynchronous server class.\n#\n# This class extends asyncore and dispatches connection requests to\n# RequestHandler.\n\nclass AsyncServer(asyncore.dispatcher):\n\n\tdef __init__(self, transmitter):\n\t\tasyncore.dispatcher.__init__(self)\n\t\tself.__transmitter = transmitter\n\t\tself.__sock = \"/var/run/fail2ban/fail2ban.sock\"\n\t\tself.__init = False\n\n\t##\n\t# Returns False as we only read the socket first.\n\n\tdef writable(self):\n\t\treturn False\n\n\tdef handle_accept(self):\n\t\ttry:\n\t\t\tconn, addr = self.accept()\n\t\texcept socket.error:\n\t\t\tlogSys.warning(\"Socket error\")\n\t\t\treturn\n\t\texcept TypeError:\n\t\t\tlogSys.warning(\"Type error\")\n\t\t\treturn\n\t\tAsyncServer.__markCloseOnExec(conn)\n\t\t# Creates an instance of the handler class to handle the\n\t\t# request/response on the incoming connection.\n\t\tRequestHandler(conn, self.__transmitter)\n\t\n\t##\n\t# Starts the communication server.\n\t#\n\t# @param sock: socket file.\n\t# @param force: remove the socket file if exists.\n\t\n\tdef start(self, sock, force):\n\t\tself.__sock = sock\n\t\t# Remove socket\n\t\tif os.path.exists(sock):\n\t\t\tlogSys.error(\"Fail2ban seems to be already running\")\n\t\t\tif force:\n\t\t\t\tlogSys.warning(\"Forcing execution of the server\")\n\t\t\t\tos.remove(sock)\n\t\t\telse:\n\t\t\t\traise AsyncServerException(\"Server already running\")\n\t\t# Creates the socket.\n\t\tself.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)\n\t\tself.set_reuse_addr()\n\t\ttry:\n\t\t\tself.bind(sock)\n\t\texcept Exception:\n\t\t\traise AsyncServerException(\"Unable to bind socket %s\" % self.__sock)\n\t\tAsyncServer.__markCloseOnExec(self.socket)\n\t\tself.listen(1)\n\t\t# Sets the init flag.\n\t\tself.__init = True\n\t\t# TODO Add try..catch\n\t\t# There's a bug report for Python 2.6/3.0 that use_poll=True yields some 2.5 incompatibilities:\n\t\tif sys.version_info >= (2, 7) and sys.version_info < (2, 8): # if python 2.7 ...\n\t\t\tlogSys.debug(\"Detected Python 2.7. asyncore.loop() using poll\")\n\t\t\tasyncore.loop(use_poll=True) # workaround for the \"Bad file descriptor\" issue on Python 2.7, gh-161\n\t\telse:\n\t\t\tasyncore.loop(use_poll=False) # fixes the \"Unexpected communication problem\" issue on Python 2.6 and 3.0\n\t\n\t##\n\t# Stops the communication server.\n\t\n\tdef stop(self):\n\t\tif self.__init:\n\t\t\t# Only closes the socket if it was initialized first.\n\t\t\tself.close()\n\t\t# Remove socket\n\t\tif os.path.exists(self.__sock):\n\t\t\tlogSys.debug(\"Removed socket file \" + self.__sock)\n\t\t\tos.remove(self.__sock)\n\t\tlogSys.debug(\"Socket shutdown\")\n\n\t##\n\t# Marks socket as close-on-exec to avoid leaking file descriptors when\n\t# running actions involving command execution.\n\n\t# @param sock: socket file.\n\t\n\t@staticmethod\n\tdef __markCloseOnExec(sock):\n\t\tfd = sock.fileno()\n\t\tflags = fcntl.fcntl(fd, fcntl.F_GETFD)\n\t\tfcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC)\n\n##\n# AsyncServerException is used to wrap communication exceptions.\n\nclass AsyncServerException(Exception):\n\tpass\n", "path": "fail2ban/server/asyncserver.py"}]}