It is common practice to save the 0th argument passed to a C program main
and use that as the parameter for perror
— for simple programs:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *foo = malloc(9999999999L);
if (foo == 0)
perror(argv[0]);
return 0;
}
call that program "foo", and running it illustrates the point:
> ./foo
./foo: Cannot allocate memory
Complicated programs may add to the text (or use only the filename without the path), but keeping the program name lets you find where a misbehaving program came from.
There is no universally accepted scheme for error messages, but some widely-used programs (such as gcc) add a message category such as "Error" or "Warning". Here's an example from one of my build-logs:
compiling fld_def (obj_s)
../form/fld_def.c: In function '_nc_Copy_Argument':
../form/fld_def.c:164:14: warning: cast discards 'const' qualifier from pointer target type [-Wcast-qual]
res = (TypeArgument *)argp;
^
In this example, gcc separates fields with colons and adds a category "warning" after the filename, line number, column number — and before the actual message. But there are several variations, making it complicated for programs (such as vi-like-emacs) to parse the information.
For compilers, using a category in the message makes it simple to detect the fatal errors (which may not be immediately fatal) and warnings. If your program exits on an error it does not add much to say that some are really warnings and some are errors. But when it behaves differently (or continues to work more or less) the category helps to diagnose the problem encountered.
Best Answer
It appears that the program is re-writting the various write() functions to detect whether you are printing to file descriptor 2 and then adding the relevant escape codes to make the output red at the terminal.
Unfortunately, in shell, when you do something like
The function will still be calling write (or some other similar system call) on file descriptor 1. The output appears on fd 2 since file descriptor 1 has been dupped to file descriptor 2 by your shell.
Unfortunately, I don't know of way to write /directly/ to fd 2 in shell, but you can use awk. A function like this will write the arguments directly to file descriptor 2.
I believe this is a feature of GNU awk that isn't part of POSIX but it also works on the awk provided on OS X.