mSatyam
mSatyam

Reputation: 541

How system function in C works

I have read that system function make use of execl, fork and wait functions internally. So, I tried to simulate working of system without using it. But I am not able to achieve the same working.

When we call a program using system function the code below(after) system() function call also executes. So to simulate system function i wrote this code below:

int main()
{
    printf("In controller Start: %d\n\n",getpid());
    system("./prog1");
    printf("Forking New Process %d\n\n",fork());
    printf("Process Id: %d\n\n",getpid());
    execl("./infinite",0);
    printf("In controller End\n\n");
    return 0;
}

In the above code after running "infinite" program the last line does not get printed. i.e. printf("In controller End\n\n");

What to do in order to print the last line and also execute the "infinite" program without using system function.

It would be great if someone can explain the step by step working of system function like which function is called by system first and so on.

Why execution is not continuing to last line like it must have did if we made a simple function call other than execl.

Foot notes:- infinite: is a binary file created using C code.

Upvotes: 3

Views: 1730

Answers (6)

Some programmer dude
Some programmer dude

Reputation: 409472

The last line doesn't get printed because it is never executed. The execl function never returns if everything went okay, instead it replaces your program with the one in the call.

I highly recommend you read the manual pages for fork and execl.


In short, fork splits the current process into two, and returns differently depending on if it returns to the parent or the child process. In the child process you then does your exec call, while the parent process continues to do what it wants. The parent must however wait on the child process to finish, or the child process will become what is called a "zombie" process.

In your code, both the parent and the child processes calls exec.

Upvotes: 5

Dave Costa
Dave Costa

Reputation: 48131

When you call fork(), both the parent and child process continue executing the same code from that point, but the return value of fork() is different for each. Generally you would do some conditional logic based on that return value.

I would imagine that system() does something like this:

int childpid = fork();
if (childpid) {
  /* This is the parent */
  wait( childpid );
} else {
  /* This is the child */
  execl( program_name );
}

Since execl() replaces the current executable with a new one, the child will run that executable then end. The parent will wait for the child to complete then continue.

Upvotes: 2

mf_
mf_

Reputation: 625

this is basis of fork

/*previous code*/
if((cpid=fork())<0){
    printf("\n\tFORK ERROR");
    exit(1);
}

if(cpid==0){        /*SON*/
    /*CODE FOR SON-your `execl("./infinite",0);` goes here*/

}else{              /*FATHER*/

    /*CODE FOR FATHER-your `printf("In controller End\n\n");` */

}

dont forget that when making a fork memory and variables are copied to the SON pid

Upvotes: 2

jbr
jbr

Reputation: 6258

In your example you do the same thing in both the parent and the child process. You have to check the return value of fork, which indicates if you are in the parent or the child, and then exec in the child, while you wait in your main process.

Upvotes: 2

Fabien
Fabien

Reputation: 13456

int main()
{
    int pid;

    printf("In controller Start: %d\n\n",getpid());

    system("./prog1");

    pid = fork();

    printf("Forking New Process %d\n\n",pid);
    printf("Process Id: %d\n\n",getpid());

    if (pid == 0) {  /* Son process : execute the command */
        execl("./infinite",0);
    } else {  /* Original process : keep working */
        printf("In controller End\n\n");
        return 0;
    }
}

Upvotes: 0

Will
Will

Reputation: 4713

You are not performing any kind of conditional statement based on the return value of fork. If you don't make sure that one process does the exec and one does something else then both will do the same thing.

You usually want to check against 0 and then execute the program you want to run. 0 signals that everything went ok and you are in the child process.

Upvotes: 1

Related Questions