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='')
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)
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):
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)
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)
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)
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)
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)
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: