Vous êtes sur la page 1sur 17

systèmes d’exploitation

exercices

v4

Hervé COSTANTINI
Table des matières
introduction ............................................................................................................................................. 3
processus ................................................................................................................................................. 4
mémoire .................................................................................................................................................. 5
fichiers ..................................................................................................................................................... 5
v3 ......................................................................................................................................................... 8
shells/scripts ............................................................................................................................................ 9
Exercice 1 : énoncé .............................................................................................................................. 9
Exercice 2 : énoncé .............................................................................................................................. 9
Signalisation........................................................................................................................................... 10
Exercice 1 : énoncé ............................................................................................................................ 10
Exercice 2 : énoncé ............................................................................................................................ 10
Exercice 3 : énoncé ............................................................................................................................ 11
Manipulation de chiffres binaires (bits) ................................................................................................ 13
Exercice 1 : énoncé ............................................................................................................................ 13
Entrées/Sorties et Communication Inter-processus ............................................................................. 14
Exercice 1 : synchrones bloquantes : énoncé.................................................................................... 14
Exercice 2 : synchrones non bloquantes par pipe : énoncé .............................................................. 16

2
introduction
Ce fascicule d’exercices suit l’ordre des thèmes du cours correspondant. Vous devez vous familiariser
tout d’abord avec les commandes de la présente section afin de pouvoir ensuite parcourir les sections
suivantes. Commencez, sous une distribution Linux de votre choix, par lancer l’application Terminal.
Le tableau ci-dessous vous invite à taper des commandes, constater les affichages provoqués par ces
commandes ; en outre, des commentaires sont clairsemés ; ils apparaissent derrière le mot « nota ».
Enfin, le caractère point-virgule (;) permet d’écrire plusieurs commandes sur la même ligne, en les
séparant l’une de l’autre. Par exemple :

cd .. ; pwd

est équivalent à :

cd ..

pwd

Pour trouver ce que ces commandes signifient, voir p. 5.

Les sections concernant la programmation C commencent par une introduction dédiée.

3
processus
taper la commande suivante constater qu’elle affiche et expliquer
ps

sleep 120 &

ps

attendre 2 minutes et taper la


touche ENTREE
sleep 180 &

kill 29004
ou bien
kill -9 29004

sleep 80 &
sleep 60 &
sleep 90 &
killall sleep

killall -u <nom_uti>

killall -w sleep
pidof bash

nice -n 19 ls -l

renice -n 18 12345

4
top
pstree

time ls -l

mémoire
taper la commande suivante constater qu’elle affiche et expliquer
df

du

fichiers
taper la commande suivante constater qu’elle affiche
pwd

mkdir –v rep1

ls

5
cd rep1 ; pwd

cd .. ; pwd
cd

touch fichier1.txt ; ls

clear
echo "bonjour"

echo "bonjour" >> fichier1.txt

cat fichier1.txt
echo "au revoir" >> fichier1.txt
head -1 fichier1.txt

tail -1 fichier1.txt

stat fichier1.txt

stat rep1

6
du –xh ~

cp –v fichier1.txt rep1

mv –v fichier1.txt rep1

md5sum fichier1.txt

7
ln –v fichier1.txt file1.txt

ln –sv fichier1.txt datei1.txt

rm –v fichier1.txt

v3
taper la commande suivante constater qu’elle affiche
grep hello fichier1.txt

grep -r hello .

wc fichier1.txt

echo -e "col1 col2 r1\ncol5


col6 r2\ncol3 col4
r3" > nouveau.txt ; cat
nouveau.txt (sur la même
ligne !)

cut -f1 -d' ' nouveau.txt

sort nouveau.txt;

8
diff nouveau.txt fichier1.txt

dirname fichier1.txt

basename ./fichier1.txt

chmod -v 666 fichier1.txt

shells/scripts
Exercice 1 : énoncé
1. Écrivez un script qui affiche le nom d'une ville.

2. Assurez-vous que le script s'exécute dans le shell bash.

3. Assurez-vous que le script s'exécute dans le shell Korn.

4. Créez un script qui définit deux variables et génère leur valeur.

