summary refs log tree commit diff
path: root/Src/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/loop.c')
-rw-r--r--Src/loop.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/Src/loop.c b/Src/loop.c
index 89ef59689..4da5a50f0 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -380,37 +380,53 @@ execwhile(Estate state, int do_exec)
     cmdpush(isuntil ? CS_UNTIL : CS_WHILE);
     loops++;
     loop = state->pc;
-    for (;;) {
-	state->pc = loop;
-	noerrexit = 1;
-	execlist(state, 1, 0);
-	noerrexit = olderrexit;
-	if (!((lastval == 0) ^ isuntil)) {
-	    if (breaks)
-		breaks--;
-	    lastval = oldval;
-	    break;
-	}
-	if (retflag) {
-	    lastval = oldval;
-	    break;
-	}
-	execlist(state, 1, 0);
-	if (breaks) {
-	    breaks--;
-	    if (breaks || !contflag)
-		break;
-	    contflag = 0;
-	}
-	if (errflag) {
-	    lastval = 1;
-	    break;
-	}
-	if (retflag)
-	    break;
-	freeheap();
-	oldval = lastval;
-    }
+
+    if (loop[0] == WC_END && loop[1] == WC_END) {
+
+        /* This is an empty loop.  Make sure the signal handler sets the
+        * flags and then just wait for someone hitting ^C. */
+
+        int old_simple_pline = simple_pline;
+
+        simple_pline = 1;
+
+        while (!breaks)
+            ;
+        breaks--;
+
+        simple_pline = old_simple_pline;
+    } else
+        for (;;) {
+            state->pc = loop;
+            noerrexit = 1;
+            execlist(state, 1, 0);
+            noerrexit = olderrexit;
+            if (!((lastval == 0) ^ isuntil)) {
+                if (breaks)
+                    breaks--;
+                lastval = oldval;
+                break;
+            }
+            if (retflag) {
+                lastval = oldval;
+                break;
+            }
+            execlist(state, 1, 0);
+            if (breaks) {
+                breaks--;
+                if (breaks || !contflag)
+                    break;
+                contflag = 0;
+            }
+            if (errflag) {
+                lastval = 1;
+                break;
+            }
+            if (retflag)
+                break;
+            freeheap();
+            oldval = lastval;
+        }
     cmdpop();
     popheap();
     loops--;