Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[BUG] queueing_enabled grows infinitely when in .recursive-edit



Hello,
below is code from raw_getbyte() / zle_main.c:

                case ZTM_FUNC:
                    // MY DEBUG
                    _F = fopen("/tmp/recursive.txt", "a+");
                    fprintf( _F, "queueing_enabled MARK[D] (%d)\n",
queueing_enabled );
                    fclose(_F);

                    while (firstnode(timedfns)) {
                        Timedfn tfdat = (Timedfn)getdata(firstnode(timedfns));
                        /*
                         * It's possible a previous function took
                         * a long time to run (though it can't
                         * call zle recursively), so recalculate
                         * the time on each iteration.
                         */
                        time_t now = time(NULL);
                        if (tfdat->when > now)
                            break;
                        tfdat->func();
                    }
                    // MY DEBUG
                    _F = fopen("/tmp/recursive.txt", "a+");
                    fprintf( _F, "queueing_enabled MARK[C] (%d)\n",
queueing_enabled );
                    fclose(_F);

When not in .recursive-edit, log messages look like:

zlecore() - queueing_enabled (1)
getkeycmd() - queueing_enabled (1)
getkeymapcmd() - queueing_enabled (1)
getkeybuf() - queueing_enabled (1)
getbyte() - queueing_enabled (1)
raw_getbyte() - queueing_enabled (0)
...
...
queueing_enabled MARK[2] (0)
queueing_enabled MARK[D] (0)
queueing_enabled MARK[C] (0)
queueing_enabled MARK[B] (0)
...
...

Timeout is reached every second (I do sched +1 and reschedule), the
logs are produced at that rate. However, when I press Ctrl-C to invoke
a .recursive-edit widget, then:

recursiveedit() - queueing_enabled (1)
zlecore() - queueing_enabled (1)
getkeycmd() - queueing_enabled (1)
getkeymapcmd() - queueing_enabled (1)
getkeybuf() - queueing_enabled (1)
getbyte() - queueing_enabled (1)
raw_getbyte() - queueing_enabled (0)
...
...
queueing_enabled MARK[2] (0)
queueing_enabled MARK[D] (0)
queueing_enabled MARK[C] (1)
queueing_enabled MARK[B] (1)
...
...
queueing_enabled MARK[2] (1)
queueing_enabled MARK[D] (1)
queueing_enabled MARK[C] (2)
queueing_enabled MARK[B] (2)
...
...
queueing_enabled MARK[2] (2)
queueing_enabled MARK[D] (2)
queueing_enabled MARK[C] (3)
queueing_enabled MARK[B] (3)
...
...

This causes Ctrl-C signal to be queued when in .recursive-edit, what
results in need of multiple Ctrl-C presses (errflag is set in middle
of sequence of checks of it's value and raw_getbytes() executes in
weird way). Also, errflag is set at random place after select() in
raw_getbyte(), and as Bart says, this prevents scheduled function to
execute at all, thus chain of rescheduling breaks.

For completeness I attach 10 context lines diff with the debug
messages, but the crucial two are pasted above. To see the efect only
this has to be ran:

wid() { zle .recursive-edit; }
zle -N wid
bindkey '^T' wid
fun() { sched +1 fun; }
fun
^T

PS. Because of problems with ML (maybe they're over?) I send also to
Bart and Peter.

Best regards,
Sebastian Gniazdowski
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 3db4207..e0fe2d0 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -1550,20 +1550,25 @@ getrestchar_keybuf(void)
 }
 /**/
 #endif
 
 /* read a sequence of keys that is bound to some command in a keymap */
 
 /**/
 char *
 getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
 {
+    // MY DEBUG
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "getkeymapcmd() - queueing_enabled (%d)\n", queueing_enabled );
+    fclose(_F);
+
     Thingy func = t_undefinedkey;
     char *str = NULL;
     int lastlen = 0, lastc = lastchar;
     int timeout = 0;
 
     keybuflen = 0;
     keybuf[0] = 0;
     /*
      * getkeybuf returns multibyte strings, which may not
      * yet correspond to complete wide characters, regardless
@@ -1653,20 +1658,25 @@ addkeybuf(int c)
  * middle of a wide character.  However, I think we're OK since
  * EOF and 0xff are distinct and we're reading bytes from the
  * lower level, so EOF really does mean something went wrong.  Even so,
  * I'm worried enough to leave this note here for now.
  */
 
 /**/
 static int
 getkeybuf(int w)
 {
+    // MY DEBUG
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "getkeybuf() - queueing_enabled (%d)\n", queueing_enabled );
+    fclose(_F);
+
     int c = getbyte((long)w, NULL);
 
     if(c < 0)
 	return EOF;
     addkeybuf(c);
     return c;
 }
 
 /* Push back the last command sequence read by getkeymapcmd(). *
  * Must be executed at most once after each getkeymapcmd().    */