5. Le script précédent n'influence pas votre shell actuel (les variables n'existent pas en dehors du
script). Exécutez maintenant le script pour qu'il influence votre shell actuel.

6. Existe-t-il un moyen plus court de trouver le script?

7. Commentez vos scripts pour savoir ce qu'ils font.

Exercice 2 : énoncé
1. Écrivez un script qui demande deux nombres et génère la somme et le produit (comme illustré ci-
dessous).
Entrez un nombre: 5
Entrez un autre numéro: 2

Somme: 5 + 2 = 7
Produit: 5 x 2 = 10

2. Améliorez le script précédent pour tester que les nombres sont compris entre 1 et 100, quittez avec
une erreur si nécessaire.

3. Améliorez le script précédent pour féliciter l'utilisateur si la somme est égale au produit.

4. Écrivez un script avec une déclaration de casse insensible à la casse, en utilisant l'option shopt
nocasematch. L'option nocasematch est réinitialisée à la valeur qu'elle avait avant le démarrage des
scripts.

9
Signalisation
Exercice 1 : énoncé
Dans votre navigateur préféré, se rendre à l'url suivante :

https://www.onlinegdb.com/

puis y copier/coller le code ci-après :


/*
Vectorisation de signal.
Écriture à une adresse sans allocation de mémoire pour provoquer une
violation de segmentation.
*/
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#define True 1
int i = 0;
int
main ()
{
char *ptr;
void segViolation (int);
if (signal (SIGSEGV, segViolation) == SIG_ERR)
{
perror ("signal");
exit (1);
}
while (True)
*(ptr + i) = ++i;
}

void
segViolation (int sig)
{
exit (1);
}

puis cliquer Run ( ) puis cliquer le bouton Download code ( ) afin d'enregistrer ce
code sur votre ordinateur, et surtout vos modifications. Enfin, y copier/coller les lignes ci-dessous aux
bons endroits :
printf("D\u00e9but.\n");
printf("D\u00e9claration pointeur fou (=qui pointe nulle part).\n");
printf("Vectorisation signal SIGSEGV (%d) : violation segmentation.\n", SIGSEGV);
printf("Boucle d'\u00e9critures en m\u00e9moire depuis le pointeur fou.\n");
printf("Ce message ne devrait pas s'afficher.\n");
printf ("Signal %d re\u00e7u. Violation de segmentation.\n", sig);
printf ("Fin pr\u00e9matur\u00e9e.\n");

Nota : les lettres accentuées ne sont pas supportées d'où l'utilisation de \u00e9 pour é, \u00e7 pour
ç. Cf. https://outils-javascript.aliasdmc.fr/encodage-caracteres-accentues/ et choisir la valeur Js.

Exercice 2 : énoncé
Dans votre navigateur préféré, se rendre à l'url suivante :

https://www.onlinegdb.com/

puis y copier/coller le code ci-après :


/*
Exemple d'utilisation de l'alarme horloge.
signal() permet de définir (vectoriser) le traitement du signal alarme.
alarm() permet d'armer l'alarme à N secondes.
pause() permet d'attendre l'arrivée du signal alarme.
*/

10
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#define N 3
int
main ()
{
void sigalrm (int);
if (signal (SIGALRM, sigalrm) == SIG_ERR)
{
perror ("signal");
exit (1);
}
alarm (N);
pause ();
return 0;
}

void
sigalrm (int sig)
{
}

puis cliquer Run ( ) puis cliquer le bouton Download code ( ) afin d'enregistrer ce
code sur votre ordinateur, et surtout vos modifications. Enfin, y copier/coller les lignes ci-dessous aux
bons endroits :
printf("D\u00e9but.\n");
printf("Vectorisation SIGALRM (%d).\n", SIGALRM);
printf("Armement alarme à %d sec.\n", N);
printf("Attente \u00e9ch\u00e9ance.\n");
printf("\u00c9ch\u00e9ance trait\u00e9e.\n");
printf("Fin.\n");
printf ("Signal (%d) re\u00e7u.\n", sig);
printf ("\u00c9ch\u00e9ance atteinte.\n");

