# HG changeset patch # User Oleg Oshmyan # Date 1314041649 -10800 # Node ID 65b5c93900109f89fcfea6ab22c14cf17673a7fe # Parent ce12857289528f4aa02c0a82652e0a523c0e0f72 With _unix, Escape presses now cancel test data unarchiving diff -r ce1285728952 -r 65b5c9390010 upreckon/_unixmodule.cpp --- a/upreckon/_unixmodule.cpp Sun Aug 21 01:24:29 2011 +0300 +++ b/upreckon/_unixmodule.cpp Mon Aug 22 22:34:09 2011 +0300 @@ -2,7 +2,6 @@ #include #include -#include #ifdef HAVE_SYS_TYPES_H #include @@ -155,6 +154,9 @@ #ifdef HAVE_TERMIOS_H static bool catch_escape = false; static struct termios orig_termios; +#ifdef O_ASYNC +static int orig_stdout_fl; +#endif #endif typedef struct @@ -405,6 +407,10 @@ #endif #endif +#if defined HAVE_TERMIOS_H && defined O_ASYNC + signal(SIGIO, SIG_DFL); +#endif + if (c2ppipe[1] < 3) { int newfd; @@ -1275,6 +1281,9 @@ #ifdef HAVE_TERMIOS_H if (catch_escape) { +#ifdef O_ASYNC + signal(SIGIO, SIG_DFL); +#endif char c; while (read(0, &c, 1) == -1 && errno == EINTR) { @@ -1309,6 +1318,9 @@ static void restore_termios(void) { tcsetattr(0, TCSAFLUSH, &orig_termios); +#ifdef O_ASYNC + fcntl(0, F_SETFL, orig_stdout_fl); +#endif #ifdef USE_WAKEUP_FD close_intpipe(); #endif @@ -1443,6 +1455,10 @@ if (!Py_AtExit(restore_termios) && !tcsetattr(0, TCSAFLUSH, &new_termios)) { catch_escape = true; +#ifdef O_ASYNC + orig_stdout_fl = fcntl(0, F_GETFL); + fcntl(0, F_SETFL, orig_stdout_fl | O_ASYNC); +#endif } } #ifdef USE_WAKEUP_FD diff -r ce1285728952 -r 65b5c9390010 upreckon/exceptions.py --- a/upreckon/exceptions.py Sun Aug 21 01:24:29 2011 +0300 +++ b/upreckon/exceptions.py Mon Aug 22 22:34:09 2011 +0300 @@ -13,7 +13,7 @@ class CPUTimeLimitExceeded(TimeLimitExceeded): __slots__ = () class WallTimeLimitExceeded(TimeLimitExceeded): __slots__ = () class MemoryLimitExceeded(TestCaseNotPassed): __slots__ = () -class CanceledByUser(TestCaseNotPassed): __slots__ = () +class CanceledByUser(BaseException): __slots__ = () class WrongAnswer(TestCaseNotPassed): __slots__ = 'comment' diff -r ce1285728952 -r 65b5c9390010 upreckon/testcases.py --- a/upreckon/testcases.py Sun Aug 21 01:24:29 2011 +0300 +++ b/upreckon/testcases.py Mon Aug 22 22:34:09 2011 +0300 @@ -19,6 +19,8 @@ def __enter__(self): pass def __exit__(self, exc_type, exc_value, traceback): pass signal_ignorer = DummySignalIgnorer() +def install_escape_handler(): pass +def remove_escape_handler(): pass try: from .win32 import * @@ -121,8 +123,10 @@ case.files_to_delete = [] case.time_limit_string = case.wall_time_limit_string try: + install_escape_handler() return case.test(callback) finally: + remove_escape_handler() now = clock() if getattr(case, 'time_started', None) is None: case.time_started = case.time_stopped = now diff -r ce1285728952 -r 65b5c9390010 upreckon/unix.py --- a/upreckon/unix.py Sun Aug 21 01:24:29 2011 +0300 +++ b/upreckon/unix.py Mon Aug 22 22:34:09 2011 +0300 @@ -308,3 +308,21 @@ tty.setcbreak(sys.stdin.fileno()) def pause(): sys.stdin.read(1) +else: + try: + from signal import signal, SIGIO, SIG_DFL + from select import select + except ImportError: + pass + else: + def sigio_handler(signum, frame): + if select((sys.stdin,), (), (), 0)[0]: + if os.read(sys.stdin.fileno(), 1) == '\33'.encode('ascii'): + remove_escape_handler() + raise CanceledByUser + def install_escape_handler(): + signal(SIGIO, sigio_handler) + sigio_handler(SIGIO, None) + def remove_escape_handler(): + signal(SIGIO, SIG_DFL) + __all__ += 'install_escape_handler', 'remove_escape_handler'