C program to use clone system call

Introduction to "Clone" system call

 clone() creates a new process, in a manner similar to fork(2).

     Unlike fork(2), clone() allows the child process to share parts of its execution context with the calling process, such as the memory space, the table of file descriptors, and  the
 table of signal handlers. 

     The main use of clone() is to implement threads: multiple threads of control in a program that run concurrently in a shared memory space.

     When  the child process is created with clone(), it executes the function fn(arg).  (This differs from fork, where execution continues in the child from the point of the fork call.)  The fn argument is a pointer to a function that is called by the child process at the beginning of its execution.  The arg argument is passed to the fn function.

      When the fn(arg) function application returns, the child process terminates.  The integer returned by fn is the exit code for the child process.  The child process may also  termi‐
nate explicitly by calling exit(2) or after receiving a fatal signal.

       The  child_stack  argument  specifies  the  location of the stack used by the child process.  Since the child and calling process may share memory, it is not possible for the child process to execute in the same stack as the calling process.  The calling process must therefore set up memory space for the child stack  and  pass  a  pointer  to  this  space  to clone().   Stacks  grow downward on all processors that run Linux (except the HP PA processors), so child_stack usually points to the topmost address of the memory space set up for the child stack.

C program


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

void *pchild_stack =  NULL;

int fn(void *arg)
{
    strcpy((char *)pchild_stack, "aricent");
    printf("I am the child my pid :%d parent's parent pid : %d pchild_stack: %s \n"
            ,getpid() , getppid(), (char *)pchild_stack);

    return 0;
}

void main(int argc, char *argv[])
{
    pchild_stack = malloc(1024 * 1024);
    if ( pchild_stack == NULL ) {
        printf("ERROR: Unable to allocate memory.\n");
        exit(EXIT_FAILURE);
    }

    strcpy((char *)pchild_stack, "google");
    printf("I am the parent my pid :%d parent's parent pid : %d pchild_stack: %s\n",
            getpid() , getppid(), (char *)pchild_stack);

    int pid = clone(fn, (char *)pchild_stack + (1024 * 1024), SIGCHLD, argv[1]);
    if ( pid < 0 ) {
        printf("ERROR: Unable to create the child process.\n");
        exit(EXIT_FAILURE);
    }

    printf("INFO: Child process terminated.\n");
    wait(NULL);


    printf("I am the parent my pid :%d parent's parent pid : %d pchild_stack: %s\n",
            getpid() , getppid(), (char *)pchild_stack);
    free(pchild_stack);
    pchild_stack = NULL;

}


Output

Neelkanth_98$ ./a.out
I am the parent my pid :29371 parent's parent pid : 28022 pchild_stack: google
INFO: Child process terminated.
I am the child my pid :29372 parent's parent pid : 29371 pchild_stack: aricent
I am the parent my pid :29371 parent's parent pid : 28022 pchild_stack: google