Implementation of system() function in Linux using fork() , exec() and waitpid() system calls I have written the code for implementation of  system() function using fork(), exec() and waitpid(). Could someone please review this code and provide feedback. Thanks a lot.


#include&lt;stdio.h&gt;
#include&lt;string.h&gt;
#include&lt;unistd.h&gt;
#include&lt;sys/types.h&gt;
#include&lt;sys/wait.h&gt;
#include&lt;error.h&gt;
#include&lt;errno.h&gt;
#define size 30

char *get_command(int argc, char *argv[]);
int my_system(const char *command);

int my_system(const char *command)
{
    pid_t pid;
    int wstatus  = 0;
    int ret = 0;

    if (command == NULL)
        return 1;
    pid = fork();
    if (pid == -1) {
        return -1;
    } else if (pid == 0) {
        ret = execle("/bin/sh", "sh", "-c",command, (char *)NULL);
        if (ret == -1)
            return wstatus;

    } else {
        ret = waitpid(-1, &amp;wstatus, 0);
        if (ret == -1)
            return -1;
    }
    return wstatus;
}

char *get_command(int argc, char **argv)
{
    int i = 0;
    static char command[size];

    if (argc == 1)
        return NULL;

    strcpy(command, argv[1]);
    for (i = 2; i &lt; argc; i++) {
        strcat(command, " ");
        strcat(command, argv[i]);
    }
    return command;
}

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

    command = get_command(argc, argv);
    ret = my_system(command);
    if (ret == 1)
        printf("Command is NULL, shell is available\n");
    else if (ret == -1)
        printf("Child process could not be created or error in the wait system call\n");
    else if (ret == 127)
        printf("The Child process could not be executed in the shell\n");
    else
        printf("The status of the child process is :%d\n", ret);
    return 0;
}
```
I think the biggest mistake is the return after the exec.  If you reach that point, and return, you have returned to the calling function in the subprocess.  Use exit() instead.  Note that the value you pass to exit should come out in wstatus.  Note also, if execle returns, it must have failed, so don't even both checking the status.  (For this to happen, the path must be invalid.  Change it for testing, and set it back afterwards.)

The use of execle() is a mistake.  You didn't pass an environment.  Use execl() instead.

You have at least one case where you return -1 without having set errno.  Set errno.  (Many cases, something else has already set errno for you.)

One other thing that can bite you:  If the caller has made another subprocess, and it terminates while you are waiting for your subprocess, you will return the result of the wrong subprocess.  To fix this, pass the pid as the first parameter to waitpid().

As a style issue, I would recommend moving wstatus completely into the last block.  And nothing should ever come out of the compound if statement.

As a personal style point: I tend to use switch to test for -1, 0, or other.  if statements work equally well.