From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19732 invoked from network); 30 Jun 2004 16:57:32 -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 16:57:32 -0000 Received: (qmail 5424 invoked from network); 30 Jun 2004 18:08:30 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 30 Jun 2004 18:08:30 -0000 Received: (qmail 9270 invoked by alias); 30 Jun 2004 16:56:48 -0000 Mailing-List: contact zsh-users-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 7638 Received: (qmail 9260 invoked from network); 30 Jun 2004 16:56:47 -0000 Received: from odin.dotsrc.org (HELO a.mx.sunsite.dk) (qmailr@130.225.247.85) by sunsite.dk with SMTP; 30 Jun 2004 16:56:47 -0000 Received: (qmail 4617 invoked from network); 30 Jun 2004 18:08:10 -0000 Received: from unknown (HELO moonbase.zanshin.com) (@167.160.213.139) by a.mx.sunsite.dk with SMTP; 30 Jun 2004 18:08:03 -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 i5UGubqH024175 for ; Wed, 30 Jun 2004 09:56:37 -0700 Date: Wed, 30 Jun 2004 09:56:37 -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: <20040630114341.GR2033@ay.vinc17.org> Message-ID: References: <20040627190433.Q27888@willy_wonka> <20040629160826.GL2033@ay.vinc17.org> <20040630070902.GO2033@ay.vinc17.org> <20040630114341.GR2033@ay.vinc17.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; CHARSET=US-ASCII Content-ID: 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-30 03:52:46 -0700, Bart Schaefer wrote: > > > > coproc while read line; do > > print '\e[91m'${(q)line}'\e[0m' > /dev/tty > > print -n $'\0' > > done > > Thanks for the explanation. But in fact, I didn't add the > > print -n $'\0' > > line, so there is no R problem in my case. So, is this line really > useful? (See next message excerpted below.) > Also, when I quit zsh, the coprocess is not killed (the NO_HUP option > is set, but a coprocess can be seen as a particular case). Is it a bug? Possibly. > And is it possible to hide the coprocess from the jobs table? Older versions of zsh did that -- the coprocess was not managed as a job at all, in fact -- but it was changed because (with the old behavior) there was no clean way to send termination signals etc. to the coprocess. So at present, no, it's not possible to hide the coprocess. It just occurred to me that exec 2>>( while ... & ) accomplishes the same thing without using the coprocess at all. However, it doesn't give you a handle on the stdout of the "colorizer" so it's more difficult to synchronize it with the printing of the prompt. On Wed, 30 Jun 2004, Vincent Lefevre wrote: > > Hmm... I now see. It seems I got confused by the zshbuiltins man page, > which says: > > -p Input is read from the coprocess. > > Is it > 1) from the coprocess output, or > 2) sharing the coprocess input? It's (1). > First I supposed (2); I think that this is really what I want. There's no way for two processes to read from the same descriptor without stealing bytes from each other (or synchronizing in some out-of-band way so that they don't do so). Zsh multios work by creating an intervening process that reads from one descriptor and writes duplicate bytes on two (or more) other descriptors, for just this reason. > But looking at the explanations, it seems to be (1); however, in this > case, there seems to be a race condition anyway, as the coprocess may > be too late to write its input to the tty, i.e. the following is > possible, isn't it? > > 1) I type Ctrl-d. > 2) "zsh: you have running jobs." is written by zsh to stderr (will be > read by the coprocess). > 3) precmd() is called (but there are still no bytes sent by the > coprocess). At this point the "read -p" in precmd() will block, because the coproc has not yet executed "print -n $'\0'". So your step (4) won't happen: > 4) The new prompt is displayed (sent to the tty). And instead you go directly here: > 5) The coprocess reads a line. > 6) The coprocess sends "zsh: you have running jobs." to the tty. > 7) The coprocess sends a byte to stdout (too late!). At this point "read -p" gets that byte and precmd() proceeds and the prompt is printed. There _is_ a race condition when, at step (2), _more_than_one_ line is written to stderr, because then the coprocess may "print -n" one or more bytes "too soon". You might be able to get away with something involving having preexec start up a process and then precmd wait for it and kill it off.