@@ -1677,20 +1687,25 @@ ungetkeycmd(void)
 {
     ungetbytes_unmeta(keybuf, keybuflen);
 }
 
 /* read a command from the current keymap, with widgets */
 
 /**/
 mod_export Thingy
 getkeycmd(void)
 {
+    // MY DEBUG
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "getkeycmd() - queueing_enabled (%d)\n", queueing_enabled );
+    fclose(_F);
+
     Thingy func;
     int hops = 0;
     char *seq, *str;
 
     sentstring:
     seq = getkeymapcmd(curkeymap, &func, &str);
     if(!*seq)
 	return NULL;
     if(!func) {
 	if (++hops == 20) {
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 9a83d41..0a7933a 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -450,78 +450,127 @@ static void
 calc_timeout(struct ztmout *tmoutp, long do_keytmout)
 {
     if (do_keytmout && (keytimeout > 0 || do_keytmout < 0)) {
 	if (do_keytmout < 0)
 	    tmoutp->exp100ths = (time_t)-do_keytmout;
 	else if (keytimeout > ZMAXTIMEOUT * 100 /* 24 days for a keypress???? */)
 	    tmoutp->exp100ths = ZMAXTIMEOUT * 100;
 	else
 	    tmoutp->exp100ths = keytimeout;
 	tmoutp->tp = ZTM_KEY;
-    } else
+        // MY DEBUG
+        FILE *_F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "-- tmoutp->tp <- ZTM_KEY (%d) / calc_timeout() zle_main.c\n", tmoutp->exp100ths );
+        fclose(_F);
+    } else {
+        // MY DEBUG
+        FILE *_F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "-- tmoutp->tp <- ZTM_NONE / calc_timeout( do_keytmout: %d ), keytimeout: %d / zle_main.c\n", do_keytmout, keytimeout );
+        fclose(_F);
+
 	tmoutp->tp = ZTM_NONE;
+    }
 
     if (timedfns) {
+        // MY DEBUG
+        FILE *_F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "== CALC_TIMEOUT() one more chance (timedfns exp100ths: %d)\n", tmoutp->exp100ths );
+        fclose(_F);
 	for (;;) {
 	    LinkNode tfnode = firstnode(timedfns);
 	    Timedfn tfdat;
 	    time_t diff, exp100ths;
 
-	    if (!tfnode)
+	    if (!tfnode) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- CALC_TIMEOUT() !tfnode break\n" );
+                fclose(_F);
 		break;
+            }
 
 	    tfdat = (Timedfn)getdata(tfnode);
 	    diff = tfdat->when - time(NULL);
+
 	    if (diff < 0) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- CALC_TIMEOUT() tfnode TRUE no break CALLING >> DIFF=%d <<\n", diff );
+                fclose(_F);
+
 		/* Already due; call it and rescan. */
 		tfdat->func();
 		continue;
-	    }
+	    } else {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- CALC_TIMEOUT() tfnode TRUE no break NOT calling >> DIFF=%d <<\n", diff );
+                fclose(_F);
+            }
 
 	    if (diff > ZMAXTIMEOUT) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- CALC_TIMEOUT() %d > %d ZTM_MAX(%d)\n", diff, ZMAXTIMEOUT, ZTM_MAX );
+                fclose(_F);
+
 		tmoutp->exp100ths = ZMAXTIMEOUT * 100;
 		tmoutp->tp = ZTM_MAX;
