15

I have a C program which returns an integer value. I was surprised to find out that when examining the return value from the shell prompt I get the value modulo 256.

/* prog.c */
int main(...) { return 257; }

--

> ./prog.e
> echo $?  
1
  • Why don't I see the whole integer?
  • Where is this behavior documented?
  • How can I get the whole 32-bit value to the shell?
ysap
  • 7,723
  • 7
  • 59
  • 122
  • 3
    Return values are by definition error codes. You cannot use the return value to communicate some other numeric value, it is *necessarily* used to indicate success (0) or an error (non-zero). If your intent is to output some kind of count or other non-zero numeric value during a *successful* execution, you must write it to STDOUT. – user229044 Nov 10 '11 at 16:36
  • Thanks, @meagar. I need this as a temporary hack on some non-production code I work on - to verify my embedded code development. I understand the caveat you mention, but yet, it does not answer my question. – ysap Nov 10 '11 at 16:41
  • That is why it is a comment, not an answer. Comments are not *supposed* to answer questions. Temporary hack or otherwise, you aren't going to be able to ahold of the number you're returning. You will have to output it to STDOUT. – user229044 Nov 10 '11 at 16:42
  • 3
    It's not *necessarily* used to indicate success or error. 0 = success, other = faliure is a convention only. – JeremyP Nov 10 '11 at 16:46
  • @meager - yes, after reading the answer posted later, I understood my misfortune. – ysap Nov 10 '11 at 16:46
  • @JeremyP A convention used by pretty much every program since before I was born, and that ancient things such as built-in conditionals in shells assume to be true for all programs. I call that a *standard*. – Camilo Martin Jun 16 '14 at 05:37

3 Answers3

11

When a program exits, it can return to the parent process a small amount of information about the cause of termination, using the exit status. This is a value between 0 and 255 that the exiting process passes as an argument to exit.

http://www.gnu.org/s/hello/manual/libc/Exit-Status.html

alternatively:

http://en.wikipedia.org/wiki/Exit_status

came from "posix return codes" and "c return codes" respective Google searches.

Doug Moscrop
  • 4,479
  • 3
  • 26
  • 46
4

The explanation is right at the top of man exit:

   The  exit() function causes normal process termination and the value of
   status & 0377 is returned to the parent (see wait(2)).

In other words, only the lowest 8 bits are propagated to the parent process.

In this respect, returning the exit code from main() is no different to passing it to exit().

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Thanks. I actually looked in the `man bash` page but couldn't find that there. I guess b/c I was doing C I did not think of looking at the `exit` page. – ysap Nov 10 '11 at 16:45
2

The return status is explained (sort of) in the wait and related syscalls.

Basically:

WEXITSTATUS(stat_val)
If the value of WIFEXITED(stat_val) is non-zero, this macro evaluates to the low-order 8 bits of the status argument that the child process passed to _exit() or exit(), or the value the child process returned from main().

So it's limited to 8 bits. You can't portably get more than that. (With Linux kernel 2.6.9 and above, waitid(2) can be used to obtain the full 32 bits.)

Community
  • 1
  • 1
Mat
  • 202,337
  • 40
  • 393
  • 406