Nota : les lettres accentuées ne sont pas supportées d'où l'utilisation de \u00e9 pour é, \u00e7 pour
ç. Cf. https://outils-javascript.aliasdmc.fr/encodage-caracteres-accentues/ et choisir la valeur Js.

Exercice 3 : énoncé
Dans votre navigateur préféré, se rendre à l'url suivante :

https://www.onlinegdb.com/

puis y copier/coller le code ci-après :


/*
Deux processus s'envoient des signaux mutuellement
*/
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int idpere;
int idfils;

int pere ();


int fils ();
void erreur (char *nom);
void func_user1 (int);

#define FILS 0
#define SYS_ERR -1

int
main ()

11
{
idpere = getpid ();
if (signal (SIGUSR1, func_user1) == SIG_ERR)
{
perror ("signal");
exit (1);
}
switch (idfils = fork ())
{
case FILS:
fils ();
break;
case SYS_ERR:
erreur ("fork");
break;
default:
pere ();
break;
}

return 0;
}

int
pere ()
{
sleep(1);
if (kill (idfils, SIGUSR1))
{
perror ("kill p\u00e8re");
exit (1);
}
pause ();
return 0;
}

int
fils ()
{
pause ();
if (kill (idpere, SIGUSR1))
{
perror ("kill fils");
exit (1);
}
return 0;
}

void
erreur (char *nom)
{
perror (nom);
exit (1);
}

void
func_user1 (int sig)
{
}

puis cliquer Run ( ) puis cliquer le bouton Download code ( ) afin d'enregistrer ce
code sur votre ordinateur, et surtout vos modifications. Enfin, y copier/coller les lignes ci-dessous aux
bons endroits :
printf ("P\u00e8re. D\u00e9but.\n");
printf ("P\u00e8re. Identifiant=%d.\n", idpere);
printf ("P\u00e8re. Vectorisation SIGUSR1 (%d).\n", SIGUSR1);
printf ("P\u00e8re. Cr\u00e9ation Fils.\n");
printf ("P\u00e8re. Identifiant Fils=%d.\n", idfils);
printf ("P\u00e8re. Attente stabilisation Fils.\n");
printf ("P\u00e8re. Envoi signal.\n");
printf ("P\u00e8re. Attente signal.\n");
printf ("P\u00e8re. Signal trait\u00e9.\n");
printf ("P\u00e8re. Fin.\n");

12
printf ("Fils. D\u00e9but.\n");
printf ("Fils. Attente signal.\n");
printf ("Fils. Signal trait\u00e9.\n");
printf ("Fils. Envoi signal.\n");
printf ("Fils. Fin.\n");
printf ("%d. Signal SIGUSR1 (%d) re\u00e7u.\n", getpid (), sig);

Nota : les lettres accentuées ne sont pas supportées d'où l'utilisation de \u00e9 pour é, \u00e7 pour
ç. Cf. https://outils-javascript.aliasdmc.fr/encodage-caracteres-accentues/ et choisir la valeur Js.

Manipulation de chiffres binaires (bits)


Exercice 1 : énoncé
Dans votre navigateur préféré, se rendre à l'url suivante :

https://www.onlinegdb.com/

puis y copier/coller le code ci-après :


