Created
August 7, 2011 00:04
-
-
Save cehoffman/1129908 to your computer and use it in GitHub Desktop.
ZSH STDERR Colorizing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* $Id: colorize.c 3816 2004-07-03 17:01:32Z lefevre $ | |
* | |
* Colorize the standard input. Written for zsh stderr coloring. | |
* This was taken from a mail archive on the subject of colorizing | |
* the stderr stream in zsh. It was written by Vincent Lefèvre as far | |
* as I know. It is here so it can be used in a brew formula. | |
* | |
* The intended usage is to place a line like the following in your zshrc | |
* exec 2>>(colorize `tput bold; tput setaf 1` `tput sgr0` > /dev/tty &) | |
* | |
* I use the colors associative array generated by zsh to make friendly color names, e.g. | |
* exec 2>>(colorize $fg[yellow] $reset_color > /dev/tty &) | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <limits.h> | |
#include <errno.h> | |
#include <signal.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <sys/select.h> | |
#include <sys/types.h> | |
#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 <begstr> <endstr> [ <zshpid> <tmpfile> ]\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); | |
} | |
} | |
} | |
} |
How funny :
I just went here by following the link in an issue of stderr related to its structure :
ku1ik/stderred#38
stderred has an advantage : a full explanation on how to install it.
Just giving a .c will be insufficient for many people, and won't make it popular. (And, as I don't have time to try how to install it, I won't...)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can also check out stderred: https://github.com/sickill/stderred