-	    } else if (diff > 0) {
+	    } else if (diff >= 0) {
 		exp100ths = diff * 100;
 		if (tmoutp->tp != ZTM_KEY ||
-		    exp100ths < tmoutp->exp100ths) {
+		    exp100ths <= tmoutp->exp100ths) {
+                    // MY DEBUG
+                    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                    fprintf( _F, "-- CALC_TIMEOUT() %d != %d || %d <= %d ZTM_FUNC(%d)\n", tmoutp->tp, ZTM_KEY, exp100ths, tmoutp->exp100ths, ZTM_FUNC );
+                    fclose(_F);
+
 		    tmoutp->exp100ths = exp100ths;
 		    tmoutp->tp = ZTM_FUNC;
 		}
 	    }
 	    break;
 	}
 	/* In case we called a function which messed up the display... */
 	if (resetneeded)
 	    zrefresh();
     }
 }
 
 /* see calc_timeout for use of do_keytmout */
 
 static int
 raw_getbyte(long do_keytmout, char *cptr)
 {
+    // MY DEBUG
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "raw_getbyte() - queueing_enabled (%d)\n", queueing_enabled );
+    fclose(_F);
+
     int ret;
     struct ztmout tmout;
 #if defined(HAS_TIO) && \
   (defined(sun) || (!defined(HAVE_POLL) && !defined(HAVE_SELECT)))
     struct ttyinfo ti;
 #endif
 #ifndef HAVE_POLL
 # ifdef HAVE_SELECT
     fd_set foofd, errfd;
     FD_ZERO(&errfd);
 # endif
 #endif
 
     calc_timeout(&tmout, do_keytmout);
+    // MY DEBUG
+    _F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "-- INIT tmout.tp(%d) ZTM_NONE(%d) ZTM_KEY(%d) / BEGIN RAW_GETBYTE() zle_main.c\n", tmout.tp, ZTM_NONE, ZTM_KEY );
+    fclose(_F);
 
     /*
      * Handle timeouts and watched fd's.  If a watched fd or a function
      * timeout triggers we restart any key timeout.  This is likely to
      * be harmless: the combination is extremely rare and a function
      * is likely to occupy the user for a little while anyway.  We used
      * to make timeouts take precedence, but we can't now that the
      * timeouts may be external, so we may have both a permanent watched
      * fd and a long-term timeout.
      */
@@ -565,150 +614,271 @@ raw_getbyte(long do_keytmout, char *cptr)
 	/*
 	 * POLLIN, POLLIN, POLLIN,
 	 * Keep those fd's POLLIN...
 	 */
 	fds[0].events = POLLIN;
 	for (i = 0; i < nwatch; i++) {
 	    fds[i+1].fd = watch_fds[i].fd;
 	    fds[i+1].events = POLLIN;
 	}
 # endif
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[-6] (%d)\n", queueing_enabled );
+            fclose(_F);
 	for (;;) {
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[-5] (%d)\n", queueing_enabled );
+            fclose(_F);
 # ifdef HAVE_POLL
 	    int poll_timeout;
 
 	    if (tmout.tp != ZTM_NONE)
 		poll_timeout = tmout.exp100ths * 10;
 	    else
 		poll_timeout = -1;
 
 	    winch_unblock();
 	    selret = poll(fds, errtry ? 1 : nfds, poll_timeout);
 	    winch_block();
 # else
 	    int fdmax = SHTTY;
 	    struct timeval *tvptr;
 	    struct timeval expire_tv;
 
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[-4] (%d)\n", queueing_enabled );
+            fclose(_F);
+
 	    FD_ZERO(&foofd);
 	    FD_SET(SHTTY, &foofd);
 	    if (!errtry) {
 		for (i = 0; i < nwatch; i++) {
 		    int fd = watch_fds[i].fd;
 		    if (FD_ISSET(fd, &errfd))
 			continue;
 		    FD_SET(fd, &foofd);
 		    if (fd > fdmax)
 			fdmax = fd;
 		}
 	    }
 	    FD_ZERO(&errfd);
 
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[-3] (%d)\n", queueing_enabled );
+            fclose(_F);
+
 	    if (tmout.tp != ZTM_NONE) {
 		expire_tv.tv_sec = tmout.exp100ths / 100;
 		expire_tv.tv_usec = (tmout.exp100ths % 100) * 10000L;
 		tvptr = &expire_tv;
+
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "\n-- tmoutp != ZTM_NONE / raw_getbyte() zle_main.c\n" );
+                fclose(_F);
 	    }
