Socket: Detect closed TCP connections.

So far Limnoria relied on detecting 'ERROR :closing link' (see doError
in src/irclib.py), but that's not a standard at all, and fails on
Oragono; so we need to do this to check we're disconnected.

Plus, parsing the argument of ERROR is awful in the first place.
This commit is contained in:
Valentin Lorentz 2020-05-29 19:46:32 +02:00
parent d9b1d1f49d
commit 2bcdfd069a

View File

@ -105,9 +105,11 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
return server return server
def _handleSocketError(self, e): def _handleSocketError(self, e):
# 'e is None' means the socket was closed.
#
# (11, 'Resource temporarily unavailable') raised if connect # (11, 'Resource temporarily unavailable') raised if connect
# hasn't finished yet. We'll keep track of how many we get. # hasn't finished yet. We'll keep track of how many we get.
if e.args[0] != 11 or self.eagains > 120: if e is None or e.args[0] != 11 or self.eagains > 120:
drivers.log.disconnect(self.currentServer, e) drivers.log.disconnect(self.currentServer, e)
if self in self._instances: if self in self._instances:
self._instances.remove(self) self._instances.remove(self)
@ -195,7 +197,13 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
def _read(self): def _read(self):
"""Called by _select() when we can read data.""" """Called by _select() when we can read data."""
try: try:
self.inbuffer += self.conn.recv(1024) new_data = self.conn.recv(1024)
if not new_data:
# Socket was closed
self._handleSocketError(None)
return
self.inbuffer += new_data
self.eagains = 0 # If we successfully recv'ed, we can reset this. self.eagains = 0 # If we successfully recv'ed, we can reset this.
lines = self.inbuffer.split(b'\n') lines = self.inbuffer.split(b'\n')
self.inbuffer = lines.pop() self.inbuffer = lines.pop()