a C-programm can fail to execute under special circumstances in Linux. Example: You allocate some space and the OS denies it.
char *buffer = (char *) malloc
Typically a Linux program returns 0 on success or non-zero on failure. There are some exceptions (grep for example, which has values to represent whether it found a match). The reason for this is that the bash prompt defines true as 0, and false as 1, so it makes scripting simple:
somecmd && action "if succesful"
But that's the program itself. For code inside of a program, there is often a mixture of conventions. A common one is to return 0 (or positive) on success, or negative on failure. The reason behind this is that all instruction sets (that I'm aware of), have a branch-if-zero, or branch-if-less-than-zero instructions, which means its only one instruction to do the comparison (as opposed to having to do a compare and then branch if the comparison matched).