zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: Why sourcing a file is not faster than doing a loop with eval, zle -N
Date: Mon, 19 Jun 2017 20:28:35 +0100	[thread overview]
Message-ID: <20170619202835.7f207185@ntlworld.com> (raw)
In-Reply-To: <20170619161601.GB9294@chaz.gmail.com>

On Mon, 19 Jun 2017 17:16:01 +0100
Stephane Chazelas <stephane.chazelas@gmail.com> wrote:
> That defeats a benefit of stdio saving read() systems calls by
> reading in chunk if we end up doing one system call per byte
> anyway.

Yes, if it's line buffered we should ideally only be unblocking
interrupts once around reading the line, which will dominate the
timing.

How about something like this?  As far as I can tell, fgets is designed
from the ground up as Gets Done Properly, so if you have it on your
system it will work correctly.  I can't think of a case where this
wouldn't do the right thing --- fgets will read at most one line and if
it does we were going to get the big STDIO overhead at that point
anyway.

pws

diff --git a/Src/input.c b/Src/input.c
index 92abaec..03d6476 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -147,6 +147,53 @@ shingetline(void)
     for (;;) {
 	winch_unblock();
 	dont_queue_signals();
+#ifdef HAVE_FGETS
+	do {
+	    errno = 0;
+	    p = fgets(buf, BUFSIZ, bshin);
+	} while (!p && errno == EINTR);
+	winch_block();
+	if (!p) {
+	    restore_queue_signals(q);
+	    return NULL;
+	}
+	c = 0;
+	while (*p) {
+	    if (imeta(STOUC(*p++)))
+		c++;
+	}
+	if (p > buf) {
+	    /* p is pointing to '\0' */
+	    ptrdiff_t nread = p - buf;
+	    queue_signals();
+	    line = zrealloc(line, ll + c + nread + 1);
+	    if (c) {
+		char *dest = line + ll;
+		char *src = buf;
+		while (src < p) {
+		    if (imeta(STOUC(*src))) {
+			*dest++ = Meta;
+			*dest++ = STOUC(*src++) ^ 32;
+		    } else
+			*dest++ = *src++;
+		}
+		*dest++ = '\0';
+	    } else {
+		/* copy null */
+		memcpy(line + ll, buf, nread + 1);
+	    }
+	    unqueue_signals();
+	    /* fgets stops at first newline but stores '\0' after */
+	    if (p[-1] == '\n') {
+		restore_queue_signals(q);
+		return line;
+	    }
+	    ll += nread;
+	} else {
+	    restore_queue_signals(q);
+	    return NULL;
+	}
+#else
 	do {
 	    errno = 0;
 	    c = fgetc(bshin);
@@ -178,6 +225,7 @@ shingetline(void)
 	    p = buf;
 	    unqueue_signals();
 	}
+#endif
     }
 }
 
diff --git a/configure.ac b/configure.ac
index 88da89e..2f19a73 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1325,7 +1325,8 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
 	       cygwin_conv_path \
 	       nanosleep \
 	       srand_deterministic \
-	       setutxent getutxent endutxent getutent)
+	       setutxent getutxent endutxent getutent \
+	       fgets)
 AC_FUNC_STRCOLL
 
 AH_TEMPLATE([REALPATH_ACCEPTS_NULL],


       reply	other threads:[~2017-06-19 19:35 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <etPan.594513a8.516100cd.10b2e__10513.1716504276$1497699329$gmane$org@zdharma.org>
     [not found] ` <20170619122413.GA9294@chaz.gmail.com>
     [not found]   ` <170619083116.ZM17323__41722.0601499595$1497886320$gmane$org@torch.brasslantern.com>
     [not found]     ` <20170619161601.GB9294@chaz.gmail.com>
2017-06-19 19:28       ` Peter Stephenson [this message]
2017-06-19 19:57         ` Bart Schaefer
2017-06-19 20:38         ` Bart Schaefer
2017-06-19 20:44           ` Peter Stephenson
2017-06-20 11:28             ` fgets() portability (Was: Why sourcing a file is not faster than doing a loop with eval, zle -N) Stephane Chazelas
2017-06-19 20:52         ` Why sourcing a file is not faster than doing a loop with eval, zle -N Peter Stephenson
2017-06-19 23:01           ` Bart Schaefer
2017-12-15 11:01             ` Sebastian Gniazdowski
2017-12-23 15:01           ` Sebastian Gniazdowski
2017-12-23 15:47             ` Sebastian Gniazdowski
2017-12-23 22:19 Joey Pabalinas
     [not found] ` <7096.1521281564@thecus>
2018-03-19  9:07   ` Joey Pabalinas
2018-03-19 14:24     ` Sebastian Gniazdowski
2018-03-20  5:14       ` Joey Pabalinas

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=20170619202835.7f207185@ntlworld.com \
    --to=p.w.stephenson@ntlworld.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).