'Read until a given string is encountered or until timeout.
The timeout is implemented using select.select().'

def _read_until_with_select(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
    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()