/******************************************************************************

Manipulation de chiffres binaires (bits)

*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>

void init_bm (unsigned char *map);


void print_bm (unsigned char *map);
void s_bm (unsigned char *map, int c);
void r_bm (unsigned char *map, int c);
int t_bm (unsigned char *map, int c);
void valid_c (int c);

//Taille du tableau de bits, en octets


#define SIZE 5
//Numéro du bit manipulé
#define BIT 32

int
main ()
{
unsigned char map[SIZE];
init_bm (map);
print_bm (map);
s_bm (map, BIT);
print_bm (map);
t_bm (map, BIT);
print_bm (map);
r_bm (map, BIT);
print_bm (map);

return 0;
}

// INIT BITMAP
void
init_bm (unsigned char *map)
{
for (int i = 0; i < SIZE; i++)
map[i] = 0;

// PRINT BITMAP
void
print_bm (unsigned char *map)
{
int i = SIZE;
while (i-- > 0) printf ("map[%d]=%x%s", i, map[i], i > 0 ? ", " : ".\n");
i = SIZE;
while (i-- > 0) {

13
printf ("map[%d]=", i);
int j = 8;
while (j > 0) printf("%x", (map[i] >> --j) & 1);
printf("%s", i > 0 ? ", " : ".\n"); }
}

// SET BIT
void
s_bm (unsigned char *map, int c)
{
valid_c (c);
map[c >> 3] |= 1 << (c & 0x07);
return;
}

// RESET BIT
void
r_bm (unsigned char *map, int c)
{
valid_c (c);
map[c >> 3] &= ~(1 << (c & 0x07));
return;
}

// TEST BIT
int
t_bm (unsigned char *map, int c)
{
int ret;
valid_c (c);
ret = (map[c >> 3] & (1 << (c & 0x07)));
return ret;
}

void
valid_c (int c)
{
if (c >> 3 < SIZE)
return;
exit (1);
}

puis cliquer Run ( ) puis cliquer le bouton Download code ( ) afin d'enregistrer ce
code sur votre ordinateur, et surtout vos modifications. Enfin, y copier/coller les lignes ci-dessous aux
bons endroits :
printf ("D\u00e9but\n");
printf ("D\u00e9clarer un tableau de %d bits, i.e. %d octets.\n", SIZE * 8, SIZE);
printf ("Initialiser le tableau \u00e0 z\u00e9ro.\n");
printf ("Valeurs du tableau en octets puis en chiffres binaires (bits).\n");
printf ("Demande re\u00e7ue : mettre à 1 le bit %d.\n", c);
printf ("Demande effectu\u00e9e : mettre à 1 le bit %d.\n", c);
printf ("Demande re\u00e7ue : mettre à 0 le bit %d.\n", c);
printf ("Demande effectu\u00e9e : mettre à 0 le bit %d.\n", c);
printf ("Demande re\u00e7ue : tester le bit%d.\n", c);
printf ("Demande effectu\u00e9e : bit%d=%d.\n", c, ret);
printf ("D\u00e9passement de capacit\u00e9 : %d > %d.\n", c, SIZE*8 - 1);

Nota : les lettres accentuées ne sont pas supportées d'où l'utilisation de \u00e9 pour é, \u00e7 pour
ç. Cf. https://outils-javascript.aliasdmc.fr/encodage-caracteres-accentues/ et choisir la valeur Js.

Entrées/Sorties et Communication Inter-processus


Exercice 1 : synchrones bloquantes : énoncé
Dans votre navigateur préféré, se rendre à l'url suivante :

https://www.onlinegdb.com/

14
puis y copier/coller le code ci-après :
/******************************************************************************
E/S synchrones Bloquantes
******************************************************************************/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SIZE 512


#define FILE "testFichier.txt"
#define WAIT 2

int
main ()
{
int fd, status;
char buffer[SIZE];
if (!(fd = open (FILE, O_RDWR | O_APPEND | O_CREAT)))
{
perror ("Open/Create");
return (1);
}
switch (status = read (fd, buffer, SIZE))
{
case -1:
perror ("Read");
return (1);
case 0:
break;
default:
break;
}

sleep(WAIT);

// Préparer l'écriture
sprintf (buffer, "%s\n", "Ecriture de texte");

switch (status = write (fd, buffer, strlen(buffer)))


{
case -1:
perror ("Write");
return (1);
case 0:
break;
default:
break;
}
return (0);
}

puis cliquer Run ( ) puis cliquer le bouton Download code ( ) afin d'enregistrer ce
code sur votre ordinateur, et surtout vos modifications. Enfin, y copier/coller les lignes ci-dessous aux
bons endroits :
printf("D\u00e9but.\n");
printf("D\u00e9claration d'un tampon d'entr\u00e9e/sortie, de taille %d.\n", SIZE);
printf("Ouverture du fichier d'entr\u00e9e/sortie \"%s\".\n", FILE);
printf("Lecture du fichier.\n");
printf ("End Of File\n");
printf ("Lecture (%d octets) :\n>>>\n%s\n<<<\n", (int)strlen(buffer), buffer);
printf ("Attente entre lecture et \u00e9criture : %d sec.\n", WAIT);
printf ("Pr\u00e9paration de l'\u00e9criture.\n");
printf ("\u00c9criture du fichier.\n");
printf ("End Of File\n");
printf ("Ecriture (%d octets) : %s\n", status, buffer);

