]> git.wh0rd.org Git - nano.git/commitdiff
Apply DLR's patches for the SIGHUP and "Replace $" bugs.
authorJordi Mallach <jordi@gnu.org>
Wed, 29 Oct 2003 19:44:45 +0000 (19:44 +0000)
committerJordi Mallach <jordi@gnu.org>
Wed, 29 Oct 2003 19:44:45 +0000 (19:44 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/branches/nano_1_2_branch/nano@1578 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
nano.c
search.c

index 1f7b53f852842d9e7d649d7f918510acb7407539..1c43c9bacd6e9356ccf4d57f08628f547937b842 100644 (file)
--- 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 1cb3aedc35591d9245a0a7e93905caad1480e6b1..00272be8f906e604951bdfa0b0c3f7877fa7f2ba 100644 (file)
--- 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();
index 4fc984c6ab0baa09dcdedf6b884ec3b193825ad1..39798c6fbbb4a7d8216db81e0f777648d9eec141 100644 (file)
--- 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;
     }