To: vim-dev@vim.org Subject: patch 5.5.004 Fcc: outbox From: Bram Moolenaar ------------ Patch 5.5.004 Problem: On Unix it's not possible to interrupt ":sleep 100". Solution: Switch terminal to cooked mode while asleep, to allow a SIGINT to wake us up. But switch off echo, added TMODE_SLEEP. Files: src/term.h, src/os_unix.c *** ../vim-5.5.3/src/term.h Wed Sep 22 10:06:19 1999 --- src/term.h Fri Sep 24 22:46:26 1999 *************** *** 147,151 **** #define T_CRV (term_str(KS_CRV)) /* request version string */ #define T_OP (term_str(KS_OP)) /* original color pair */ ! #define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */ ! #define TMODE_RAW 1 /* terminal mode for Normal and Insert mode */ --- 147,152 ---- #define T_CRV (term_str(KS_CRV)) /* request version string */ #define T_OP (term_str(KS_OP)) /* original color pair */ ! #define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */ ! #define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */ ! #define TMODE_RAW 2 /* terminal mode for Normal and Insert mode */ *** ../vim-5.5.3/src/os_unix.c Wed Sep 22 21:12:18 1999 --- src/os_unix.c Sat Sep 25 20:26:59 1999 *************** *** 182,187 **** --- 182,189 ---- #endif static int deadly_signal = 0; /* The signal we caught */ + static int curr_tmode = TMODE_COOK; /* contains current terminal mode */ + #ifdef SYS_SIGLIST_DECLARED /* * I have seen *************** *** 419,437 **** long msec; int ignoreinput; { if (ignoreinput) { /* * Everybody sleeps in a different way... * Prefer nanosleep(), some versions of usleep() can only sleep up to * one second. */ #ifdef HAVE_NANOSLEEP ! struct timespec ts; ! ts.tv_sec = msec / 1000; ! ts.tv_nsec = (msec % 1000) * 1000000; ! (void)nanosleep(&ts, NULL); #else # ifdef HAVE_USLEEP while (msec >= 1000) --- 421,448 ---- long msec; int ignoreinput; { + int old_tmode; + if (ignoreinput) { + /* Go to cooked mode without echo, to allow SIGINT interrupting us + * here */ + old_tmode = curr_tmode; + settmode(TMODE_SLEEP); + /* * Everybody sleeps in a different way... * Prefer nanosleep(), some versions of usleep() can only sleep up to * one second. */ #ifdef HAVE_NANOSLEEP ! { ! struct timespec ts; ! ts.tv_sec = msec / 1000; ! ts.tv_nsec = (msec % 1000) * 1000000; ! (void)nanosleep(&ts, NULL); ! } #else # ifdef HAVE_USLEEP while (msec >= 1000) *************** *** 447,465 **** # ifdef __EMX__ _sleep2(msec); # else ! struct timeval tv; ! tv.tv_sec = msec / 1000; ! tv.tv_usec = (msec % 1000) * 1000; ! /* ! * NOTE: Solaris 2.6 has a bug that makes select() hang here. Get a ! * patch from Sun to fix this. Reported by Gunnar Pedersen. ! */ ! select(0, NULL, NULL, NULL, &tv); # endif /* __EMX__ */ # endif /* HAVE_SELECT */ # endif /* HAVE_NANOSLEEP */ #endif /* HAVE_USLEEP */ } else WaitForChar(msec); --- 458,480 ---- # ifdef __EMX__ _sleep2(msec); # else ! { ! struct timeval tv; ! tv.tv_sec = msec / 1000; ! tv.tv_usec = (msec % 1000) * 1000; ! /* ! * NOTE: Solaris 2.6 has a bug that makes select() hang here. Get ! * a patch from Sun to fix this. Reported by Gunnar Pedersen. ! */ ! select(0, NULL, NULL, NULL, &tv); ! } # endif /* __EMX__ */ # endif /* HAVE_SELECT */ # endif /* HAVE_NANOSLEEP */ #endif /* HAVE_USLEEP */ + + settmode(old_tmode); } else WaitForChar(msec); *************** *** 1699,1706 **** } } - static int curr_tmode = TMODE_COOK; /* contains current terminal mode */ - void mch_settmode(tmode) int tmode; --- 1714,1719 ---- *************** *** 1720,1737 **** struct termio tnew; # endif ! if (tmode == TMODE_RAW) { ! if (first) ! { ! first = FALSE; # if defined(HAVE_TERMIOS_H) ! tcgetattr(read_cmd_fd, &told); # else ! ioctl(read_cmd_fd, TCGETA, &told); # endif ! } ! tnew = told; /* * ~ICRNL enables typing ^V^M */ --- 1733,1751 ---- struct termio tnew; # endif ! if (first) { ! first = FALSE; # if defined(HAVE_TERMIOS_H) ! tcgetattr(read_cmd_fd, &told); # else ! ioctl(read_cmd_fd, TCGETA, &told); # endif ! } ! ! tnew = told; ! if (tmode == TMODE_RAW) ! { /* * ~ICRNL enables typing ^V^M */ *************** *** 1747,1767 **** # endif tnew.c_cc[VMIN] = 1; /* return after 1 char */ tnew.c_cc[VTIME] = 0; /* don't wait */ - # if defined(HAVE_TERMIOS_H) - tcsetattr(read_cmd_fd, TCSANOW, &tnew); - # else - ioctl(read_cmd_fd, TCSETA, &tnew); - # endif } ! else ! { # if defined(HAVE_TERMIOS_H) ! tcsetattr(read_cmd_fd, TCSANOW, &told); # else ! ioctl(read_cmd_fd, TCSETA, &told); # endif ! } #else /* * for "old" tty systems */ --- 1761,1778 ---- # endif tnew.c_cc[VMIN] = 1; /* return after 1 char */ tnew.c_cc[VTIME] = 0; /* don't wait */ } ! else if (tmode == TMODE_SLEEP) ! tnew.c_lflag &= ~(ECHO); ! # if defined(HAVE_TERMIOS_H) ! tcsetattr(read_cmd_fd, TCSANOW, &tnew); # else ! ioctl(read_cmd_fd, TCSETA, &tnew); # endif ! #else + /* * for "old" tty systems */ *************** *** 1771,1790 **** static struct sgttyb ttybold; struct sgttyb ttybnew; if (tmode == TMODE_RAW) { - if (first) - { - first = FALSE; - ioctl(read_cmd_fd, TIOCGETP, &ttybold); - } - ttybnew = ttybold; ttybnew.sg_flags &= ~(CRMOD | ECHO); ttybnew.sg_flags |= RAW; - ioctl(read_cmd_fd, TIOCSETN, &ttybnew); } ! else ! ioctl(read_cmd_fd, TIOCSETN, &ttybold); #endif curr_tmode = tmode; } --- 1782,1802 ---- static struct sgttyb ttybold; struct sgttyb ttybnew; + if (first) + { + first = FALSE; + ioctl(read_cmd_fd, TIOCGETP, &ttybold); + } + + ttybnew = ttybold; if (tmode == TMODE_RAW) { ttybnew.sg_flags &= ~(CRMOD | ECHO); ttybnew.sg_flags |= RAW; } ! else if (tmode == TMODE_SLEEP) ! ttybnew.sg_flags &= ~(ECHO); ! ioctl(read_cmd_fd, TIOCSETN, &ttybnew); #endif curr_tmode = tmode; } *** ../vim-5.5.3/src/version.c Thu Sep 23 10:12:21 1999 --- src/version.c Sat Sep 25 20:32:06 1999 *************** *** 420,420 **** --- 420,421 ---- { /* Add new patch number below this line */ + 4, -- hundred-and-one symptoms of being an internet addict: 172. You join listservers just for the extra e-mail. --/-/---- Bram Moolenaar ---- Bram@moolenaar.net ---- Bram@vim.org ---\-\-- \ \ www.vim.org/iccf www.moolenaar.net www.vim.org / /