zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: zsh-workers@zsh.org
Subject: Re: precmd: write error: interrupted
Date: Sun, 28 Apr 2013 18:03:38 -0700	[thread overview]
Message-ID: <130428180338.ZM14577@torch.brasslantern.com> (raw)
In-Reply-To: <517D40B0.8020609@thregr.org>

On Apr 28,  5:30pm, Yuri D'Elia wrote:
} Subject: Re: precmd: write error: interrupted
}
} > +    signal_block(signal_mask(SIGWINCH));  /* See zleread() */
} >       callhookfunc("precmd", NULL, 1, NULL);
} > +    signal_unblock(signal_mask(SIGWINCH));
} 
} This is going to solve the issue for "precmd" only though, not the 
} SIGWHINCH issue as a whole.

True; I was trying to creep up on it incrementally.

Incidentally even queue_signals() doesn't actually block the signals, it
just doesn't call anything below the top-level handler, so I suspect that
replacing the above with queue_signals() would still show the bug.

Here's a stab at a more comprehensive patch.  This follows the pattern of
child_block()/child_unblock() which we use elsewhere to reap children only
when safe to do so.

I'm not 100% confident that this does the right thing for non-interactive
shells/sourcing of scripts, but I *think* the change in shingetline()
should cover those cases.

diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 9a4265f..569ad5f 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -567,7 +567,9 @@ raw_getbyte(long do_keytmout, char *cptr)
 	gettyinfo(&ti);
 	ti.tio.c_cc[VMIN] = 0;
 	settyinfo(&ti);
+	winch_unblock();
 	ret = read(SHTTY, cptr, 1);
+	winch_block();
 	ti.tio.c_cc[VMIN] = 1;
 	settyinfo(&ti);
 	if (ret > 0)
@@ -597,7 +599,9 @@ raw_getbyte(long do_keytmout, char *cptr)
 	    else
 		poll_timeout = -1;
 
+	    winch_unblock();
 	    selret = poll(fds, errtry ? 1 : nfds, poll_timeout);
+	    winch_block();
 # else
 	    int fdmax = SHTTY;
 	    struct timeval *tvptr;
@@ -622,8 +626,10 @@ raw_getbyte(long do_keytmout, char *cptr)
 	    else
 		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.
@@ -788,7 +794,9 @@ raw_getbyte(long do_keytmout, char *cptr)
 #  else
 	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
@@ -799,7 +807,9 @@ raw_getbyte(long do_keytmout, char *cptr)
 #endif
     }
 
+    winch_unblock();
     ret = read(SHTTY, cptr, 1);
+    winch_block();
 
     return ret;
 }
diff --git a/Src/init.c b/Src/init.c
index 8467a73..f4fb3be 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -1113,6 +1113,7 @@ init_signals(void)
     install_handler(SIGCHLD);
 #ifdef SIGWINCH
     install_handler(SIGWINCH);
+    winch_block();	/* See utils.c:preprompt() */
 #endif
     if (interact) {
 	install_handler(SIGALRM);
diff --git a/Src/input.c b/Src/input.c
index 5cff22d..9bd9663 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -143,10 +143,12 @@ shingetline(void)
 
     p = buf;
     for (;;) {
+	winch_unblock();
 	do {
 	    errno = 0;
 	    c = fgetc(bshin);
 	} while (c < 0 && errno == EINTR);
+	winch_block();
 	if (c < 0 || c == '\n') {
 	    if (c == '\n')
 		*p++ = '\n';
diff --git a/Src/signals.h b/Src/signals.h
index 9541a1a..d680968 100644
--- a/Src/signals.h
+++ b/Src/signals.h
@@ -59,6 +59,14 @@
 #define child_block()      signal_block(sigchld_mask)
 #define child_unblock()    signal_unblock(sigchld_mask)
 
+#ifdef SIGWINCH
+# define winch_block()      signal_block(signal_mask(SIGWINCH))
+# define winch_unblock()    signal_unblock(signal_mask(SIGWINCH))
+#else
+# define winch_block()      0
+# define winch_unblock()    0
+#endif
+
 /* ignore a signal */
 #define signal_ignore(S)   signal(S, SIG_IGN)
 
diff --git a/Src/utils.c b/Src/utils.c
index 26e2a5c..94ae522 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1291,6 +1291,13 @@ preprompt(void)
     int period = getiparam("PERIOD");
     int mailcheck = getiparam("MAILCHECK");
 
+    /*
+     * Handle any pending window size changes before we compute prompts,
+     * then block them again to avoid interrupts during prompt display.
+     */
+    winch_unblock();
+    winch_block();
+
     if (isset(PROMPTSP) && isset(PROMPTCR) && !use_exit_printed && shout) {
 	/* The PROMPT_SP heuristic will move the prompt down to a new line
 	 * if there was any dangling output on the line (assuming the terminal
-- 
1.7.9.6 (Apple Git-31.1)


  reply	other threads:[~2013-04-29  1:03 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <klbmnc$ieh$1@ger.gmane.org>
     [not found] ` <130425111646.ZM17258@torch.brasslantern.com>
     [not found]   ` <klc0n1$34u$1@ger.gmane.org>
2013-04-26  0:53     ` Bart Schaefer
     [not found]   ` <20130425193817.2f82b60c@pws-pc.ntlworld.com>
     [not found]     ` <130425151839.ZM17476@torch.brasslantern.com>
2013-04-26  8:42       ` Peter Stephenson
     [not found]   ` <klc2ah$jiv$1@ger.gmane.org>
     [not found]     ` <130426080805.ZM18619__18102.73175729$1366989065$gmane$org@torch.brasslantern.com>
2013-04-26 17:59       ` Yuri D'Elia
     [not found]     ` <130426080805.ZM18619@torch.brasslantern.com>
     [not found]       ` <517C0E09.4040505@users.sourceforge.net>
2013-04-27 22:31         ` Bart Schaefer
2013-04-28 15:30           ` Yuri D'Elia
2013-04-29  1:03             ` Bart Schaefer [this message]
2013-04-29  1:59               ` Bart Schaefer
2013-05-05  0:01               ` Frank Terbeck
2013-05-05  6:52                 ` Bart Schaefer
2013-05-05  9:38                   ` Frank Terbeck
2013-05-05 17:53                     ` Bart Schaefer
2013-05-05 18:37                       ` Frank Terbeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=130428180338.ZM14577@torch.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).