C, exit and pcntl_wait produce multiples of 256, why?

I wrote a test to find out if I can reliably determine the integer value of the exit code with wait .

Questions

1. Why is the exit code multiplied by 256?
2. Is exit() , wait() , OS, or something else doing multiplication?

Code to reproduce the problem.

 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> // implementation is correct but irrelevant to the question int compareInt(const void* a, const void* b); int main(void) { pid_t pids[6]; int i; for (i = 0; i < 6; i++) { pid_t pid = fork(); pids[i] = pid; if (pid == 0) { exit(i); } } int codes[6]; do { i--; wait(&codes[i]); } while (i > 0); const size_t num_elem = 6; qsort(codes, num_elem, sizeof(int), compareInt); for (i = 0; i < 5; i++) { printf("%d, ", codes[i]); } printf("%d\n", codes[5]); return 0; } 

Outputs: 0, 256, 512, 768, 1024, 1280

As it turned out, I should use wifexited(), wifstopped(), wifsignaled(), wexitstatus(), wtermsig(), or wstopsig() to determine the exit status.

Also, the same behavior is reproduced in PHP (where I first came across it)

 $pids = []; foreach (range(0, 5) as $i) { $pids[] = $pid = pcntl_fork(); if ($pid === 0) { exit($i); } } $exit_codes = []; do { pcntl_wait($exit_codes[]); array_pop($pids); } while (count($pids) > 0); sort($exit_codes); echo implode(', ', $exit_codes) . "\n"; 

Outputs: 0, 256, 512, 768, 1024, 1280

If that matters, I run Ubuntu 14.04 and man wait says I have WAIT(2)

+6
source share
2 answers

The reasons why you see these results is that the return value from wait() encoded and contains information about how and why the process was stopped, as well as the actual exit status; therefore convenient macros are supplied to test certain parts of the return value.

The definition of WEXITSTATUS(status) can be found in sys/wait.h and may look like this:

 #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) 

Or that:

 #define WEXITSTATUS(status) (((status) >> 8) & 0x000000ff) 

So you see the multiplication because:

 exit(1) -> 0x0100 (256) exit(2) -> 0x0200 (512) 

In PHP, you would use pcntl_wexitstatus() to accomplish the same thing; if the process was killed due to a signal, there would be no exit status, and you would need to use pcntl_wtermsig() to determine the signal used to kill it.

+11
source

The return value of wait() encodes several pieces of information. There are macros defined to highlight results and get just what you need. e.g. WEXITSTATUS(result_of_wait) .

+1
source

Source: https://habr.com/ru/post/978650/


All Articles