0

I have to develop my own C function system. To do that, I use the call-system fork to create a child process and it has to execute the command given to system, calling exec.

What I've wrote seems to work fine (it compiles and executes without any error).

The problem concerns my function system's return (called mySystem in my code). For example, in my child process, if I give an nonexistent shell to exec (the latter returns -1), my child process stops with an exit code of -1 because I told it to do that. But : my parent process, which retrieves this exit code thanks to a wait(&status), returns... 255 and not -1 !

I don't understand why. I paid attention to use the macro WEXISTATUS in my mySystem's return.

Could you help me to know why my parent process doesn't return -1 (the exit code of its child process) please ? Thank you in advance.

My src (there are a lot of comments) :

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

pid_t pid;

int mySystem(char*);
int main(int argc, char* argv[]) {

    int result = mySystem("ls");
    fprintf(stdout, "%i", result);

    return 0;
}

int mySystem(char* command) {
    pid = fork();
    if(pid == -1) {
        perror("Fork");
        return -1; // An error occurred => return -1
    } else if (pid == 0) { // The child process will do the following
        execl("BLABLABLABLA MAUVAIS SHELL BLABLABLAA", "sh", "-c", command, NULL); // If this call doesn't fail, the following lines are not read
        perror("Exec"); // If (and only if) execl couldn't be called (bad shell's path, etc.)...
        exit(-1); // ..., we stop the child process and this one has an exit code equaled to -1
    }

    /*
     * NOW, the child process ended because... :
     * 1. Either because of our "exit(-1)" after the "perror"               (our source-code)
     * 2. OR because of an "exit(-1") of the command passed into the execl  (source-code of the execl's command)
     * 3. OR because of the "exit(0)" of the command passed into the execl  (source-code of the execl's command)
     */

    // The parent process will execute the following lines (child process ended)
    int status = -1;
    if(wait(&status) == -1) { // We store into the var 'status' the exit code of the child process : -1 or 0
        perror("Wait"); // Note that because we have only one process child, we don't need to do : while(wait(&status) > 0) {;;}
        return -1;
    }

    return WEXITSTATUS(status); // Our function mySystem returns this exit code
}
JarsOfJam-Scheduler
  • 2,809
  • 3
  • 31
  • 70
  • 1
    Possible duplicate of [What does WEXITSTATUS(status) return?](http://stackoverflow.com/questions/20465039/what-does-wexitstatusstatus-return) – Andrew Henle Jun 23 '16 at 11:46
  • What does the documentations say? What did you not understand in the documentation? – too honest for this site Jun 23 '16 at 11:54
  • Ah I read again the documentation, and I think my mistake is bound to "This consists of the least significant 8 bits"... Mmmh I can't return a positive value. I will cast the return to `signed char`. – JarsOfJam-Scheduler Jun 23 '16 at 11:58
  • BTW, [POSIX specifies](http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_08_02) the exit code for "program not found" in the shell as 127. – Mark Plotnick Jun 23 '16 at 14:54

1 Answers1

2

Look at the following picture: enter image description here

Where each of the 2 blocks is 8 bits (so total 16 bits). Now you pass exit(-1) which in binary using 8 bits is: 11111111 (the two-complement) that's why you get 255 using WEXITSTATUS(status).

Another example to be clear: let's suppose to call exit(-6), -6 in binary two-complement is 11111010 that correspond to 250, if you make your program run you will see 250 printed on stdout.

mik1904
  • 1,335
  • 9
  • 18
  • Thank you very much. Is the "status" a "return in main" and an "exit" value ? I think so ; thus, what is the error code ? Is it "errno" ? I thought it could be a "return in main" or "exit" value too. – JarsOfJam-Scheduler Jun 24 '16 at 17:14
  • No the exit() call doesn't set the errno value I suggest you to look bere for the errno http://stackoverflow.com/questions/11699596/how-to-set-errno-value – mik1904 Jun 24 '16 at 17:59
  • Thank you, I already knew this. I just don't understand clearly the vocabulary used for processes (status and error code in the image). I thought "status" was the process' one (so not the return-in-main/exit's value) and the error code, errno. But it's not. – JarsOfJam-Scheduler Jun 24 '16 at 21:45