예제 #1
0
 def testReadlineWithBadDelimLen(self):
     rfd, wfd = os.pipe()
     os.close(wfd)
     f = coio.fdopen(rfd)
     # Multicharacter string delimiters not allowed.
     self.assertRaises(TypeError, f.readline, delim='fo')
     # Empty string delimiters not allowed.
     self.assertRaises(TypeError, f.readline, delim='')
예제 #2
0
 def testReadlineWithBadDelimLen(self):
   rfd, wfd = os.pipe()
   os.close(wfd)
   f = coio.fdopen(rfd)
   # Multicharacter string delimiters not allowed.
   self.assertRaises(TypeError, f.readline, delim='fo')
   # Empty string delimiters not allowed.
   self.assertRaises(TypeError, f.readline, delim='')
예제 #3
0
def NewReadLine(in_fd, out_fd):
    """Terminal-enhanced readline function generator.

  Tested on Linux 2.6.
  """
    xin = coio.fdopen(in_fd, 'r', do_close=False)
    packed_i = struct.pack('i', 0)

    def NonTerminalReadLine(prompt=''):
        xout.write(prompt)
        xout.flush()
        # Coroutines are scheduled while xin.readline() is reading the rest of
        # its line.
        line = xin.readline()
        if line:
            return line.rstrip('\n')
        raise EOFError

    def TerminalReadLine(prompt=''):
        old = termios.tcgetattr(0)
        new = list(old)
        new[6] = list(new[6])  # Copy sublist.
        #print 'READLINE', prompt
        new[3] &= ~termios.ECHO  # [2] is c_lflag
        new[3] &= ~termios.ICANON  # [3] is c_lflag
        #new[6][termios.VMIN] = '\0'  # !! VMIN -- no effect below, affects only blocking / nonblocking reads
        termios.tcsetattr(0, termios.TCSANOW, new)
        BlockingWriteAll(out_fd, prompt)
        global just_after_prompt
        just_after_prompt = (out_fd, prompt)
        try:
            while not xin.wait_for_readable():
                pass
        finally:
            just_after_prompt = False
        # Is this the correct way to disable new input while we're examining the
        # existing input?
        termios.tcflow(in_fd, termios.TCIOFF)
        nread = struct.unpack('i',
                              fcntl.ioctl(in_fd, termios.FIONREAD,
                                          packed_i))[0]
        # We read more than 1 character here so that we can push all characters in
        # an escape sequence back.
        got = xin.read_at_most(nread)
        if got in ('\r', '\n'):  # Helps GNU libreadline a bit.
            BlockingWriteAll(out_fd, '\n')
            return ''
        if '\x04' in got:  # Got EOF (isn't handled well here by readline).
            new[3] |= termios.ECHO  # [2] is c_lflag; this is needed by readline.so
            new[3] |= termios.ICANON  # [2] is c_lflag; superfluous
            termios.tcsetattr(0, termios.TCSANOW, new)
            for c in got:
                fcntl.ioctl(in_fd, termios.TIOCSTI, c)
            termios.tcflow(in_fd, termios.TCION)
            raise EOFError
        prompt_width = GetPromptWidth(prompt)
        if 'readline' in sys.modules:  # raw_input() is GNU libreadline.
            WritePromptToNextLine(out_fd, '', prompt_width)
            new[3] |= termios.ICANON  # [2] is c_lflag; superfluous
            termios.tcsetattr(0, termios.TCSANOW, new)
            for c in got:
                fcntl.ioctl(in_fd, termios.TIOCSTI, c)
            new[3] |= termios.ECHO  # [2] is c_lflag; this is needed by readline.so
            termios.tcsetattr(0, termios.TCSANOW, new)
            termios.tcflow(in_fd, termios.TCION)
            # The disadvantage of the GNU libreadline implementation of
            # raw_input() here is that coroutines are not scheduled while readline
            # is reading the prompt (the non-first character).
            try:
                return raw_input(prompt)
            finally:
                termios.tcsetattr(in_fd, termios.TCSANOW, old)
        else:
            WritePromptToNextLine(out_fd, prompt, prompt_width)
            new[3] |= termios.ECHO  # [2] is c_lflag; this is needed by readline.so
            new[3] |= termios.ICANON  # [2] is c_lflag; superfluous
            termios.tcsetattr(0, termios.TCSANOW, new)
            for c in got:
                fcntl.ioctl(in_fd, termios.TIOCSTI, c)
            termios.tcflow(in_fd, termios.TCION)
            if False:
                # Coroutines are scheduled in xin.readline(), so this would be
                # incompatible with raw_input() above.
                try:
                    line = xin.readline()
                finally:
                    termios.tcsetattr(in_fd, termios.TCSANOW, old)
                if line:
                    return line.rstrip('\n')
                raise EOFError
            line = array.array('c')  # TODO(pts): Use a byte arra
            while True:
                # Do a blocking read on purpose, so other tasklets are suspended until
                # the user finishes typing the command.
                try:
                    c = os.read(in_fd, 1)  # Don't read past the first '\n'.
                except OSError, e:
                    if e.errno != errno.EAGAIN:
                        raise
                    select.select([in_fd], (), ())
                    continue
                if not c:
                    if line:
                        return line.tostring()  # Without the terminating '\n'.
                    else:
                        raise EOFError
                if c in ('\r', '\n'):
                    return line.tostring()
                line.append(c)