-	    else
+	    else {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "\n-- FINAL (STOP) tmoutp == ZTM_NONE / raw_getbyte() zle_main.c\n" );
+                fclose(_F);
+
 		tvptr = NULL;
+            }
+
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[-2] (%d)\n", queueing_enabled );
+            fclose(_F);
 
 	    winch_unblock();
+
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[-1] (%d)\n", queueing_enabled );
+            fclose(_F);
+
+            // MY DEBUG
+            FILE *_F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "Right before select() - queueing_enabled (%d)\n", queueing_enabled );
+            fclose(_F);
+
 	    selret = select(fdmax+1, (SELECT_ARG_2_T) & foofd,
 			    NULL, NULL, tvptr);
 	    winch_block();
 # endif
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[0] (%d)\n", queueing_enabled );
+            fclose(_F);
+
 	    /*
 	     * Make sure a user interrupt gets passed on straight away.
 	     */
-	    if (selret < 0 && (errflag || retflag || breaks || exit_pending))
+	    if (selret < 0 && (errflag || retflag || breaks || exit_pending)) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- Doing break [selret:%d/%d/%d] / zle_main.c: errflag: %d, retflag: %d, breaks: %d, exit_pending: %d\n",
+                            selret, EINTR, errno, errflag, retflag, breaks, exit_pending );
+                fclose(_F);
 		break;
+            } else {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- NOT doing break selret[%d/%d/%d] / zle_main.c: errflag: %d, retflag: %d, breaks: %d, exit_pending: %d\n",
+                            selret, EINTR, errno, errflag, retflag, breaks, exit_pending );
+                fclose(_F);
+            }
+
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[1] (%d)\n", queueing_enabled );
+            fclose(_F);
+
 	    /*
 	     * Try to avoid errors on our special fd's from
 	     * messing up reads from the terminal.  Try first
 	     * with all fds, then try unsetting the special ones.
 	     */
 	    if (selret < 0 && !errtry) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- Trying again selret[%d], !errtry[%d] / zle_main.c\n", selret, errtry );
+                fclose(_F);
+
 		errtry = 1;
 		continue;
-	    }
+	    } else {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "--  Passed !errtry(errtry:%d) selret[%d] / zle_main.c\n", errtry, selret );
+                fclose(_F);
+            }
+
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[2] (%d)\n", queueing_enabled );
+            fclose(_F);
+
 	    if (selret == 0) {
 		/*
 		 * Nothing ready and no error, so we timed out.
 		 */
 		switch (tmout.tp) {
 		case ZTM_NONE:
 		    /* keeps compiler happy if not debugging */
 #ifdef DEBUG
 		    dputs("BUG: timeout fired with no timeout set.");
 #endif
 		    /* treat as if a key timeout triggered */
 		    /*FALLTHROUGH*/
 		case ZTM_KEY:
 		    /* Special value -2 signals nothing ready */
 		    selret = -2;
 		    break;
 
 		case ZTM_FUNC:
+                    // MY DEBUG
+                    _F = fopen("/tmp/recursive.txt", "a+");
+                    fprintf( _F, "queueing_enabled MARK[D] (%d)\n", queueing_enabled );
+                    fclose(_F);
+                    
 		    while (firstnode(timedfns)) {
 			Timedfn tfdat = (Timedfn)getdata(firstnode(timedfns));
 			/*
 			 * It's possible a previous function took
 			 * a long time to run (though it can't
 			 * call zle recursively), so recalculate
 			 * the time on each iteration.
 			 */
 			time_t now = time(NULL);
 			if (tfdat->when > now)
 			    break;
 			tfdat->func();
 		    }
+                    // MY DEBUG
+                    _F = fopen("/tmp/recursive.txt", "a+");
+                    fprintf( _F, "queueing_enabled MARK[C] (%d)\n", queueing_enabled );
+                    fclose(_F);
+
 		    /* Function may have messed up the display */
 		    if (resetneeded)
 			zrefresh();
+
+                    // MY DEBUG
+                    _F = fopen("/tmp/recursive.txt", "a+");
+                    fprintf( _F, "queueing_enabled MARK[B] (%d)\n", queueing_enabled );
+                    fclose(_F);
 		    /* We need to recalculate the timeout */
 		    /*FALLTHROUGH*/
 		case ZTM_MAX:
 		    /*
 		     * Reached the limit of our range, but not the
 		     * actual timeout; recalculate the timeout.
 		     * We're cheating with the key timeout here:
 		     * if one clashed with a function timeout we
 		     * reconsider the key timeout from scratch.
 		     * The effect of this is microscopic.
 		     */
 		    calc_timeout(&tmout, do_keytmout);
+                    // MY DEBUG
+                    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                    fprintf( _F, "^^^ LOOP-CALLED calc_timeout: tmout.tp == %d / zle_main.c\n", tmout.tp );
+                    fclose(_F);
 		    break;
 		}
 		/*
 		 * If we handled the timeout successfully,
 		 * carry on.
 		 */
 		if (selret == 0)
 		    continue;
 	    }
