Lezione 15
Chiamate di sistema
Sistemi Operativi (9 CFU), CdL Informatica, A. A. 2020/2021 Dipartimento di Scienze Fisiche, Informatiche e Matematiche
2
Quote of the day
(Meditate, gente, meditate...)
“Perfection is finally attained, not when there is more to add, but when there is nothing left to take away. ”
Antoine de Saint-Exupery (1901-1944) Scrittore, poeta, aviatore
Esercizio 1 (3 min.)
Individuate la chiamata di sistema che individua lo stato di un file a partire dal suo percorso.
4
Individuazione chiamata con apropos
Si usa il comando apropos per individuare la chiamata di sistema richiesta (Sezione 2) a partire da una sua descrizione in inglese (“file status”):
apropos -s 2 -a file status
Si ottengono una marea di risultati riguardanti una funzionalità di tipo “get file status”.
Lettura pagine di manuale con man
Si usa il comando man per leggere le varie voci:
man 2 fstat man 2 fstat64 man 2 fstatat ...
Guardando l’output di man in alto a sinistra, sembra aprirsi sempre la pagina di manuale della chiamata di sistema stat.
6
Lettura pagina di manuale di stat
Si usa il comando man per leggere la voce di stat:
man 2 stat
Si scopre che la chiamata di sistema richiesta è stat, che riceve due parametri:
pathname: percorso del file da analizzare;
statbuf: puntatore alla struttura contenente i metadati.
Inoltre, stat ritorna un valore intero:
0: tutto OK;
-1: si è verificato un errore (errno contiene l’identificatore corrispondente).
Esercizio 2 (3 min.)
Individuate la funzione di servizio associata alla chiamata di sistema stat.
8
Identificazione numero di parametri
Quanti parametri riceve in ingresso stat?
man 2 stat
La chiamata di sistema stat riceve due parametri in ingresso.
Ottenimento albero sorgente kernel
La macchina virtuale fornita dal docente è Intel a 64 bit.
Se si usa una macchina diversa, si può scoprire la sua architettura con il comando seguente:
arch
L’archivio contenente l’albero sorgente del kernel (identificato dalla variabile $LINUX) è scaricabile all’URL seguente:
https://kernel.org
10
Identificazione tabella syscall
La tabella delle chiamate di sistema è identificabile con il comando seguente:
find $LINUX -name syscall_64.tbl
Si dovrebbe trovare il file seguente:
$LINUX/arch/x86/entry/syscalls/syscall_64.tbl
Identificazione nome funzione servizio
Si apra la tabella delle chiamate di sistema:
$LINUX/arch/x86/entry/syscalls/syscall_64.tbl
Si individui il record relativo alla chiamata di sistema stat:
4 common stat sys_newstat
La funzione di servizio è sys_newstat.
12
Identificazione funzione servizio
La funzione di servizio è definita tramite la macro seguente:
SYSCALL_DEFINE2(newstat, PARAMETRI FORMALI);
Si può individuare la definizione con il comando seguente:
grep -nrHiE ’SYSCALL_DEFINE2\(newstat.*’
Si dovrebbe ottenere la definizione nel file fs/stat.c alla riga 345.
Esercizio 3 (5 min.)
Scrivete un programma che cambi il nome del file /path/to/file1 nel nome del file /path/to/file2. Ovviamente, sostituite ai percorsi fittizi dei percorsi sensati e create fisicamente il file file1. Gestite eventuali errori e l'uscita del programma.
14
Identificazione chiamata di sistema
Si usa il comando apropos per identificare la chiamata di sistema richiesta:
apropos -s 2 rename
Si ottengono tre risultati correlati:
rename (2) renameat (2) renameat2 (2)
Lettura pagine manuale con man
Si usa il comando man per leggere tutte le chiamate di sistema:
man 2 rename man 2 renameat man 2 renameat2
Guardando l’output di man in alto a sinistra, sembra aprirsi sempre la pagina di manuale della chiamata di sistema rename.
16
Lettura pagina di manuale di rename
Si usa il comando man per leggere la voce di rename:
man 2 rename
Si scopre che la chiamata di sistema richiesta è rename, che riceve due parametri:
oldpath: percorso del file da rinominare;
newpath: percorso della nuova locazione del file.
Inoltre, rename ritorna un valore intero:
0: tutto OK;
-1: si è verificato un errore (errno contiene l’identificatore corrispondente).
Creazione del file C sorgente
Si crea un file vuoto con il nome seguente:
rename.c
18
Inclusione degli header per rename
La pagina di manuale di rename mostra chiaramente gli header da includere.
#include <stdio.h>
Si aggiorna rename.c con questa direttiva.
Creazione di uno scheletro in C
Si aggiorna rename.c con lo scheletro della funzione main():
int main(int argc, char *argv[]) { }
20
Preparazione dei parametri di rename
Si definiscono due parametri da passare alla chiamata di sistema rename tramite il suo wrapper rename() della libreria del C (man 3 rename).
const char src_path[] = ”/path/to/src”;
const char dst_path[] = ”/path/to/dst”;
Ovviamente, si può sostituire un percorso invalido con il percorso di un file esistente (non lo si faccia ora).
La chiamata di sistema rename ritorna un valore intero.
È buona prassi salvarlo e controllarlo. Pertanto, si definisce anche una variabile intera.
int ret;
Invocazione della chiamata di sistema
Si aggiorna rename.c con lo statement di invocazione del wrapper della libreria del C:
ret = rename(dst_path, src_path);
22
Controllo degli errori
Si controlla che ret abbia il valore -1. Se lo ha, si stampa un messaggio di errore tramite printf().
if (ret == -1) {
printf(“Errore”);
}
Il compilatore emette un warning; manca il file include di printf(), ossia <stdio.h>.
Se si include tale file in rename.c, il warning sparisce.
Uscita in caso di errore
Si aggiorna il ramo di codice di rename.c contenente la gestione degli errori con una invocazione di exit() atta a segnalare un errore generico:
exit(EXIT_FAILURE);
La exit() richiede il file include <stdlib.h>. Lo si includa all'inizio del programma rename.c.
24
Uscita in caso di successo
Si aggiorna il ramo di codice principale di rename.c con una invocazione di exit() atta a segnalare l’uscita corretta:
exit(EXIT_SUCCESS);
Il sorgente completo rename.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
const char src_path[] = "/path/to/src";
const char dst_path[] = "/path/to/dst";
int ret;
ret = rename(src_path, dst_path);
if (ret == -1) {
perror(argv[0]);
exit(EXIT_FAILURE);
}
26
Il sorgente completo rename.c
Il file rename.c è contenuto nell'archivio 15-soluzioni.tar.bz2.