Partiel de Systèmes -- Master 1-II -- Nov. 2007

Exercice

 /* programme a.c de binaire a */
 main(int argc,char *argv[]) {
  fork();
  fork();
  fork();
}
  1. Combien de processus sont-ils créés à l'exécution du programme a ?
  2. Dessinez l'arbre des processus engendrés
  3. Même question si l'on remplace le second appel à fork() par un appel à execlp(argv[0],argv[0],NULL); ?
  4. Même question si c'est le premier appel à fork() que l'on remplace par un appel à execlp(argv[0],argv[0],NULL); ?

Exercice

/* programme b.c de binaire b */
#define N ... /* Une certaine valeur */
main() {
  int i=0;
  while (fork()==0 && i++<N);
  printf("%d\n",i);
}
Quels affichages peuvent être possiblement engendrés par l'exécution de b ? Expliquez.

Exercice

Soit la fonction de prototype int fils(int n,void (*g)(void));.
  1. Écrire le code de cette fonction de sorte que n processus soient créés et exécutent en concurrence la fonction g passée en argument.
  2. Écrire le code de cette fonction de sorte que n processus soient créés et exécutent l'un après l'autre la fonction g passée en argument.

Exercice

Écrire une fonction de prototype void fonc(char *c[2],char *f[2]); réalisant par appel à des fonctions systèmes (system() est interdit d'usage) l'équivalent de la commande shell: c0<f0 | c1>f1 (où ci est la chaîne contenue dans c[i] et fi la chaîne contenue dans f[i]).

Exercice

#include <signal.h>
static int ns=0;
void f(int s) { ns++; }
int main() {
  int i; struct sigaction sa; int s;
  sa.sa_handler=f; sa.sa_flags=0; sigemptyset(&(sa.sa_mask));
  sigaction(SIGUSR1,&sa,NULL);
  if (fork()==0) { for (i=0; i<10000; i++) kill(getppid(),SIGUSR1); exit(0); }
  else while (wait(&s)==-1 && errno==EINTR);
  printf("%d\n",ns);
}
Quel est l'affichage produit par ce programme ? Expliquez.

Exercice

Vous souhaitez que l'exécution d'une certaine fonction f ne puisse être interrompue par le signal SIGUSR1:
  1. Quelle(s) fonction(s) système connaissez-vous permet(tent) d'obtenir le comportement attendu ?
  2. Écrire la partie de code précédent et/ou suivant l'appel à f, pour faire en sorte qu'un exemplaire du signal émis pendant l'exécution ne soit pas perdu;
  3. Écrire la partie de code précédent et/ou suivant l'appel à f, pour faire en sorte qu'un exemplaire du signal soit perdu.