From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8994 invoked from network); 30 Jul 2004 23:46:58 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 30 Jul 2004 23:46:58 -0000 Received: (qmail 89386 invoked from network); 30 Jul 2004 23:46:51 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 30 Jul 2004 23:46:51 -0000 Received: (qmail 10386 invoked by alias); 30 Jul 2004 23:46:06 -0000 Mailing-List: contact zsh-users-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 7794 Received: (qmail 10376 invoked from network); 30 Jul 2004 23:46:06 -0000 Received: from unknown (HELO a.mx.sunsite.dk) (130.225.247.88) by 130.225.247.90 with SMTP; 30 Jul 2004 23:46:06 -0000 Received: (qmail 87519 invoked from network); 30 Jul 2004 23:44:08 -0000 Received: from vinc17.net1.nerim.net (HELO ay.vinc17.org) (62.4.18.82) by a.mx.sunsite.dk with SMTP; 30 Jul 2004 23:44:06 -0000 Received: from lefevre by ay.vinc17.org with local (Exim 4.34) id 1Bqh2j-0004A3-D5; Sat, 31 Jul 2004 01:44:05 +0200 Date: Sat, 31 Jul 2004 01:44:05 +0200 From: Vincent Lefevre To: zsh-users@sunsite.dk Subject: Re: coloring STDERR to terminal Message-ID: <20040730234405.GS2892@ay.vinc17.org> Mail-Followup-To: zsh-users@sunsite.dk References: <20040629160826.GL2033@ay.vinc17.org> <20040630070902.GO2033@ay.vinc17.org> <20040630114341.GR2033@ay.vinc17.org> <20040701181459.GF2033@ay.vinc17.org> <20040702124259.GS2033@ay.vinc17.org> <20040730115024.GA25889@spiegl.de> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="k1lZvvs/B4yU6o8G" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20040730115024.GA25889@spiegl.de> X-Mailer-Info: http://www.vinc17.org/mutt/ User-Agent: Mutt/1.5.6i Sender: Vincent Lefevre X-Spam-Checker-Version: SpamAssassin 2.63 on a.mx.sunsite.dk X-Spam-Level: X-Spam-Status: No, hits=-4.9 required=6.0 tests=BAYES_00 autolearn=no version=2.63 X-Spam-Hits: -4.9 --k1lZvvs/B4yU6o8G Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2004-07-30 13:50:24 +0200, Andy Spiegl wrote: > As you can see the question doesn't appear at all! AFAIK, this is due to the "read line", that waits for a whole line. When I reimplemented stderr coloring, I fixed that (and other problems too) by writing a small C program "colorize" (attached) instead of zsh code. So, you should do the following: exec 2>>(colorize `tput bold; tput setaf 1` `tput sgr0` > /dev/tty &) for instance, by putting that in your zshrc. But I no longer use it since too many programs use stderr for things other than error or warning messages, and sometimes not in a consistent way. I don't know why, perhaps because developpers think that stderr means tty (in case stdout is redirected); but if they want to write to the tty, they should really do it instead of using stderr. -- Vincent Lefèvre - Web: 100% validated (X)HTML - Acorn / RISC OS / ARM, free software, YP17, Championnat International des Jeux Mathématiques et Logiques, etc. Work: CR INRIA - computer arithmetic / SPACES project at LORIA --k1lZvvs/B4yU6o8G Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="colorize.c" /* $Id: colorize.c 3816 2004-07-03 17:01:32Z lefevre $ * * Colorize the standard input. Written for zsh stderr coloring. */ #include #include #include #include #include #include #include #include #include #define BUFFSIZE 512 static volatile sig_atomic_t usr1; static void sigusr1(int sig) { usr1 = 1; } static void writepid(char *tmpfile) { FILE *f; f = fopen(tmpfile, "w"); if (f == NULL) { perror("colorize (fopen)"); exit(EXIT_FAILURE); } fprintf(f, "%ld\n", (long) getpid()); if (fclose(f) != 0) { perror("colorize (fclose)"); exit(EXIT_FAILURE); } } int main(int argc, char **argv) { pid_t zshpid = 0; char *begstr, *endstr; fd_set rfds; int ret; if (argc != 3 && argc != 5) { fprintf(stderr, "Usage: colorize [ ]\n"); exit(EXIT_FAILURE); } /* Assume that the arguments are correct. Anyway, it is not possible to check them entirely. */ begstr = argv[1]; endstr = argv[2]; if (argc == 5) { /* To do the synchronization with the zsh prompt output... Seems to be useless in practice, hence the argc == 3 case. */ zshpid = atol(argv[3]); signal(SIGUSR1, sigusr1); writepid(argv[4]); } fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK); /* To watch stdin (fd 0). */ FD_ZERO(&rfds); FD_SET(0, &rfds); for (;;) { ret = select(1, &rfds, NULL, NULL, NULL); if (ret < 0 && errno != EINTR) { perror("colorize (pselect)"); exit(EXIT_FAILURE); } if (ret > 0) { static unsigned char buffer[BUFFSIZE]; static int dontcol = 0; ssize_t n; while ((n = read(0, buffer, BUFFSIZE)) >= 0) { ssize_t i; if (n == 0) return 0; /* stdin has been closed */ for (i = 0; i < n; i++) { if (buffer[i] == 27) dontcol = 1; if (buffer[i] == '\n') dontcol = 0; if (!dontcol) fputs(begstr, stdout); putchar(buffer[i]); if (!dontcol) fputs(endstr, stdout); } } fflush(stdout); } if (usr1) { usr1 = 0; if (kill(zshpid, SIGUSR1) != 0) { perror("colorize (kill)"); exit(EXIT_FAILURE); } } } } --k1lZvvs/B4yU6o8G--