Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Where to start debugging zle recursive-edit? / Ctrl-C
Investigated this further. The handler isn't exactly late. It is
called before errflag checks, but exits here without setting errflag:
/* Are we queueing signals now? */
if (queueing_enabled) {
The log looks now like this:
-- tmoutp != ZTM_NONE / raw_getbyte() zle_main.c
## zhandler(2) signals.c (debug message in first line of zhandler)
## zhandler(2) EXIT 1 signals.c (debug message in if(queueing_enabled))
-- NOT doing break selret[-1/4/4] / zle_main.c: errflag: 0, retflag:
0, breaks: 0, exit_pending: 0
-- Trying again selret[-1], !errtry[0] / zle_main.c
-- tmoutp != ZTM_NONE / raw_getbyte() zle_main.c
-- (**) NOT doing break selret[0/4/4] / zle_main.c: errflag: 0,
retflag: 0, breaks: 0, exit_pending: 0
-- Passed !errtry(errtry:1) selret[0] / zle_main.c
## zhandler(2) signals.c
## set errflag to 2 (ERRFLAG_INT:2) / signals.c
-- tmoutp->tp <- ZTM_NONE / calc_timeout( do_keytmout: 0 ),
keytimeout: 40 / zle_main.c
== CALC_TIMEOUT() one more chance (timedfns exp100ths: 100)
-- CALC_TIMEOUT() tfnode TRUE no break NOT calling >> DIFF=1 <<
-- CALC_TIMEOUT() 0 != 1 || 100 <= 100 ZTM_FUNC(2)
^^^ LOOP-CALLED calc_timeout: tmout.tp == 2 / zle_main.c
Interesting is (**) line, it still has errno == 4 (last number in
[%d/%d/%d]), apparently errno=0 is needed before select, doing so
clears the value. What's with the queueing and early exit from
zhandler()? It brings disorder to .recursiveedit.
Best regards,
Sebastian Gniazdowski
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 9a83d41..79d6e20 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -450,47 +450,87 @@ 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();
}
@@ -508,20 +548,24 @@ raw_getbyte(long do_keytmout, char *cptr)
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
+ FILE *_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.
*/
@@ -600,43 +644,78 @@ raw_getbyte(long do_keytmout, char *cptr)
if (fd > fdmax)
fdmax = fd;
}
}
FD_ZERO(&errfd);
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;
+ }
winch_unblock();
selret = select(fdmax+1, (SELECT_ARG_2_T) & foofd,
NULL, NULL, tvptr);
winch_block();
# endif
/*
* 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);
+ }
+
/*
* 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);
+ }
+
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
@@ -669,20 +748,24 @@ raw_getbyte(long do_keytmout, char *cptr)
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;
}
/* If error or unhandled timeout, give up. */
@@ -888,22 +971,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);
@@ -1115,20 +1212,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 */
diff --git a/Src/signals.c b/Src/signals.c
index e2587dc..ea2f472 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\n", sig );
+ 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