1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

32
1 Esempio di ADT e make Operazioni bit a bit su piu’ file

Transcript of 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

Page 1: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

1

Esempio di ADT e make

Operazioni bit a bit su piu’ file

Page 2: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

2

Albero delle dipendenze complessivo dell’esempio

glob.hbitbit.h

bitbit.c

menu_bit.h

bitbit.o

bit

bit.o

Struttura dipendenze• Albero dipendenze radicato nell’eseguibile bit

menu_bit.o

menu_bit.c

bit.c

Page 3: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

3

Come visualizzare i moduli oggetto– Comando nm options file.o fornisce tutti i simboli definiti in file.o

•$nm -g bitbit.o

fornisce solo i simboli esportati

– Comandi objdump e readelf permettoni di leggere le varie sezioni dell’eseguibile•$objdump -d bitbit.o

fornisce il testo disassemblato•-r tabelle di rilocazione•-t symbol table

– Vedere anche info binutils da emacs

Page 4: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

4

Classi di memorizzazione

Page 5: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

5

Classi di memorizzazione

• Definiscono le regole di visibilità delle variabili e delle funzioni quando il programma è diviso su più file• Stabiliscono dove (in quale parte dello spazio di indirizzamento) allocare le varie variabili • Stabiliscono cosa finisce nella tabella dei simboli del modulo oggetto

– simboli (esterni, esportati)

Page 6: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

6

registerautostaticextern

variabili locali

funzionivariabili globali

Classi di memorizzazione (2)

• Tutti i modificatori possono essere applicati alle variabili locali• Solo static ed extern a globali e funzioni

Page 7: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

7

Variabili locali• La classe di memorizzazione di default per le variabili locali è auto (automatica):

int x;

auto int x;

– significano entrambe la stessa cosa : la variabile viene allocata sullo stack all’ingresso del blocco in cui è dichiarata e rimossa all’uscita– non c’è alcun legame fra il valore ad una certa attivazione ed il valore alla attivazione successiva– la visibilità di x è solo all’interno del blocco

Page 8: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

8

Variabili locali (2)• La classe di memorizzazione register è obsoleta

int x;

register int x;

– significa che la variabile x è usata pesantemente e consiglia al compilatore di metterla in un registro generale

– viene ignorata, i compilatori di oggi sono dotati di sofisticati algoritmi di allocazione dei registri

– la visibilità di x è solo all’interno del blocco

Page 9: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

9

Variabili locali (3)• La classe di memorizzazione static è utilizzata quando il valore della variabile deve essere mantenuto da una invocazione all’altra del blocco

{ static int x;

}

– significa che la variabile x mantiene il proprio valore da una attivazione del blocco alla successiva– la visibilità di x è solo all’interno del blocco

Page 10: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

10

Variabili locali (4)• La classe di memorizzazione extern

{ extern int x;

}

– significa che la variabile x è dichiarata globale in questo o in altri file – il nome x finisce nella tabella dei simboli come simbolo esterno – il compilatore segnala la situazione nell’oggetto ed il linker ‘cerca x altrove’

Page 11: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

11

Variabili globali• La classe di memorizzazione extern è la condizione di default per le variabili globali

int x;

extern int x;

int funct (…) { ...}

– queste due dichiarazioni di x sono equivalenti, ed x viene allocata nell’area dati statica

– il nome x finisce nella tabella dei simboli come simbolo esportato

– la visibilità di x comprende tutte le funzioni dichiarate nel file dopo di essa ed x può essere utilizzata in un altro file

Page 12: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

12

Variabili globali (2)• La classe di memorizzazione static serve a limitare la portata delle varibili globali

static int x;

int funct (…) { ...}

– questa dichiarazioni di x rende la variabile visibile da tutte le funzioni che la seguono nel file

– MA, il nome x NON finisce nella tabella dei simboli esportati

– la visibilità di x è ristretta al file dove è dichiarata

– può servire per realizzare variabili ‘private’ di una implementazione

Page 13: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

13

Funzioni • extern è la classe di memorizzazione di default delle funzioni

int funct (…) { ...}

extern int funct (…) { ...}

– sono equivalenti : funct è chiamabile all’interno di tutte le funzioni che la seguono nel file– il nome funct finisce nella tabella dei simboli come simbolo esportato– funzioni di altri file possono usare funct, chiamate a funzioni definite in altri file finiscono nella tabella dei simboli come esterne e vengono risolte dal linker (es. printf)

Page 14: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

14

Funzioni (2)• La classe di memorizzazione static serve a limitare la portata delle funzioni

static int funct (…) { ...}

– questa dichiarazioni di funct la rende la visibile solo a tutte le funzioni che la seguono nel file– MA, il nome funct NON finisce nella tabella dei simboli esportati– può servire per implementare delle funzioni‘private’ di una implementazione, non chiamabili dall’esterno del file

Page 15: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

15

ADT ‘protetti’ in C• Idea di base :

– definire l’interfaccia in un file X.h (tipi di dato e prototipi delle funzioni utilizzabili) – utilizzare lo specificatore static per realizzare la protezione nel file X.c che realizza l’implementazione – mettere a disposizione l’oggetto X.o (da solo o all’interno di una libreria) per permettere un linking corretto

• Esempio : il tipo BIT32

Page 16: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

16

ADT ‘protetti’ in C (2)• ... Come si usa il tipo BIT32

– includere l’header (bitbit.h)

– compilare linkando anche bitbit.o

• Insiemi di file oggetti di uso comune possono essere raccolti in librerie ….

Page 17: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

17

Librerie (ar)• Il comando :

ar r nomelibreria.a file1.o fileN.o

– inserisce/aggiorna i file file1.o fileN.o nella libreria nomelibreria.a– es.

