clinuxunixsystems-programming

Managing processes in C


I am trying to test how to create and manage processes with a program what should create a process and execute a command 2 times (each time executing a different command).

What I am trying to do exactly:

Weirdly, when I execute 1 command, it works fine but when I execute the routine twice, the 2nd command is being executed twice also. Meaning that 3 commands get executed.

Here is my code:

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



void launch_command(char command[]) {
  pid_t pid;

  pid = fork();
  if(pid==0)

  {
    printf("Creating process %d from %d\n", getpid(),getppid());
    system(command);
    exit(0);

  }
  else {
    if ((pid = fork()) == -1)
       perror("Error while creating a new process");
  }

}

int main () {
  printf("Root process: %d\n",getpid());

  launch_command("/bin/ls -l");
  while(wait(NULL) >= 0);

  launch_command("/bin/date");
  while(wait(NULL) >= 0);

  return 0;

}

The output:

$ ./a.out 
Root process: 8924
Creating process 8925 from 8924
Creating process 8928 from 8926
Sun 13 Nov 2022 23:54:51 EST
total 128
-rwxr-xr-x  1 gg  staff  49784 13 Nov 23:54 a.out
-rw-r--r--  1 gg  staff   3499 11 Nov 10:59 create_process.c
Creating process 8931 from 8924
Sun 13 Nov 2022 23:54:51 EST

Could someone explain me this behaviour?

The desired result should be:

$ ./a.out 
Root process: 8924
Creating process 8925 from 8924
total 128
-rwxr-xr-x  1 gg  staff  49784 13 Nov 23:54 a.out
-rw-r--r--  1 gg  staff   3499 11 Nov 10:59 create_process.c
Creating process 8931 from 8924
Sun 13 Nov 2022 23:54:51 EST

Solution

  • As pointed out in the comments, the second call to fork is creating too many processes.

    After the first call to launch_command returns, there will be both a parent process and a freshly made child process. They will both call the second launch_command function, spawning two more processes that call system, and then an additional process each, that again return from the function as well.

    There will be four total processes that execute the second while loop.

    Remove the second fork call, and use the same value of pid again to check for failure.

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    void launch_command(const char *command)
    {
        pid_t pid = fork();
    
        if (0 == pid) {
            printf("Creating process %d from %d\n", getpid(), getppid());
            system(command);
            exit(EXIT_SUCCESS);
        } else if (-1 == pid) {
            perror("Error while creating a new process");
        }
    
        while (wait(NULL) >= 0);
    }
    
    int main(void)
    {
        printf("Root process: %d\n", getpid());
    
        launch_command("/bin/ls -l");
        launch_command("/bin/date");
    }