Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Apr 2013 21:34:39 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r249034 - head/bin/sh
Message-ID:  <201304022134.r32LYdrc059381@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Tue Apr  2 21:34:38 2013
New Revision: 249034
URL: http://svnweb.freebsd.org/changeset/base/249034

Log:
  sh: Write as much into the heredoc pipe as possible, to avoid forking.
  
  Use non-blocking I/O to write as much as the pipe will accept (often 64K,
  but it can be as little as 4K), avoiding the need for the ugly PIPESIZE
  constant. If PIPESIZE was set too high, a deadlock would occur.

Modified:
  head/bin/sh/redir.c

Modified: head/bin/sh/redir.c
==============================================================================
--- head/bin/sh/redir.c	Tue Apr  2 21:31:11 2013	(r249033)
+++ head/bin/sh/redir.c	Tue Apr  2 21:34:38 2013	(r249034)
@@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
 
 #define EMPTY -2		/* marks an unused slot in redirtab */
 #define CLOSED -1		/* fd was not open before redir */
-#define PIPESIZE 4096		/* amount of buffering in a pipe */
 
 
 MKINIT
@@ -253,7 +252,9 @@ openhere(union node *redir)
 {
 	char *p;
 	int pip[2];
-	int len = 0;
+	size_t len = 0;
+	int flags;
+	ssize_t written = 0;
 
 	if (pipe(pip) < 0)
 		error("Pipe call failed: %s", strerror(errno));
@@ -263,9 +264,16 @@ openhere(union node *redir)
 	else
 		p = redir->nhere.doc->narg.text;
 	len = strlen(p);
-	if (len <= PIPESIZE) {
-		xwrite(pip[1], p, len);
+	if (len == 0)
 		goto out;
+	flags = fcntl(pip[1], F_GETFL, 0);
+	if (flags != -1 && fcntl(pip[1], F_SETFL, flags | O_NONBLOCK) != -1) {
+		written = write(pip[1], p, len);
+		if (written < 0)
+			written = 0;
+		if ((size_t)written == len)
+			goto out;
+		fcntl(pip[1], F_SETFL, flags);
 	}
 
 	if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
@@ -275,7 +283,7 @@ openhere(union node *redir)
 		signal(SIGHUP, SIG_IGN);
 		signal(SIGTSTP, SIG_IGN);
 		signal(SIGPIPE, SIG_DFL);
-		xwrite(pip[1], p, len);
+		xwrite(pip[1], p + written, len - written);
 		_exit(0);
 	}
 out:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201304022134.r32LYdrc059381>