15
Nota : les lettres accentuées ne sont pas supportées d'où l'utilisation de \u00e9 pour é, \u00e7 pour
ç. Cf. https://outils-javascript.aliasdmc.fr/encodage-caracteres-accentues/ et choisir la valeur Js.

Exercice 2 : synchrones non bloquantes par pipe : énoncé


Dans votre navigateur préféré, se rendre à l'url suivante :

https://www.onlinegdb.com/

puis y copier/coller le code ci-après :


/******************************************************************************
E/S synchrones non Bloquantes par pipe
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#define MSGSIZE 9

char* msg1 ="bonjour !";


char* msg2 ="au revoir";

void parent_read(int p[]);


void child_write(int p[]);

int main()
{
int p[2];

if (pipe(p) < 0) {
exit(1);
}
if (fcntl(p[0], F_SETFL, O_NONBLOCK) < 0) {
exit(2);
}
switch (fork()) {
case -1:
exit(3);
case 0:
child_write(p);
break;
default:
parent_read(p);
break;
}
return 0;
}
void parent_read(int p[])
{
int nread;
char buf[MSGSIZE];
close(p[1]);
while (1) {
nread = read(p[0], buf, MSGSIZE);
switch (nread) {
case -1:
if (errno == EAGAIN) {
sleep(1);
break;
} else {
perror("read");
exit(4);
}
case 0:
close(p[0]);
exit(0);
default:
}
}

16
}
void child_write(int p[])
{
close(p[0]);
for (int i = 0; i < 3; i++) {
printf(" Fils. \u00c9criture tube. ");
write(p[1], msg1, MSGSIZE);
printf("Message \u00e9mis. Taille = %d. Contenu = \"%s\".\n", MSGSIZE, msg1);
sleep(3);
}
write(p[1], msg2, MSGSIZE);
exit(0);
}

puis cliquer Run ( ) puis cliquer le bouton Download code ( ) afin d'enregistrer ce
code sur votre ordinateur, et surtout vos modifications. Enfin, y copier/coller les lignes ci-dessous aux
bons endroits :
printf("P\u00e8re. D\u00e9but.\n");
printf("P\u00e8re. Cr\u00e9ation d'un tube.\n");
printf("P\u00e8re. Tubes non support\u00e9s. Fin\n");
printf("P\u00e8re. Activation du mode non bloquant.\n");
printf("P\u00e8re. Mode non bloquant indisponible. Fin\n");
printf("P\u00e8re. Cr\u00e9ation Fils.\n");
printf("P\u00e8re. Fork impossible.\n");
printf("Fils. D\u00e9but.\n");
printf("P\u00e8re. Fermeture acc\u00e8s \u00e9criture du tube.\n");
printf("P\u00e8re. Boucle de lecture.\n");
printf(" P\u00e8re. Lecture tube. ");
printf("Tube vide.\n");
printf("Fin de communication re\u00e7ue.\n");
printf("P\u00e8re. Fermeture acc\u00e8s lecture du tube.\n");
printf("P\u00e8re. Fin.\n");
printf("Message re\u00e7u. Taille = %d. Contenu = \"%s\".\n", nread, buf);
printf("Fils. Fermeture acc\u00e8s lecture du tube.\n");
printf("Fils. Boucle d'\u00e9criture.\n");
printf("Fils. \u00c9criture tube. ");
printf("Message \u00e9mis. Taille = %d. Contenu = \"%s\".\n", MSGSIZE, msg2);
printf("Fils. Fin \u00e9mise.\n");
printf("Fils. Fin.\n");

Nota : les lettres accentuées ne sont pas supportées d'où l'utilisation de \u00e9 pour é, \u00e7 pour
ç. Cf. https://outils-javascript.aliasdmc.fr/encodage-caracteres-accentues/ et choisir la valeur Js.

17

Vous aimerez peut-être aussi