Forum Programmation.c Questions d'exam

Posté par .
Tags : aucun
0
24
juin
2007
Bonsoir à tous,

je passe à la repêche un examen de programmation système (demain matin 8h30...) et nous n'avons pas eu de correction de l'exam de première session. J'ai donc quelques questions à vous poser :)

Exercice 1
Repondre par vrai ou faux:
1/ un processus dont le propriétaire est 1000 à les droits de l'utilisateur 1000.

2/Une ecriture sur un tube sans lecteurs en mode bloquant provoque l'envoi du signal SIGPIPE au processus ecrivain, même si celui-ci a la place d'ecrire dans le tube.

3/ Un processus n'effectuant aucun appel systeme n'est pas interruptible par un signal, car les signaux ne sont délivrés que lors du passage en mode noyau.

4/ La terminaison d'un processus provoque la terminaison de tous ses fils.

5/ En général, un shell interactif ignore ou install son propre traitant pour le signal SIGINT.

6/ En terme d'espace disque, la création réussie d'un lien physique (par le shell: ln titi toto ou par l'appel link) est plus couteuse que la création réussie d'un lien symbolique.


Exercice 2
Répondre briévement:
1/Expliquer pourquoi il est en général préférable d'utiliser les fonctions d'entrées-sorties de haut niveau plutot que celle de bas niveau?

2/ Qu'est-ce qu'une fonction réentrante? Illustrer sur un exemple le type de problème que peut poser l'utilisation de fonctions non réentrantes.

3/ Quelle différence y'a-t-il entre attente active et attente passive? Donner un exemple de chacune des deux.


Exercice 3
On suppose que rep est un répertoire appartenant à l'utilisateur qui lance les commandes suivantes:
$ bin/ls rep
titi toto
$bin/ls -l rep
ls: titi: permission denied
ls: toto: permission denied
On supose que les permissions n'ont pas changé entre les 2 commandes.
1/ Quels appels systèmes ou bibliothèque pourrait-on utiliser pour ecrire un programme dont le lancement équivaut à ls rep? Quels sont les permissions nécessaire pour que cette commande réussise?

2/ Même questions pour la commande ls -l rep

3/ Que peut-on en déduire pour les permissions positionnées sur le répertoire rep?


Merci à tous pour votre aide ;-)
  • # Réponse (a vérifier)

    Posté par (page perso) . Évalué à 1.

    Exercice 1
    Repondre par vrai ou faux:
    1/ un processus dont le propriétaire est 1000 à les droits de l'utilisateur 1000.
    Vrai

    2/Une ecriture sur un tube sans lecteurs en mode bloquant provoque l'envoi du signal SIGPIPE au processus ecrivain, même si celui-ci a la place d'ecrire dans le tube.
    Vrai (pas sur)

    3/ Un processus n'effectuant aucun appel systeme n'est pas interruptible par un signal, car les signaux ne sont délivrés que lors du passage en mode noyau.
    Faux (on peux toujours envoyer un kill -9)

    4/ La terminaison d'un processus provoque la terminaison de tous ses fils.
    Vrai (quoique vérifie dans quel cas il passe zombi et dans quel cas il quitte proprement)

    5/ En général, un shell interactif ignore ou install son propre traitant pour le signal SIGINT.
    Vrai

    6/ En terme d'espace disque, la création réussie d'un lien physique (par le shell: ln titi toto ou par l'appel link) est plus coûteuse que la création réussie d'un lien symbolique.
    Vrai (12 octet contre 14k pour le lien physique)

    Exercice 2
    Répondre briévement:
    1/Expliquer pourquoi il est en général préférable d'utiliser les fonctions d'entrées-sorties de haut niveau plutot que celle de bas niveau?
    Meilleur perf, meilleures possibilité donnée au compilo pour optimiser le tout.

    2/ Qu'est-ce qu'une fonction réentrante? Illustrer sur un exemple le type de problème que peut poser l'utilisation de fonctions non réentrantes.
    Si mes souvenirs sont bon, c'est une fonction qui repartira au même endroit si elle a été interrompue par un signal.

    3/ Quelle différence y'a-t-il entre attente active et attente passive? Donner un exemple de chacune des deux.
    Dans quel contexte ?
    sleep (attente passive)
    select(attente active)

    Exercice 3
    On suppose que rep est un répertoire appartenant à l'utilisateur qui lance les commandes suivantes:
    $ bin/ls rep
    titi toto
    $bin/ls -l rep
    ls: titi: permission denied
    ls: toto: permission denied
    On supose que les permissions n'ont pas changé entre les 2 commandes.
    1/ Quels appels systèmes ou bibliothèque pourrait-on utiliser pour ecrire un programme dont le lancement équivaut à ls rep? Quels sont les permissions nécessaire pour que cette commande réussise?
    getdents()

    2/ Même questions pour la commande ls -l rep
    getdents() + boucle + stats()

    3/ Que peut-on en déduire pour les permissions positionnées sur le répertoire rep?
    Je vois pas comment c'est possible.
    Parce que si il peux lister c'est qu'il a les droits x (traverser le répertoire) et r (lire la liste des fichiers)
    Et ls -l donnera la liste de ces mêmes fichiers avec un descriptif long.

    A part si on a joué avec chattr ou retiré des syscalls (genre retirer le droit stats sur les fichiers en question).
    • [^] # Re: Réponse (a vérifier)

      Posté par (page perso) . Évalué à 2.

      2/ Qu'est-ce qu'une fonction réentrante? Illustrer sur un exemple le type de problème que peut poser l'utilisation de fonctions non réentrantes.
      Si mes souvenirs sont bon, c'est une fonction qui repartira au même endroit si elle a été interrompue par un signal.


      Non, c'est une fonction qui peut être appelée par plusieurs threads concurrents.

      http://fr.wikipedia.org/wiki/R%C3%A9entrance
    • [^] # Re: Réponse (a vérifier)

      Posté par (page perso) . Évalué à 2.

      3/ Quelle différence y'a-t-il entre attente active et attente passive? Donner un exemple de chacune des deux.
      Dans quel contexte ?
      sleep (attente passive)
      select(attente active)


      Non.

      http://fr.wikipedia.org/wiki/Attente_active
    • [^] # Re: Réponse (a vérifier)

      Posté par . Évalué à 2.

      le dimanche 24 juin à 23:48
      Bonsoir à tous,

      je passe à la repêche un examen de programmation système (demain matin 8h30...)


      Ah, ouais ! quand même ! :-)

      2/Une ecriture sur un tube sans lecteurs en mode bloquant provoque l'envoi du signal SIGPIPE au processus ecrivain, même si celui-ci a la place d'ecrire dans le tube.
      Vrai (pas sur)


      Non. C'est même à cela que servent les tubes nommés. A se donner rendez-vous de manière asynchrone. Par contre, il y a des chances de se prendre un SIGPIPE si le lecteur REFERME son handler.

      3/ Un processus n'effectuant aucun appel systeme n'est pas interruptible par un signal, car les signaux ne sont délivrés que lors du passage en mode noyau.
      Faux (on peux toujours envoyer un kill -9)


      Pas seulement. Même si tu fais un while(1);, ton processus pourra être préempté ! C'est à ça que servent les signaux. Et c'est pour cela que l'on peut faire un Ctrl-C dessus.

      4/ La terminaison d'un processus provoque la terminaison de tous ses fils. Vrai (quoique vérifie dans quel cas il passe zombi et dans quel cas il quitte proprement)


      Oui, c'est vrai, mais le processus peut prendre les devants pour s'émanciper. Par contre, cela n'a rien à voir avec les zombies, qui sont des processus morts mais qui ne peuvent être incinérés avant que le père n'ait reconnu le corps.

      6/ En terme d'espace disque, la création réussie d'un lien physique (par le shell: ln titi toto ou par l'appel link) est plus coûteuse que la création réussie d'un lien symbolique.
      Vrai (12 octet contre 14k pour le lien physique)


      Quoi ? O_O

      1/Expliquer pourquoi il est en général préférable d'utiliser les fonctions d'entrées-sorties de haut niveau plutot que celle de bas niveau? Meilleur perf, meilleures possibilité donnée au compilo pour optimiser le tout.


      Pas le compilateur, mais le système lui-même. En particulier, on permet au processus de rester en userland le maximum du temps et de limiter les appels au noyau.

      2/ Qu'est-ce qu'une fonction réentrante? Illustrer sur un exemple le type de problème que peut poser l'utilisation de fonctions non réentrantes.
      Si mes souvenirs sont bon, c'est une fonction qui repartira au même endroit si elle a été interrompue par un signal.


      Non. C'est une fonction qui, sans être explicitement récursive, sera quand même directement ou indirectement dépendante d'elle-même, ce qui fait qu'elle se mordra la queue. Exemple à la con :

      int fprintf (FILE * f, char * message)
      {
      if (f) /* Fichier ouvert ? */
      {
      Ecrire message
      }
      else fprintf (stderr,"Erreur : fichier non ouvert");
      }


      3/ Quelle différence y'a-t-il entre attente active et attente passive? Donner un exemple de chacune des deux.
      Dans quel contexte ?
      sleep (attente passive)
      select(attente active)


      Non plus. Ces deux fonctions sont toutes les deux passives et attendent le feu vert du système pour se réveiller. Une attente active est lorsque l'on provoque soit même une temporisation, ou bien lorsqu'on boucle bêtement en attendant qu'une condition soit remplie :

      while (!feu_vert); /* Attend le bon moment */.

      Pas la peine de dire que le programme en question va bouffer 100% du CPU.

      1/ Quels appels systèmes ou bibliothèque pourrait-on utiliser pour ecrire un programme dont le lancement équivaut à ls rep? Quels sont les permissions nécessaire pour que cette commande réussise?
      getdents()


      man getdents :

      This is not the function you are interested in. Look at readdir(3) for the POSIX conforming C library interface. This page documents the bare kernel system call interface.

      3/ Que peut-on en déduire pour les permissions positionnées sur le répertoire rep?
      Je vois pas comment c'est possible.
      Parce que si il peux lister c'est qu'il a les droits x (traverser le répertoire) et r (lire la liste des fichiers)
      Et ls -l donnera la liste de ces mêmes fichiers avec un descriptif long.


      Essaie chmod 111 rep, c'est marrant.



      Les gars ! relisez-vous un peu, quoi. C'était pour un exam !
    • [^] # Re: Réponse (a vérifier)

      Posté par (page perso) . Évalué à 1.

      1.4
      Faux: (comme dit en dessous...) les fils sont rattachés à init. Dans le cas inverse, quand un processus fils se termine, le processus parent reçoit un signal SIGCHILD.

      1.6
      Faux: Le lien physique est une entrée du répertoire, qui pointe vers le même inode que le fichier lié. Le nombre de liens dans l'inode est incrémenté, et aucun espace supplémentaire n'est utilisé. Le lien symbolique est une entrée de répertoire qui pointe sur un nouvel inode, pointant l'espace contenant le chemin du fichier lié. Le lien symbolique consomme donc au moins 1 inode (en général, le chemin prend quelques octets et se loge dans une partie réservée de l'inode, plutôt que de réserver un bloc de données en plus).

      2.3
      sleep() et select() font tous les deux de l'attente passive.
      Attente passive: le processus rend le contrôle au système, et charge le système de le réveiller sur une ou plusieurs conditions.
      Attente active: le processus attend dans une boucle, et monopolise les ressources. Le système n'a pas moyen de savoir si le processus est réellement en train de travailler, et lui alloue des ressources au détriment des autres processus. Un processus en attente active fait systématiquement grimper la charge de 1.
      Exemple d'attente active:
      while(1); /* attente d'un signal externe */
      Exemple d'attente passive:
      sleep(86400); /* attente d'un signal externe, limitée à 1 jour */

      3.1
      ls rep:
      effectue des readdir() pour donner les entrées présentes dans le répertoire. Le répertoire doit être accessible en lecture, et tous les répertoires parents doivent être traversables.
      3.2
      ls -l rep:
      effectue des readdir() comme au dessus, et des stat() sur chaque entrée pour connaitre les permissions et propriétaires des fichiers. Le stat() nécessite que tous les répertoires parents (y compris rep) soient traversables (droit x).
      3.3
      On déduit que pour le propriétaire, le bit de lecture est activé, mais pas le bit d'exécution. Les autres permissions ne sont pas connues (dr?-??????).
      • [^] # Re: Réponse (a vérifier)

        Posté par (page perso) . Évalué à 2.

        1.6
        Faux: Le lien physique est une entrée du répertoire, qui pointe vers le même inode que le fichier lié. Le nombre de liens dans l'inode est incrémenté, et aucun espace supplémentaire n'est utilisé. Le lien symbolique est une entrée de répertoire qui pointe sur un nouvel inode, pointant l'espace contenant le chemin du fichier lié. Le lien symbolique consomme donc au moins 1 inode (en général, le chemin prend quelques octets et se loge dans une partie réservée de l'inode, plutôt que de réserver un bloc de données en plus).

        Ici en XFS, j'ai donné les informations exactes données par un ls -l sur les deux (lien symbolique et physique), l'un me donne 12octets, là où l'autre en a 14k
        • [^] # Re: Réponse (a vérifier)

          Posté par (page perso) . Évalué à 1.

          Si tu comptes la taille de ton fichier, c'est de la triche ;)
          12 octets, c'est la taille du chemin du fichier pointé par le lien.
          14k c'est la taille du fichier lui-même. Ces 14k ne sont pas recopiés par ln (ni normal, ni -s).
          • [^] # Re: Réponse (a vérifier)

            Posté par (page perso) . Évalué à 2.

            Oups, effectivement, c'est bien possible, j'avais pas pensé a ça :'(
            • [^] # Re: Réponse (a vérifier)

              Posté par . Évalué à 2.

              Et c'est bien dommage parce que c'est l'un des deux intérêts majeurs d'un lien dur !

              Le second, c'est qu'il ne consomme pas d'inode supplémentaire.

              C'est bien le même fichier référencé deux fois.
  • # Un complément...

    Posté par . Évalué à 3.

    Bonjour,

    4/ La terminaison d'un processus provoque la terminaison de tous ses fils.

    Non, les fils deviennent fils d'init (sauf si c'est init lui-même qui est 'terminé')

    2/ Qu'est-ce qu'une fonction réentrante?

    Une fonction réentrante est une fonction que l'on peut appeler dans un contexte multi-thread (par exemple), ou qui peut être appelée récursivement.
    Une fonction réentrante alloue un espace distinct pour ses variables locales (en général dans la pile) à chaque appel.
    • [^] # Re: Un complément...

      Posté par . Évalué à 1.

      > Une fonction réentrante alloue un espace distinct pour ses variables locales (en général dans la pile) à chaque appel.
      pas seulement.
      une fonction non-reentrante stock souvent les resultats dans une meme structure . donc si elle est appelée plusieurs fois au meme moment , les resultats peuvent etre ecrasés.

      le fonctions autour de time sont l'exemple le plus frequent et le plus connues :
      struct tm *localtime(const time_t *timep);
      struct tm *localtime_r(const time_t *timep, struct tm *result);

      les _r sont reentrantes car on fournit un pointeur struct tm *result sur une zone memoire alouee pour y stocker le resultat.
    • [^] # Re: Un complément...

      Posté par . Évalué à 1.


      4/ La terminaison d'un processus provoque la terminaison de tous ses fils.

      Non, les fils deviennent fils d'init (sauf si c'est init lui-même qui est 'terminé')



      pourtant tu ouvres un ligne de commande (bash/sh/...)
      tu ouvres un programme depuis cette ligne de commande (firefox, amorok ou autre)

      tu fermes la ligne de commande
      ben ca ferme ton firefox :-/

      evidemment si tu met ton programme en tache de fond (& ou ctrl+z suivi de bg X) il devient alors independant du shell
  • # Exercice 1, 1)

    Posté par (page perso) . Évalué à 2.

    Exercice 1, 1)

    Je dirais Faux

    man setresuid
  • # Trop tard ?!?

    Posté par . Évalué à 1.

    Bonjour,

    Quizz me voilà (avec l'aide de WikiPedia :P)

    I - Exercice 1

    I.1) Vrai sauf cas particulier des commandes types SU ou SUDO & co :-)

    I.2) Vrai avec l'aide de Wikipedia [http://en.wikipedia.org/wiki/SIGPIPE]

    I.3) Joker :-)
    A priori, je pense que le signal sera noté dans le contexte noyau du processus (structure proc ?) mais il faudra attendre un changement de processus pour qu'il y ait une lecture de cette info...
    (Voir l'ordonnancement des processus)

    I.4) Faux SI les processus n'appartiennent pas au même groupe (voir appel systeme setsid & co) car le process init est le père qui adopte tous les petits orphelins du système.

    I.5) Vrai sinon le CTRL+C deviendrait moins amusant dans le SHELL ;-)

    I.6) Faux SI { on reste sur le même système de fichier ET le système de fichier gère les liens HARD+SOFT }.
    En effet, le lien Symbolique [http://en.wikipedia.org/wiki/Symbolic_link] est composé:
    a) 1 entrée dans le listing du répertoire (nom, infos du fichier: inode)
    b) 1 contenu (bloc(s) sur le disque) qui correspond au chemin du lien;
    De son côté, le lien Hard [http://en.wikipedia.org/wiki/Hard_link] est uniquement composé du a) avec incrément du ref count sur le fichier :-)

    Exercice 2

    II.1) Je pencherais sur la "portabilité" des appels haut niveau qui feront l'interface avec les appels systèmes "bas niveau" de chaque OS.
    La rapiditié revient à l'utilisation du bas niveau qui enlève certaines couches intermédiaires (buffers, structures...)

    II.2) WikiPedia:
    [http://fr.wikipedia.org/wiki/R%C3%A9entrance]

    II.3) WikiPedia:
    [http://fr.wikipedia.org/wiki/Attente_passive]
    [http://fr.wikipedia.org/wiki/Attente_active]

    III - Exercice 3

    III.1) les fonctions *dir: opendir, readdir, closedir
    Il faut que le répertoire soit accessible par l'utilisateur en Read+eXecute

    III.2) On rajoute les fonctions *stat (stat, fstat, lstat, ...) pour chaque entrée afin d'avoir leurs "attributs" (droits d'accès, dates systèmes, ...).

    III.3) Joker
    Bug de l'implémentation de la commande LS utilisée ;-)

    Voili voilà.

    Bon courage !

    Cdlt,
    • [^] # Re: Trop tard ?!?

      Posté par (page perso) . Évalué à 2.

      I.6)
      a) 1 entrée dans le listing du répertoire (nom, infos du fichier: inode)


      Attention, l'entrée dans le répertoire n'est pas un inode. Elle contient le nom d'un fichier et le numéro d'inode associé. Elle pointe donc sur un inode qui contient toutes les autres infos du fichiers. Le lien hard ne consomme pas d'inode, il ne consomme qu'une entrée du répertoire qui pointe sur le même inode que le fichier d'origine. C'est cet inode non dupliqué qui voit sont compteur de ref augmenter. Le lien symbolique a son propre inode, c'est pour ça qu'il prend plus d'espace disque. Par contre, il ne consomme pas forcément de bloc de données. En dessous d'une cinquantaine d'octets, les données sont rangées directement dans l'inode.

      III.1) les fonctions *dir: opendir, readdir, closedir
      Il faut que le répertoire soit accessible par l'utilisateur en Read+eXecute


      Non non et non... on n'a pas besoin de traverser un répertoire pour lister ses entrées. Les noms des élements du répertoire sont bien dans les blocs de données du répertoire, et non dans les inodes des fichiers correspondants.

      Par contre, on a bien besoin de traverser le répertoire pour lire les inodes (stat) des fichiers qui sont dedans :)
      • [^] # Re: Trop tard ?!?

        Posté par . Évalué à 1.

        Bonjour,

        Merci pour toutes ces infos :-)

        Une petite mise à jour de mon commentaire:
        Au lieu de

        Quizz me voilà (avec l'aide de WikiPedia :P)

        Il faudra lire

        Quizz me voilà (avec l'aide de WikiPedia et jimee [https://linuxfr.org/~jimee/])


        Voili voilà :P

        Cdlt,

        PS: Au passage, je comprend mieux le III.3 si on n'a pas besoin de "traverser" le répertoire... :P
  • # .

    Posté par . Évalué à 4.

    Est-ce que le repêchage s'est bien passé ?
    • [^] # Re: .

      Posté par . Évalué à 2.

      A la pêche aux moules moules moules; .....
    • [^] # Inch'allah

      Posté par . Évalué à 1.

      Bonsoir à tous,

      merci pour vos réponses et désolé pour le retard (j'ai pas le net souvent). Je vois que mes interrogations ont été débattu :)
      L'examen s'est bien passé dans l'ensemble, mis à part le dernier exercice ou j'avoue j'ai séché. En tout cas, vos réponses m'ont été fort utiles, mon prof a réutilisé certaines questions :) :)
      Pour info, c'est l'exam de la licence informatique du 4ème semestre à Bordeaux1. Résultat le 7 juin...

      Merci à tous. @++

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.