ar r libutils.a bitbit.o menu_bit.o

crea una libreria contenente i due oggetti•r : operazione da eseguire•nm -s libreria.a

fornisce informazioni sui simboli definiti nei vari file della libreria (con indicazioni del file dove si trovano)

Page 18: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

18

Librerie (ar) (2)• Tipicamente le librerie vengono raccolte in una directory

– es. ~/lib/– e recuperate in fase di linking per generare l’eseguibile finale– es: gcc -L~/lib/ -lutils main.o

esegue il linking fra main .o e le funzioni nella libreria libutils.a in ~/lib/

Page 19: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

20

SC che operano su file e directory

Lseek, stat, opendir, closedir, readdir, rewinddir, ch

Page 20: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

21

Posizionamento : lseek()off_t lseek(int fd, off_t offset,

int whence)– fd : file descriptor– offset : di quanti byte voglio spostarmi– whence : da dove calcolo lo spostamento. Può essere una delle seguenti macro

• SEEK_SET dall’inizio, • SEEK_END dalla fine, • SEEK_CUR dalla posizione corrente

– Ritorna : • la posizione corrente in caso di successo , • -1 in caso di fallimento

Page 21: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

22

Posizionamento : lseek() (2)

• Esempio …. lseek(fd, 0, SEEK _SET);

lseek(fd, -1, SEEK _END);

lseek(fd, 1, SEEK _CUR);

• cosa ritornano queste chiamate ?

Page 22: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

23

Attributi : stat()int stat(const char* pathfile,

struct stat *buf)– pathfile : path del file– buf : puntatore alla struttura struct stat in cui verranno inserite le informazioni

Page 23: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

24

Attributi : stat() (2)struct stat {

ino_t st_ino; /* # i-nodo*/

mode_t st_mode; /* diritti protezione*/

nlink_t st_nlink; /* # hard link */

uid_t st_uid; /* ID owner */

off_t st_size; /* lung totale (byte)*/

unsgn long st_blksize;/* dim blocco */

unsgn long st_blocks; /* #blk 512byte occupati*/

time_t st_atime; /* ultimo accesso*/

time_t st_mtime; /* ultima modifica */

time_t st_ctime; /* ultima var dati */

}

Page 24: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

25

Attributi : stat() (3)struct stat info;

IFERROR(stat(“dati”,&info), “In stat”);

if (S_ISLNK(info.st_mode)){/* link simbolico*/}

if (S_ISREG(info.st_mode)){/* file regolare*/}

if (S_ISDIR(info.st_mode)){/* directory */}

if (S_ISCHR(info.st_mode)){/* spec caratteri */}

if (S_ISBLK(info.st_mode)){/* spec blocchi */}

if (info.st_mode & S_IRUSR){/* r per owner */}

if (info.st_mode & S_IWGRP){/* w per group */}

Page 25: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

26

Directory• Il formato delle directory varia nei vari FS utilizzati in ambito Unix• Quando una directory viene aperta viene restituito un puntatore a un oggetto di tipo DIR (definto in dirent.h)

– es. DIR* mydir;

• Per leggere le informazioni sui file contenuti esiste la chiamata di sistema POSIX getdents()– non la useremo direttamente

Page 26: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

27

Directory (2)• Useremo funzioni di libreria conformi a POSIX che lavorano sul puntatore in modo trasparente e chiamano getdents

quando necessario– sez 3 manuali– es. readdir, rewinddir, opendir, closedir, getcwd– attenzione! : esiste anche una readdir ciamata di sistema

Page 27: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

28

Directory: opendir, closedirDIR* opendir(const char* pathdir);,

– pathdir: path directory– ritorna il puntatore all’handle della directory, o NULL se si è verificato un errore

• quindi non si può usare direttamente la IFERROR(..), che fa il confronto con "-1”, occorre programmare la gestione degli errori esplicitamente

int closedir(DIR* dir); – dir: puntatore all’ handle di una directory già aperta

Page 28: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

29

Directory: opendir, closedir (2)DIR * d;

/* esempio di apertura directory */

if ((d = opendir(".")) == NULL){

perror("nell'apertura");

exit(errno);

}

/* lavoro sulla directory */

/* chiusura directory */

IFERROR(closedir(d),"nella chiusura");

Page 29: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

30

Directory: readdirstruct dirent* readdir(DIR * dir);,

– dir : handle della directory

– ritorna il puntatore ad una struttura struct dirent contenente le informazioni dell’elemento della directory che descrive il prossimo file

– letture successive forniscono i file successivi

– ritorna NULL quando i file sono finiti

– per tornare all’inizio

void rewinddir(DIR * dir);,

Page 30: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

31

Directory: readdir (2)/* campi interessanti di dirent … */

struct dirent {

/* # di i-node */

long d_ino;

/*lunghezza di d_name */

unsigned short d_reclen;

/* nome del file */

char d_name[NAMEMAX+1];

}

Page 31: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

32

Directory: readdir (3)DIR * d;

struct dirent * file; /* …. apertura directory */

/* lettura di tutte le entry della directory */

while ( (file = readdir(d))!=NULL) {

/* ad esempio stampo gli attributi di un file */

printattr(file->d_name);

}

/* chiusura directory */

IFERROR(closedir(d),"nella chiusura");

}

Page 32: 1 Esempio di ADT e make Operazioni bit a bit su piu’ file.

33

Directory corrente ...int chdir(const char* path)

int fchdir(int fd)• sono vere chiamate di sistema

• cambiano la directory corrente con quella indicata

char* getcwd(char* buf, size_t size)• permette di leggere la directory corrente dall’environment

• scrive il nome in buf (per un massimo di size caratteri)

• se non ci riesce ritorna NULL