From: Jordi Mallach Date: Wed, 29 Oct 2003 19:44:45 +0000 (+0000) Subject: Apply DLR's patches for the SIGHUP and "Replace $" bugs. X-Git-Tag: v1.2.3~9 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=9e5f7caab900d29bc4daa34b2210638218135d81;p=nano.git Apply DLR's patches for the SIGHUP and "Replace $" bugs. git-svn-id: svn://svn.savannah.gnu.org/nano/branches/nano_1_2_branch/nano@1578 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- diff --git a/ChangeLog b/ChangeLog index 1f7b53f8..1c43c9ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,15 @@ CVS code - +- General: + - Translation updates (see po/ChangeLog for details). +- nano.c: + do_suspend() + - Use handle_hupterm() to handle SIGHUP and SIGTERM so we can + properly deal with them while nano is suspended. (DLR; problem + found by David Benbennick) +- search.c: + do_replace_loop() + - Fix potential infinite loop when doing a forward regex replace + of "$". (DLR; found by Mike Frysinger) - winio.c: titlebar() diff --git a/nano.c b/nano.c index 1cb3aedc..00272be8 100644 --- a/nano.c +++ b/nano.c @@ -2806,6 +2806,12 @@ RETSIGTYPE do_suspend(int signal) /* Restore the terminal settings for the disabled keys */ tcsetattr(0, TCSANOW, &oldterm); + /* Trap SIGHUP and SIGTERM so we can properly deal with them while + suspended */ + act.sa_handler = handle_hupterm; + sigaction(SIGHUP, &act, NULL); + sigaction(SIGTERM, &act, NULL); + /* We used to re-enable the default SIG_DFL and raise SIGTSTP, but then we could be (and were) interrupted in the middle of the call. So we do it the mutt way instead */ @@ -2817,8 +2823,8 @@ RETSIGTYPE do_cont(int signal) { /* Now we just update the screen instead of having to reenable the SIGTSTP handler. */ - doupdate(); + /* The Hurd seems to need this, otherwise a ^Y after a ^Z will start suspending again. */ signal_init(); diff --git a/search.c b/search.c index 4fc984c6..39798c6f 100644 --- a/search.c +++ b/search.c @@ -563,22 +563,25 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin, int *beginx, int wholewords, int *i) { int replaceall = 0, numreplaced = -1; - +#ifdef HAVE_REGEX_H + int dollarreplace = 0; + /* Whether we're doing a forward regex replace of "$". */ +#endif filestruct *fileptr = NULL; char *copy; switch (*i) { - case -1: /* Aborted enter */ - if (last_replace[0] != '\0') - answer = mallocstrcpy(answer, last_replace); - statusbar(_("Replace Cancelled")); - replace_abort(); - return 0; - case 0: /* They actually entered something */ - break; - default: - if (*i != -2) { /* First page, last page, for example, could - get here */ + case -1: /* Aborted enter. */ + if (last_replace[0] != '\0') + answer = mallocstrcpy(answer, last_replace); + statusbar(_("Replace Cancelled")); + replace_abort(); + return 0; + case 0: /* They actually entered something. */ + break; + default: + if (*i != -2) { /* First page, last page, for example, could + * get here. */ do_early_abort(); replace_abort(); return 0; @@ -587,7 +590,7 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin, last_replace = mallocstrcpy(last_replace, answer); while (1) { - /* Sweet optimization by Rocco here */ + /* Sweet optimization by Rocco here. */ fileptr = findnextstr(fileptr || replaceall || search_last_line, FALSE, begin, *beginx, prevanswer); @@ -599,11 +602,11 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin, if (fileptr == NULL) break; - /* Make sure only whole words are found */ + /* Make sure only whole words are found. */ if (wholewords && !is_whole_word(current_x, fileptr->data, prevanswer)) continue; - /* If we're here, we've found the search string */ + /* If we're here, we've found the search string. */ if (numreplaced == -1) numreplaced = 0; @@ -634,9 +637,18 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin, length_change = strlen(copy) - strlen(current->data); #ifdef HAVE_REGEX_H - if (ISSET(USE_REGEXP)) + if (ISSET(USE_REGEXP)) { match_len = regmatches[0].rm_eo - regmatches[0].rm_so; - else + /* If we're on the line we started the replace on, the + * match length is 0, and current_x is at the end of the + * the line, we're doing a forward regex replace of "$". + * We have to handle this as a special case so that we + * don't end up infinitely tacking the replace string + * onto the end of the line. */ + if (current == begin && match_len == 0 && current_x == + strlen(current->data)) + dollarreplace = 1; + } else #endif match_len = strlen(prevanswer); @@ -664,7 +676,7 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin, #endif current_x += match_len + length_change - 1; - /* Cleanup */ + /* Cleanup. */ totsize += length_change; free(current->data); current->data = copy; @@ -672,8 +684,28 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin, edit_refresh(); set_modified(); numreplaced++; - } else if (*i == -1) /* Abort, else do nothing and continue - loop */ + +#ifdef HAVE_REGEX_H + if (dollarreplace == 1) { + /* If we're here, we're doing a forward regex replace of + * "$", and the replacement's just been made. Avoid + * infinite replacement by manually moving the search to + * the next line, wrapping to the first line if we're on + * the last line of the file. Afterwards, if we're back + * on the line where we started, manually break out of + * the loop. */ + current_x = 0; + if (current->next != NULL) + current = current->next; + else + current = fileage; + if (current == begin) + break; + } +#endif + + } else if (*i == -1) /* Break out of the loop, else do + * nothing and continue loop. */ break; }