Questions à choix multiples

La matière couverte cette semaine couvre les processus.

Question 1. fork(2)

L’appel système fork(2) permet de créer une copie du processus courant. Un étudiant a écrit le fragment de code ci-dessous se trouvant dans la fonction main:

int n=...
for(int i=0; i<n ; i++) {
  printf("i=%d\n",i);
  pid_t pid;
  pid=fork();
  if (pid==-1) {
    perror("fork");
    exit(EXIT_FAILURE);
  }
  else {
    if(pid!=0) {
        printf("Running in %d\n",pid);
    }
  }
}
return(EXIT_SUCCESS);
Lors de l’exécution de ce programme, combien de processus sont créés en fonction de la valeur de n ?

Lorsque n est initialisé à 2, quatre processus sont créés.

Lorsque n est initialisé à 3, huit processus sont créés.

Lorsque n est initialisé à 2, deux processus sont créés.

Lorsque n est initialisé à 2, trois processus sont créés.

Lorsque n est initialisé à 3, trois processus sont créés.

Lorsque n est initialisé à 3, quatre processus sont créés.

Question 2. execve(2)

Parmi les extraits de programme ci-dessous, lequel est un appel correct à execve(2) pour lancer le programme /bin/echo avec comme arguments -n et SINF1252 ?
char *arguments[]={"echo", "-n", "SINF1252", NULL};
char *environnement[]={"LANG=fr",NULL};
int err=execve("/bin/echo", arguments, environnement);
if(err!=0) {
  perror("execve");
  exit(EXIT_FAILURE);
}
char prog[]="echo";
char param1[]="-n";
char param2[]="SINF1252";
char *arguments[4];
arguments[0]=prog;
arguments[1]=param1;
arguments[2]=param2;
arguments[3]=NULL;
char *environnement[]={"LANG=fr", NULL};
int err=execve("/bin/echo", arguments, environnement);
if(err!=0) {
  perror("execve");
  exit(EXIT_FAILURE);
}
char arguments[]={"echo", "-n", "SINF1252", NULL};
char environnement[]={"LANG=fr",NULL};
int err=execve("/bin/echo", arguments, environnement);
if(err!=0) {
  perror("execve");
  exit(EXIT_FAILURE);
}
char prog[]="echo";
char param1[]="-n";
char param2[]="SINF1252";
char *arguments[4];
arguments[0]=prog;
arguments[1]=param1;
arguments[2]=param2;
arguments[3]=NULL;
char *environnement[]={"LANG=fr"};
int err=execve("/bin/echo", arguments, environnement);
if(err!=0) {
  perror("execve");
  exit(EXIT_FAILURE);
}
char prog[]="echo";
char param1[]="-n";
char param2[]="SINF1252";
char *arguments[3];
arguments[0]=prog;
arguments[1]=param1;
arguments[2]=param2;
char *environnement[]={"LANG=fr"};
int err=execve("/bin/echo", arguments, environnement);
if(err!=0) {
  perror("execve");
  exit(EXIT_FAILURE);
}
char *arguments[]={"echo", "-n", "SINF1252"};
char *environnement[]={"LANG=fr"};
int err=execve("/bin/echo", arguments, environnement);
if(err!=0) {
  perror("execve");
  exit(EXIT_FAILURE);
}

Question 3. execve(2)

L’appel système execve(2) permet d’exécuter un programme en remplaçant le programme en cours d’exécution par celui se trouvant sur disque dont le nom est spécifié. Un étudiant a écrit le programme ci-dessous pour tester execve(2) :

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

extern char **environ;

int main (int argc, char *argv[])  {

 int n=...
 int i=0;
 for(i=0;i<n;i++) {
   sleep(1);
   printf("%d\n",i);
   int err=execve(argv[0], argv, environ);
   if(err!=0) {
     perror("execve");
     exit(EXIT_FAILURE);
   }
 }
 return(EXIT_SUCCESS);
}

Lorsque n est initialisé à 3, le programme ne s’arrête jamais et affiche :

0
0
0
...

Lorsque n est initialisé à 2, le programme ne s’arrête jamais et affiche :

0
0
0
...

Lorsque n est initialisé à 3, le programme affiche :

0
1
2

Lorsque n est initialisé à 2, le programme affiche :

0
1

Lorsque n est initialisé à 2, l’appel à execve(2) est erroné et le programme s’arrête.

Lorsque n est initialisé à 3, l’appel à execve(2) est erroné et le programme s’arrête.

Question 4. Utilisation de waitpid(2)

L’appel système waitpid(2) permet à un processus d’attendre les valeurs de retour de ses processus fils. Un étudiant a écrit un programme qui lance de nombreux processus et veut faire une boucle qui permet de récupérer tous les processus fils qu’il a créé. Parmi les fragments de code ci-dessous, un seul est correct. Lequel ?
int fils;
int done=false;
while(!done) {
  int status;
  fils=waitpid(0,&status,0);
  if( (fils==-1) && (errno==ECHILD) )
    done=true;
}
int fils;
int done=false;
while(!done) {
  int status;
  if( (waitpid(0,&status,0)==-1) && (errno==ECHILD) )
    done=true;
}
int fils;
int done=false;
int status;
while(waitpid(0,status,0)!=0) {
  if( (fils==-1) && (errno==ECHILD) )
    done=true;
}
int fils;
int done=false;
while(!done) {
  int status;
  fils=waitpid(getpid(),&status,0);
  if( (fils==-1) && (errno==ECHILD) )
    done=true;
}

Question 5. Récupération du résultat d’un processus avec waitpid(2)

Un étudiant souhaite récupérer le résultat du processus pid qu’il a créé en faisant fork(2) et l’afficher sur stdout. Parmi les fragments de programmes ci-dessous, un seul est correct. Lequel ?
int status;
int p=waitpid(pid,&status,0);
if(p==-1) {
    perror("wait");
    exit(EXIT_FAILURE);
}
if(WIFEXITED(status)) {
  printf("Le processus a retourne %d\n",WEXITSTATUS(status));
}
int status;
int p=waitpid(pid,status,0);
if(p==-1) {
    perror("wait");
    exit(EXIT_FAILURE);
}
printf("Le processus a retourne %d\n",WEXITSTATUS(status));
int status;
int p=waitpid(pid,&status,0);
if(p==-1) {
    perror("wait");
    exit(EXIT_FAILURE);
}
printf("Le processus a retourne %d\n",p);
int *status;
int p=waitpid(pid,status,0);
if(p==-1) {
    perror("wait");
    exit(EXIT_FAILURE);
}
printf("Le processus a retourne %d\n",p);

Verifiez vos réponses