+
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[3] (%d)\n", queueing_enabled );
+            fclose(_F);
+
 	    /* If error or unhandled timeout, give up. */
 	    if (selret < 0)
 		break;
+
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[4] (%d)\n", queueing_enabled );
+            fclose(_F);
+
 	    /*
 	     * If there's user input handle it straight away.
 	     * This improves the user's ability to handle exceptional
 	     * conditions like runaway output.
 	     */
 	    if (
 # ifdef HAVE_POLL
 		 (fds[0].revents & POLLIN)
 # else
 		 FD_ISSET(SHTTY, &foofd)
 # endif
 		 )
 		break;
 	    if (nwatch && !errtry) {
+
+                // MY DEBUG
+                _F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "queueing_enabled MARK[5] (%d)\n", queueing_enabled );
+                fclose(_F);
+
 		/*
 		 * Copy the details of the watch fds in case the
 		 * user decides to delete one from inside the
 		 * handler function.
 		 */
 		int lnwatch = nwatch;
 		Watch_fd lwatch_fds = zalloc(lnwatch*sizeof(struct watch_fd));
 		memcpy(lwatch_fds, watch_fds, lnwatch*sizeof(struct watch_fd));
 		for (i = 0; i < lnwatch; i++)
 		    lwatch_fds[i].func = ztrdup(lwatch_fds[i].func);
@@ -761,27 +931,35 @@ raw_getbyte(long do_keytmout, char *cptr)
 			    /* No sensible way of handling errors here */
 			    errflag &= ~ERRFLAG_ERROR;
 			    /*
 			     * Paranoia: don't run the hooks again this
 			     * time.
 			     */
 			    errtry = 1;
 			}
 		    }
 		}
+                // MY DEBUG
+                _F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "queueing_enabled MARK[6] (%d)\n", queueing_enabled );
+                fclose(_F);
 		/* Function may have invalidated the display. */
 		if (resetneeded)
 		    zrefresh();
 		for (i = 0; i < lnwatch; i++)
 		    zsfree(lwatch_fds[i].func);
 		zfree(lwatch_fds, lnwatch*sizeof(struct watch_fd));
 
+                // MY DEBUG
+                _F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "queueing_enabled MARK[7] (%d)\n", queueing_enabled );
+                fclose(_F);
 # ifdef HAVE_POLL
 		/* Function may have added or removed handlers */
 		nfds = 1 + nwatch;
 		if (nfds > 1) {
 		    fds = zrealloc(fds, sizeof(struct pollfd) * nfds);
 		    for (i = 0; i < nwatch; i++) {
 			/*
 			 * This is imperfect because it assumes fds[] and
 			 * watch_fds[] remain in sync, which may be false
 			 * if handlers are shuffled.  However, it should
@@ -791,26 +969,41 @@ raw_getbyte(long do_keytmout, char *cptr)
 			if (fds[i+1].fd == watch_fds[i].fd &&
 			    (fds[i+1].revents & (POLLERR|POLLHUP|POLLNVAL))) {
 			    fds[i+1].events = 0;	/* Don't poll this */
 			} else {
 			    fds[i+1].fd = watch_fds[i].fd;
 			    fds[i+1].events = POLLIN;
 			}
 			fds[i+1].revents = 0;
 		    }
 		}