예제 #4
0
                        raise
                    select.select([in_fd], (), ())
                    continue
                if not c:
                    if line:
                        return line.tostring()  # Without the terminating '\n'.
                    else:
                        raise EOFError
                if c in ('\r', '\n'):
                    return line.tostring()
                line.append(c)

    if os.isatty(in_fd):
        return TerminalReadLine
    else:
        xout = coio.fdopen(out_fd, 'w', do_close=False)
        return NonTerminalReadLine


class _Ticker(object):
    """Background tasklet demonstration for syncless.console.

  To start the tasklet, type this to syncless.console: +ticker

  To stop the tasklet, type this: -ticker
  """

    ticker_worker = None

    @classmethod
    def TickerWorker(cls, sleep_amount):
예제 #5
0
    def DoTestReadlineStripend(self, use_nblimitreader):
        if use_nblimitreader:
            fdopen = lambda fd: coio.nblimitreader(coio.fdopen(fd), 654321)
        else:
            fdopen = coio.fdopen

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, 'br\nk\r\nd\n\rbr\r\n')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(('br', 'k', 'd', '\rbr'),
                             tuple(iter(lambda: f.readline_stripend(), None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(('', 'br', 'k', 'd', '\rbr', '!\r'),
                             tuple(iter(lambda: f.readline_stripend(), None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(
                ('', 'br', 'k', 'd', '\rbr', '!\r'),
                tuple(iter(lambda: f.readline_stripend(limit=4), None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(
                ('', 'br', 'k', 'd', '\rbr', '', '!\r'),
                tuple(iter(lambda: f.readline_stripend(limit=3), None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(
                ('', 'br', '', 'k\r', '', 'd', '\rb', 'r', '!\r'),
                tuple(iter(lambda: f.readline_stripend(limit=2), None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(
                ('\r', '', 'b', 'r', '', 'k', '\r', '', 'd', '', '\r', 'b',
                 'r', '', '!', '\r'),
                tuple(iter(lambda: f.readline_stripend(limit=1), None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)
예제 #6
0
    def DoTestReadlineStripendWithDelim(self, use_nblimitreader):
        if use_nblimitreader:
            fdopen = lambda fd: coio.nblimitreader(coio.fdopen(fd), 654321)
        else:
            fdopen = coio.fdopen

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, 'brakadabra')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(
                ('br', 'k', 'd', 'br'),
                tuple(iter(lambda: f.readline_stripend(delim='a'), None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, 'abrakadabra!')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(
                ('', 'br', 'k', 'd', 'br', '!'),
                tuple(iter(lambda: f.readline_stripend(delim='a'), None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, 'br\xFFk\xFFd\xFFbr\xFF')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(
                ('br', 'k', 'd', 'br'),
                tuple(iter(lambda: f.readline_stripend(delim='\xFF'), None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, 'br\xFFk\xFFd\xFFbr\xFF')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(
                ('br', 'k', 'd', 'br'),
                tuple(
                    iter(lambda: f.readline_stripend(limit=3, delim='\xFF'),
                         None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)

        rfd, wfd = os.pipe()
        try:
            os.write(wfd, 'br\xFFk\xFFd\xFFbr\xFF')
            os.close(wfd)
            wfd = None
            f = fdopen(rfd)
            rfd = None
            self.assertEqual(
                ('br', '', 'k', 'd', 'br', ''),
                tuple(
                    iter(lambda: f.readline_stripend(limit=2, delim='\xFF'),
                         None)))
        finally:
            if rfd is not None:
                os.close(rfd)
            if wfd is not None:
                os.close(wfd)
예제 #7
0
  def DoTestReadlineStripend(self, use_nblimitreader):
    if use_nblimitreader:
      fdopen = lambda fd: coio.nblimitreader(coio.fdopen(fd), 654321)
    else:
      fdopen = coio.fdopen
  
    rfd, wfd = os.pipe()
    try:
      os.write(wfd, 'br\nk\r\nd\n\rbr\r\n')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(('br', 'k', 'd', '\rbr'),
                       tuple(iter(lambda: f.readline_stripend(), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)

    rfd, wfd = os.pipe()
    try:
      os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(('', 'br', 'k', 'd', '\rbr', '!\r'),
                       tuple(iter(lambda: f.readline_stripend(), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)

    rfd, wfd = os.pipe()
    try:
      os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(('', 'br', 'k', 'd', '\rbr', '!\r'),
                       tuple(iter(lambda: f.readline_stripend(limit=4), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)

    rfd, wfd = os.pipe()
    try:
      os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(('', 'br', 'k', 'd', '\rbr', '', '!\r'),
                       tuple(iter(lambda: f.readline_stripend(limit=3), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)

    rfd, wfd = os.pipe()
    try:
      os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(('', 'br', '', 'k\r', '', 'd', '\rb', 'r', '!\r'),
                       tuple(iter(lambda: f.readline_stripend(limit=2), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)

    rfd, wfd = os.pipe()
    try:
      os.write(wfd, '\r\nbr\nk\r\nd\n\rbr\n!\r')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(('\r', '', 'b', 'r', '', 'k', '\r', '', 'd', '',
                        '\r', 'b', 'r', '', '!', '\r'),
                       tuple(iter(lambda: f.readline_stripend(limit=1), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)
예제 #8
0
  def DoTestReadlineStripendWithDelim(self, use_nblimitreader):
    if use_nblimitreader:
      fdopen = lambda fd: coio.nblimitreader(coio.fdopen(fd), 654321)
    else:
      fdopen = coio.fdopen
  
    rfd, wfd = os.pipe()
    try:
      os.write(wfd, 'brakadabra')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(('br', 'k', 'd', 'br'),
                       tuple(iter(lambda: f.readline_stripend(delim='a'), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)

    rfd, wfd = os.pipe()
    try:
      os.write(wfd, 'abrakadabra!')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(('', 'br', 'k', 'd', 'br', '!'),
                       tuple(iter(lambda: f.readline_stripend(delim='a'), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)

    rfd, wfd = os.pipe()
    try:
      os.write(wfd, 'br\xFFk\xFFd\xFFbr\xFF')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(('br', 'k', 'd', 'br'),
                       tuple(iter(lambda: f.readline_stripend(delim='\xFF'), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)

    rfd, wfd = os.pipe()
    try:
      os.write(wfd, 'br\xFFk\xFFd\xFFbr\xFF')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(
          ('br', 'k', 'd', 'br'),
          tuple(iter(lambda: f.readline_stripend(limit=3, delim='\xFF'), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)

    rfd, wfd = os.pipe()
    try:
      os.write(wfd, 'br\xFFk\xFFd\xFFbr\xFF')
      os.close(wfd)
      wfd = None
      f = fdopen(rfd)
      rfd = None
      self.assertEqual(
          ('br', '', 'k', 'd', 'br', ''),
          tuple(iter(lambda: f.readline_stripend(limit=2, delim='\xFF'), None)))
    finally:
      if rfd is not None:
        os.close(rfd)
      if wfd is not None:
        os.close(wfd)
예제 #9
0
def NewReadLine(in_fd, out_fd):
  """Terminal-enhanced readline function generator.

  Tested on Linux 2.6.
  """
  xin = coio.fdopen(in_fd, 'r', do_close=False)
  packed_i = struct.pack('i', 0)

  def NonTerminalReadLine(prompt=''):
    xout.write(prompt)
    xout.flush()
    # Coroutines are scheduled while xin.readline() is reading the rest of
    # its line.
    line = xin.readline()
    if line:
      return line.rstrip('\n')
    raise EOFError

  def TerminalReadLine(prompt=''):
    old = termios.tcgetattr(0)
    new = list(old)
    new[6] = list(new[6])  # Copy sublist.
    #print 'READLINE', prompt
    new[3] &= ~termios.ECHO  # [2] is c_lflag
    new[3] &= ~termios.ICANON  # [3] is c_lflag
    #new[6][termios.VMIN] = '\0'  # !! VMIN -- no effect below, affects only blocking / nonblocking reads
    termios.tcsetattr(0, termios.TCSANOW, new)
    BlockingWriteAll(out_fd, prompt)
    global just_after_prompt
    just_after_prompt = (out_fd, prompt)
    try:
      while not xin.wait_for_readable():
        pass
    finally:
      just_after_prompt = False
    # Is this the correct way to disable new input while we're examining the
    # existing input?
    termios.tcflow(in_fd, termios.TCIOFF)
    nread = struct.unpack('i', fcntl.ioctl(
        in_fd, termios.FIONREAD, packed_i))[0]
    # We read more than 1 character here so that we can push all characters in
    # an escape sequence back.
    got = xin.read_at_most(nread)
    if got in ('\r', '\n'):  # Helps GNU libreadline a bit.
      BlockingWriteAll(out_fd, '\n')
      return ''
    if '\x04' in got:  # Got EOF (isn't handled well here by readline).
      new[3] |= termios.ECHO  # [2] is c_lflag; this is needed by readline.so
      new[3] |= termios.ICANON  # [2] is c_lflag; superfluous
      termios.tcsetattr(0, termios.TCSANOW, new)
      for c in got:
        fcntl.ioctl(in_fd, termios.TIOCSTI, c)
      termios.tcflow(in_fd, termios.TCION)
      raise EOFError
    prompt_width = GetPromptWidth(prompt)
    if 'readline' in sys.modules:  # raw_input() is GNU libreadline.
      WritePromptToNextLine(out_fd, '', prompt_width)
      new[3] |= termios.ICANON  # [2] is c_lflag; superfluous
      termios.tcsetattr(0, termios.TCSANOW, new)
      for c in got:
        fcntl.ioctl(in_fd, termios.TIOCSTI, c)
      new[3] |= termios.ECHO  # [2] is c_lflag; this is needed by readline.so
      termios.tcsetattr(0, termios.TCSANOW, new)
      termios.tcflow(in_fd, termios.TCION)
      # The disadvantage of the GNU libreadline implementation of
      # raw_input() here is that coroutines are not scheduled while readline
      # is reading the prompt (the non-first character).
      try:
        return raw_input(prompt)
      finally:
        termios.tcsetattr(in_fd, termios.TCSANOW, old)
    else:
      WritePromptToNextLine(out_fd, prompt, prompt_width)
      new[3] |= termios.ECHO  # [2] is c_lflag; this is needed by readline.so
      new[3] |= termios.ICANON  # [2] is c_lflag; superfluous
      termios.tcsetattr(0, termios.TCSANOW, new)
      for c in got:
        fcntl.ioctl(in_fd, termios.TIOCSTI, c)
      termios.tcflow(in_fd, termios.TCION)
      if False:
        # Coroutines are scheduled in xin.readline(), so this would be
        # incompatible with raw_input() above.
        try:
          line = xin.readline()
        finally:
          termios.tcsetattr(in_fd, termios.TCSANOW, old)
        if line:
          return line.rstrip('\n')
        raise EOFError
      line = array.array('c')  # TODO(pts): Use a byte arra
      while True:
        # Do a blocking read on purpose, so other tasklets are suspended until
        # the user finishes typing the command.
        try:
          c = os.read(in_fd, 1)  # Don't read past the first '\n'.
        except OSError, e:
          if e.errno != errno.EAGAIN:
            raise
          select.select([in_fd], (), ())
          continue
        if not c:
          if line:
            return line.tostring()  # Without the terminating '\n'.
          else:
            raise EOFError
        if c in ('\r', '\n'):
          return line.tostring()
        line.append(c)
예제 #10
0
            raise
          select.select([in_fd], (), ())
          continue
        if not c:
          if line:
            return line.tostring()  # Without the terminating '\n'.
          else:
            raise EOFError
        if c in ('\r', '\n'):
          return line.tostring()
        line.append(c)

  if os.isatty(in_fd):
    return TerminalReadLine
  else:
    xout = coio.fdopen(out_fd, 'w', do_close=False)
    return NonTerminalReadLine

class _Ticker(object):
  """Background tasklet demonstration for syncless.console.

  To start the tasklet, type this to syncless.console: +ticker

  To stop the tasklet, type this: -ticker
  """

  ticker_worker = None

  @classmethod
  def TickerWorker(cls, sleep_amount):
    while True: