diff -u nano/files.c nano-hatc/files.c --- nano/files.c Tue Mar 26 08:05:54 2002 +++ nano-hatc/files.c Wed Mar 27 15:33:31 2002 @@ -21,6 +21,9 @@ #include "config.h" +#include /* for tcgetattr, tcsetattr */ +#include /* for tcgetattr, tcsetattr */ +#include /* for kill, sigaction */ #include #include #include @@ -110,12 +113,8 @@ index = 0; size = read(fd, buf, BUFSIZ); if (size == -1) { - clear(); - refresh(); - resetty(); - endwin(); - perror(filename); - total_refresh(); + size = index; /* note index==0 */ + nperror(filename); return -1; } if (!size) @@ -291,11 +290,30 @@ } #ifndef NANO_SMALL +static int pid; /* this is the PID of the newly forked process below. + * It must be global since the signal handler needs it. + */ + +RETSIGTYPE cancel_fork(int signal) { + if (kill(pid, SIGKILL)==-1) nperror("kill"); +} + int open_pipe(char *command) { - int fd[2], pid; - int fork_status; - + int fd[2]; + struct sigaction oldaction, newaction; + /* original and temporary handlers for SIGINT */ +#ifdef _POSIX_VDISABLE + struct termios oldterm, newterm; +#endif /* _POSIX_VDISABLE */ + int cancel_sigs = 0; + /* cancel_sigs==1 means that sigaction failed without changing the + * signal handlers. cancel_sigs==2 means the signal handler was + * changed, but the tcsetattr didn't succeed. + * I use this variable since it is important to put things back when + * we finish, even if we get errors. + */ + /* Make our pipes. */ if (pipe(fd) == -1) { @@ -325,10 +343,54 @@ return 1; } + /* before we start reading the forked command's output, we set + * things up so that ^C will cancel the new process. + */ + if (sigaction(SIGINT, NULL, &newaction)==-1) { + cancel_sigs = 1; + nperror("sigaction"); + } else { + newaction.sa_handler = cancel_fork; + if (sigaction(SIGINT, &newaction, &oldaction)==-1) { + cancel_sigs = 1; + nperror("sigaction"); + } + } + /* note that now oldaction is the previous SIGINT signal handler, to + be restored later */ + + /* if the platform supports disabling individual control characters */ +#ifdef _POSIX_VDISABLE + /* then in nano.c:main the keyboard interrupt character (usually + * ^C) was turned off. The original version was stored in + * backup_intr_char, which we temporarily restore. + */ + if (!cancel_sigs && tcgetattr(0, &oldterm)==-1) { + cancel_sigs = 2; + nperror("tcgetattr"); + } + if (!cancel_sigs) { + newterm = oldterm; + newterm.c_cc[VINTR] = backup_intr_char; + if (tcsetattr(0, TCSANOW, &newterm)==-1) { + cancel_sigs = 2; + nperror("tcsetattr"); + } + } +#endif /* _POSIX_VDISABLE */ + read_file(fd[0],"stdin",0); set_modified(); - wait(&fork_status); + if (wait(NULL)==-1) nperror("wait"); + +#ifdef _POSIX_VDISABLE + if (!cancel_sigs && tcsetattr(0, TCSANOW, &oldterm)==-1) + nperror("tcsetattr"); +#endif /* _POSIX_VDISABLE */ + + if (cancel_sigs!=1 && sigaction(SIGINT, &oldaction, NULL)==-1) + nperror("sigaction"); return 0; } Only in nano-hatc: files.o diff -u nano/global.c nano-hatc/global.c --- nano/global.c Sun Mar 24 18:20:32 2002 +++ nano-hatc/global.c Wed Mar 27 15:22:23 2002 @@ -22,6 +22,9 @@ #include "config.h" #include +#include +#include + #include "nano.h" #include "proto.h" @@ -35,6 +38,10 @@ /* * Global variables */ + +#ifdef _POSIX_VDISABLE +cc_t backup_intr_char; /* the interrupt character, ^C, at startup */ +#endif int flags = 0; /* Our new flag containing many options */ WINDOW *edit; /* The file portion of the editor */ Only in nano-hatc: global.o Common subdirectories: nano/intl and nano-hatc/intl Common subdirectories: nano/m4 and nano-hatc/m4 Only in nano-hatc: move.o Only in nano-hatc: nano diff -u nano/nano.c nano-hatc/nano.c --- nano/nano.c Tue Mar 26 08:05:54 2002 +++ nano-hatc/nano.c Wed Mar 27 15:22:23 2002 @@ -2981,6 +2981,7 @@ #ifdef _POSIX_VDISABLE term = oldterm; + backup_intr_char = term.c_cc[VINTR]; /* we might need this later */ term.c_cc[VINTR] = _POSIX_VDISABLE; term.c_cc[VQUIT] = _POSIX_VDISABLE; term.c_lflag &= ~IEXTEN; Only in nano-hatc: nano.o Common subdirectories: nano/po and nano-hatc/po diff -u nano/proto.h nano-hatc/proto.h --- nano/proto.h Sun Mar 24 18:19:32 2002 +++ nano-hatc/proto.h Wed Mar 27 15:22:23 2002 @@ -22,6 +22,8 @@ /* Externs */ #include +#include +#include #ifdef HAVE_REGEX_H #include @@ -29,6 +31,10 @@ #include "nano.h" +#ifdef _POSIX_VDISABLE +extern cc_t backup_intr_char; +#endif + extern int editwinrows; extern int current_x, current_y, posible_max, totlines; extern int placewewant; @@ -171,6 +177,7 @@ void bottombars(shortcut *s); void blank_statusbar_refresh(void); void *nmalloc (size_t howmuch); +void nperror(const char *s); void *mallocstrcpy(char *dest, char *src); void wrap_reset(void); void display_main_list(void); Only in nano-hatc: rcfile.o Only in nano-hatc: search.o diff -u nano/utils.c nano-hatc/utils.c --- nano/utils.c Wed Mar 6 10:27:44 2002 +++ nano-hatc/utils.c Wed Mar 27 15:22:23 2002 @@ -21,6 +21,7 @@ #include "config.h" +#include #include #include #include @@ -158,6 +159,18 @@ #ifndef NANO_SMALL } #endif +} + +/* This is a wrapper for the perror function. The wrapper takes care of + * ncurses, calls perror (which writes to STDERR), then refreshes the + * screen. Note that nperror causes the window to flicker once. + */ +void nperror(const char *s) { + /* leave ncurses mode, go to the terminal */ + if (endwin() != ERR) { + perror(s); /* print the error */ + total_refresh(); /* return to ncurses and repaint */ + } } /* Thanks BG, many ppl have been asking for this... */