# Return from the parent process code or common code

In this program, the parent process creates a child process, then the child executes ls -l. The parent process waits for the child process to complete and then returns using return 0;.

/*child's output redirected to file*/
/*sps, 6262015*/

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

/*Start*/
int main(void)
{
//Create a child process
int ret = fork();
if(ret<0)
exit(1);
/*Child code*/
else if(ret==0)
{
char *argv[] = {"ls", "-l", NULL};

//Execute 'ls -l'
execvp(argv[0], argv);
}
/*Parent code*/
else if(ret>0)
{
int status;
int w = waitpid(ret, &status, WUNTRACED | WCONTINUED);
}
/*Where to place this ???*/
return 0;
}


Although above code works correctly, I am not sure where to place the return 0; statement. For instance, in the above code it is at the end so it is common to both the parent and child processes.

But in this program, the child process calls execvp, so it will never reach the last line of the code which has return 0;. So, taking this into account, can I place the return 0; inside the parent code as below?

 /*Parent code*/
else if(ret>0)
{
int status;
int w = waitpid(ret, &status, WUNTRACED | WCONTINUED);
return 0;
}


Is there any advantage or disadvantage to putting the return 0; statement inside the parent process code?

As for all these functions: Take a look at the man page. It states that execvp (respectively execve) will return on error with return value -1 and with errno set.

Since you are already handling such errors with fork you might as well do it here and either exit(1), or fall through to the end.

/*child's output redirected to file*/
/*sps, 6262015*/


I don't know what this comment is. All other comments in the file are completely useless as they state the obvious.

/*Headers*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

#include<sys/wait.h>
#include<sys/types.h>


sys/ headers should go first. The order you include these two is incorrect, which you can check with the manpage.

/*Start*/
int main(void)
{
//Create a child process


This useless comment does not match the style of previous useless comments.

    int ret = fork();
if(ret<0)


Consider adding spaces: ret < 0

            exit(1);


This should state the error with e.g. perror.

    /*Child code*/
else if(ret==0)
{
char *argv[] = {"ls", "-l", NULL};


It is a standard idiom to name main's argument array as argv, so this is a terrible abuse of the name.

            //Execute 'ls -l'


Not only useless, but actively harmful comment waiting to get out of sync with the content of the table.

            execvp(argv[0], argv);
}
/*Parent code*/
else if(ret>0)


By this time ret has to be > 0, so this can be a mere else.

    {
int status;
int w = waitpid(ret, &status, WUNTRACED | WCONTINUED);


Incorrect. waitpid can return prematurely due to an error, which is unchecked.

    }
/*Where to place this ???*/
return 0;


The question arises in the first place because the code looks incorrect. The child should _Exit with an error if execvp fails, which alone makes this question obsolete. Another thing to note is error handling in the parent process - don't you want to note somehow that ls failed?

I assume this is not a standalone tool in its entirety, if it is, it makes no sense whatsoever, as in the worst case it should exec ls -l directly, but preferably whatever executes it would do ls -l on its own (and that is assuming execing ls -l even makes sense).

}

• The first comment is his username plus a timestamp, but yeah, not useful. Could you add a reference for the order of includes? – ferada Jun 28 '15 at 12:58