From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29428 invoked from network); 30 Jun 2004 10:53:43 -0000 Received: from odin.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.85) by ns1.primenet.com.au with SMTP; 30 Jun 2004 10:53:43 -0000 Received: (qmail 10359 invoked from network); 30 Jun 2004 12:04:25 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 30 Jun 2004 12:04:25 -0000 Received: (qmail 27172 invoked by alias); 30 Jun 2004 10:52:55 -0000 Mailing-List: contact zsh-users-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 7627 Received: (qmail 27161 invoked from network); 30 Jun 2004 10:52:55 -0000 Received: from odin.dotsrc.org (HELO a.mx.sunsite.dk) (qmailr@130.225.247.85) by sunsite.dk with SMTP; 30 Jun 2004 10:52:55 -0000 Received: (qmail 9480 invoked from network); 30 Jun 2004 12:04:08 -0000 Received: from unknown (HELO moonbase.zanshin.com) (@167.160.213.139) by a.mx.sunsite.dk with SMTP; 30 Jun 2004 12:04:01 -0000 Received: from toltec.zanshin.com (toltec.zanshin.com [64.84.47.166]) by moonbase.zanshin.com (8.12.11/8.12.11) with ESMTP id i5UAqkeN015110 for ; Wed, 30 Jun 2004 03:52:46 -0700 Date: Wed, 30 Jun 2004 03:52:46 -0700 (PDT) From: Bart Schaefer Reply-To: zsh-users@sunsite.dk To: zsh-users@sunsite.dk Subject: Re: coloring STDERR to terminal In-Reply-To: <20040630070902.GO2033@ay.vinc17.org> Message-ID: References: <20040627190433.Q27888@willy_wonka> <20040629160826.GL2033@ay.vinc17.org> <20040630070902.GO2033@ay.vinc17.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Spam-Checker-Version: SpamAssassin 2.63 on a.mx.sunsite.dk X-Spam-Level: X-Spam-Status: No, hits=0.0 required=6.0 tests=none autolearn=no version=2.63 X-Spam-Hits: 0.0 On Wed, 30 Jun 2004, Vincent Lefevre wrote: > On 2004-06-29 10:14:13 -0700, Bart Schaefer wrote: > > If you want something fancier, have the coproc print a single byte to > > its stdout every time around the read loop To clarify, by this I mean to its original standard output, not to the redirected stdout which is going to /dev/tty (otherwise the parent zsh can't see it). E.g. instead of coproc while read line; print '\e[91m'${(q)line}'\e[0m' > /dev/tty You need coproc while read line; do print '\e[91m'${(q)line}'\e[0m' > /dev/tty print -n $'\0' done >[...] > > However, if you produce more lines of output between commands than > > there are bytes of space in the socket buffer you'll block the > > coproc and potentially deadlock everything > > I don't understand how this can happen. The situation is thus: The parent zsh (Z) holds the write-end (W) of the standard input of coprocess (C), and the read end (R) of the standard output of the coprocess. Within the coprocess, the first print command has its standard output redirected to the terminal (T), but the second is still writing on R. Z passes a copy of W to new job (J) as its stderr, then waits for J. C is thus reading from W and writing to both T and to R, but Z is not reading from R (because Z is waiting), so C can only execute as many loops as there are bytes in the buffer for R before C blocks. If C blocks, it stops reading from W, which means that eventually the buffer for W will fill up and also block J. Deadlock. This happens even faster when Z and J are the same process (a built-in command or shell function). The whole thing operates much better if C is independent of Z, and you live with the race condition that means you may sometimes get a prompt in the middle of your error output. Which is, in part, why I said whether it "doesn't work very well" depends on your definition of "very well." It works as well as it can, given the original premise. Using "read -t" in C's while loop test doesn't help with this, because the gating factor is Z waiting on J. If you put J in the background (so Z is not waiting on it), the gating factor becomes Z waiting on input from the terminal at the prompt, but that you can solve with a "zle -F" handler (in 4.2.1 or later). > Wouldn't it be fine to have a read option (e.g. -T) that does this, i.e. > read what is requested (i.e. until \n or num characters if -k is used) > or return as soon as nothing else is available? See "sysread" (and "syswrite") in the zsh/system module.