I have written a code for checking vfork in unix. But I am getting the ambiguous behavious.
When I am using exit(0) in child process , output is fine i.e;
output :-
Before fork
I am a child
My name is parent child PID=> 23133 kValue => 2
]
But when I am using "return 0" in place of exit(0) , program keeps on executing and each time a new process is created infinitely.
output :-
Before fork
I am a child
My name is parent child PID=> 23143 kValue => 2
Before fork
I am a child
My name is parent child PID=> 23144 kValue => 2
Before fork
I am a child
..... so on

Can anyone explain me the reason of this behavior please ? I know in case of vfork same memory space is shared between parent and child but I am not able to understand this behavior. Thanks a lot in advance.
Here is the code that I have written -->

#include <stdio.h>
#include <stdlib.h>

int main()
{
        int pid,k=1;

        printf("Before fork \n");

        pid = vfork();


        if(pid == 0) {
                printf("I am a child \n");
                k++;
                return 0; // On exit(0) works fine.
        } else
                sleep(3);

        printf("My name is parent child PID=> %d kValue => %d\n",pid,k);
        return 0;
}

Both are wrong and invoke undefined behavior. You should be calling _exit(0) because it doesn't perform any cleanup in the child, it just ends the process. Since vfork() shares process memory between parent and child, letting the child perform process cleanup is a Bad Thing™.

Technically, the way you're using vfork() is undefined regardless of your exit strategy, as allowed actions in the child are severely limited:

(From POSIX.1) The vfork() function has the same effect as fork(2), except
that the behavior is undefined if the process created by vfork() either
modifies any data other than a variable of type pid_t used to store the return
value from vfork(), or returns from the function in which vfork() was called,
or calls any other function before successfully calling _exit(2) or one of the
exec(3) family of functions.

In other words, both the printf() call and modifying k in the child are not allowed. I'd suggest you forget that vfork() exists and simply use fork().

Thanks Narue. I understand the behavior of the program is because of the update by the child progess but if I write the following code

#include <stdio.h>
#include <unistd.h>

int main()
{
        int pid,k=1;

        printf("Before fork \n");

        pid = vfork();


        if(pid == 0) {
                printf("I am a child \n");
                _exit(0);
        } else
                sleep(3);

        printf("My name is parent child PID=> %d kValue => %d\n",pid,k);
        return 0;
}

Last printf statement should not execute because child has returned to kernel using _exit(0); flushing all open streams and closing any open file descriptor. But why am I getting the following output :-

Before fork
I am a child
My name is parent child PID=> 23209 kValue => 1

Last printf statement should not execute because child has returned to kernel using _exit(0); flushing all open streams and closing any open file descriptor.

IIRC, most versions of vfork() copy file descriptors, so closing them in the child is safe. However, I'm not 100% sure, so once again I'll recommend using fork() instead of vfork(). The potential performance benefits aren't worth the risk.

Edited 5 Years Ago by Narue: n/a

Hmm , I understand it now. Thanks a lot Narue. If child process is copying the descriptor their should not be such problem.

This question has already been answered. Start a new discussion instead.