+                // MY DEBUG
+                _F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "queueing_enabled MARK[8] (%d)\n", queueing_enabled );
+                fclose(_F);
 # endif
 	    }
+
+            // MY DEBUG
+            _F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "queueing_enabled MARK[A] (%d)\n", queueing_enabled );
+            fclose(_F);
 	}
 # ifdef HAVE_POLL
 	zfree(fds, sizeof(struct pollfd) * nfds);
 # endif
+
+        // MY DEBUG
+        _F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "queueing_enabled MARK[9] (%d)\n", queueing_enabled );
+        fclose(_F);
+
 	if (selret < 0)
 	    return selret;
 #else
 # ifdef HAS_TIO
 	ti = shttyinfo;
 	ti.tio.c_lflag &= ~ICANON;
 	ti.tio.c_cc[VMIN] = 0;
 	ti.tio.c_cc[VTIME] = tmout.exp100ths / 10;
 #  ifdef HAVE_TERMIOS_H
 	tcsetattr(SHTTY, TCSANOW, &ti.tio);
@@ -818,38 +1011,49 @@ raw_getbyte(long do_keytmout, char *cptr)
 	ioctl(SHTTY, TCSETA, &ti.tio);
 #  endif
 	winch_unblock();
 	ret = read(SHTTY, cptr, 1);
 	winch_block();
 #  ifdef HAVE_TERMIOS_H
 	tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
 #  else
 	ioctl(SHTTY, TCSETA, &shttyinfo.tio);
 #  endif
+
+        // MY DEBUG
+        _F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "queueing_enabled MARK[10] (%d)\n", queueing_enabled );
+        fclose(_F);
+
 	return (ret <= 0) ? ret : *cptr;
 # endif
 #endif
     }
 
     winch_unblock();
     ret = read(SHTTY, cptr, 1);
     winch_block();
 
     return ret;
 }
 
 /* see calc_timeout for use of do_keytmout */
 
 /**/
 mod_export int
 getbyte(long do_keytmout, int *timeout)
 {
+    // MY DEBUG
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "getbyte() - queueing_enabled (%d)\n", queueing_enabled );
+    fclose(_F);
+
     char cc;
     unsigned int ret;
     int die = 0, r, icnt = 0;
     int old_errno = errno, obreaks = breaks;
 
     if (timeout)
 	*timeout = 0;
 
 #ifdef MULTIBYTE_SUPPORT
     /*
@@ -888,22 +1092,36 @@ getbyte(long do_keytmout, int *timeout)
 		   the counter (icnt) so that this happens 20 times and than
 		   the shell gives up (yes, this is a bit dirty...). */
 		if ((zlereadflags & ZLRF_IGNOREEOF) && icnt++ < 20)
 		    continue;
 		stopmsg = 1;
 		zexit(1, 0);
 	    }
 	    icnt = 0;
 	    if (errno == EINTR) {
 		die = 0;
+                static int counter = 0;
+
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- Got EINTR %d\n", ++counter );
+                fclose(_F);
+
 		if (!errflag && !retflag && !breaks && !exit_pending)
+                {
+                    // MY DEBUG
+                    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                    fprintf( _F, "-- Continuing despite EINTR / zle_main.c: errflag: %d, retflag: %d, breaks: %d, exit_pending: %d\n",
+                                errflag, retflag, breaks, exit_pending );
+                    fclose(_F);
 		    continue;
+                }
 		errflag &= ~ERRFLAG_ERROR;
 		breaks = obreaks;
 		errno = old_errno;
 		return lastchar = EOF;
 	    } else if (errno == EWOULDBLOCK) {
 		fcntl(0, F_SETFL, 0);
 	    } else if (errno == EIO && !die) {
 		ret = opts[MONITOR];
 		opts[MONITOR] = 1;
 		attachtty(mypgrp);
@@ -1072,20 +1290,25 @@ void
 zlecore(void)
 {
     Keymap km;
 #if !defined(HAVE_POLL) && defined(HAVE_SELECT)
     struct timeval tv;
     fd_set foofd;
 
     FD_ZERO(&foofd);
 #endif
 
+    // MY DEBUG
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "zlecore() - queueing_enabled (%d)\n", queueing_enabled );
+    fclose(_F);
+
     pushheap();
 
     /*
      * A widget function may decide to exit the shell.
      * We never exit directly from functions, to allow
      * the shell to tidy up, so we have to test for
      * that explicitly.
      */
     while (!done && !errflag && !exit_pending) {
 	UNMETACHECK();
@@ -1115,20 +1338,24 @@ zlecore(void)
 		if (eofsent)
 		    break;
 	    }
 	    handleprefixes();
 	    /* for vi mode, make sure the cursor isn't somewhere illegal */
 	    if (invicmdmode() && zlecs > findbol() &&
 		(zlecs == zlell || zleline[zlecs] == ZWC('\n')))
 		DECCS();
 	    handleundo();
 	} else {
+            // MY DEBUG
+            FILE *_F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "-- Setting error in zlecore.c\n" );
+            fclose(_F);
 	    errflag |= ERRFLAG_ERROR;
 	    break;
 	}
 
 	redrawhook();
 #ifdef HAVE_POLL
 	if (baud && !(lastcmd & ZLE_MENUCMP)) {
 	    struct pollfd pfd;
 	    int to = cost * costmult / 1000; /* milliseconds */
 
@@ -1847,20 +2074,25 @@ whereis(UNUSED(char **args))
 	ff.msg = appstr(ff.msg, " et al");
     showmsg(ff.msg);
     zsfree(ff.msg);
     return 0;
 }
 
 /**/
 int
 recursiveedit(UNUSED(char **args))
 {
+    // MY DEBUG
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "recursiveedit() - queueing_enabled (%d)\n", queueing_enabled );
+    fclose(_F);
+
     int locerror;
 
     redrawhook();
     zrefresh();
     zlecore();
 
     locerror = errflag ? 1 : 0;
     errflag = done = eofsent = 0;
 
     return locerror;
