Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
[BUG] queueing_enabled grows infinitely when in .recursive-edit
- X-seq: zsh-workers 39542
- From: Sebastian Gniazdowski <sgniazdowski@xxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: [BUG] queueing_enabled grows infinitely when in .recursive-edit
- Date: Sun, 2 Oct 2016 21:00:32 +0200
- Cc: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>, Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:from:date:message-id:subject:to:cc; bh=4cqRX2yQvrU2Y8ouBC0qp/JibE9zlWI0FpUon0OBrQQ=; b=uMsDVg+ojT6CP+IowDKS8zJPxrJLgERyF1QasZ83St76uteWy/zdIodu/dUNE54XYl I9rxTDDtEdGIYnRwuoP3+/Zx0eCIj3le19N4KoMqlWz4gU+1jifi/0np36assNwIQ3sz 2UVXij8RaZQcyOFndbp8H5lMy4pyJ4+IXEz/AlDr8vYG9Lytr7rnAhyhc5EF5PQmla/C mzfKYnc40JFglJgQxwe0ZA8mK9EGtZJ4KILC0LeYEonZnQRU22t0z1EB/5SzX1/9bKGD zvh9S3hNN5ta412s1XP4+eAlgPipQasHlM1UA5fLAqDszbkUoVpmYtJP5OoFFZBZEpAg eGgA==
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
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