'Read until a given string is encountered or until timeout.
When no match is found, return whatever is available instead,
possibly the empty string.  Raise EOFError if the connection
is closed and no cooked data is available.'

def read_until(self, match, timeout=None):

    n = len(match)
    self.process_rawq()
    i = self.cookedq.find(match)
    if (i >= 0):
        i = (i + n)
        buf = self.cookedq[:i]
        self.cookedq = self.cookedq[i:]
        return buf
    else:
        s_reply = ([self], [], [])
        s_args = s_reply
        if (timeout is not None):
            s_args = (s_args + (timeout,))
            from time import time
            time_start = time()
        while ((not self.eof) and (select.select(*s_args) == s_reply)):
            i = max(0, (len(self.cookedq) - n))
            self.fill_rawq()
            self.process_rawq()
            i = self.cookedq.find(match, i)
            if (i >= 0):
                i = (i + n)
                buf = self.cookedq[:i]
                self.cookedq = self.cookedq[i:]
                return buf
            if (timeout is not None):
                elapsed = (time() - time_start)
                if (elapsed >= timeout):
                    break
                s_args = (s_reply + ((timeout - elapsed),))
        return self.read_very_lazy()