diff --git a/Src/signals.c b/Src/signals.c
index e2587dc..8a53f87 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -555,20 +555,23 @@ wait_for_processes(void)
 	unqueue_signals();
     }
 }
 
 /* the signal handler */
  
 /**/
 mod_export RETSIGTYPE
 zhandler(int sig)
 {
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "## zhandler(%d) signals.c [queueing_enabled:%d]\n", sig, queueing_enabled );
+    fclose( _F );
     sigset_t newmask, oldmask;
 
 #if defined(NO_SIGNAL_BLOCKING)
     int do_jump;
     signal_jmp_buf jump_to;
 #endif
  
     last_signal = sig;
     signal_process(sig);
  
@@ -599,20 +602,24 @@ zhandler(int sig)
 	/* Make sure it's not full (extremely unlikely) */
         if (temp_rear != queue_front) {
 	    /* ok, not full, so add to queue   */
             queue_rear = temp_rear;
 	    /* save signal caught              */
             signal_queue[queue_rear] = sig;
 	    /* save current signal mask        */
             signal_mask_queue[queue_rear] = oldmask;
         }
         signal_reset(sig);
+
+        FILE *_F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "## zhandler(%d) EXIT 1 signals.c\n", sig );
+        fclose( _F );
         return;
     }
  
     /* Reset signal mask, signal traps ok now */
     signal_setmask(oldmask);
  
     switch (sig) {
     case SIGCHLD:
 	wait_for_processes();
         break;
@@ -638,20 +645,25 @@ zhandler(int sig)
     case SIGINT:
         if (!handletrap(SIGINT)) {
 	    if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
 		isset(INTERACTIVE) && noerrexit < 0)
 		zexit(SIGINT, 1);
             if (list_pipe || chline || simple_pline) {
                 breaks = loops;
                 errflag |= ERRFLAG_INT;
 		inerrflush();
 		check_cursh_sig(SIGINT);
+
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "## set errflag to %d (ERRFLAG_INT:%d) / signals.c\n", errflag, ERRFLAG_INT );
+                fclose(_F);
             }
 	    lastval = 128 + SIGINT;
         }
         break;
 
 #ifdef SIGWINCH
     case SIGWINCH:
         adjustwinsize(1);  /* check window size and adjust */
 	(void) handletrap(SIGWINCH);
         break;


Messages sorted by: Reverse Date, Date, Thread, Author