File e Directory M. Guarracino - File e Directory 1
File e Directory Abbiamo visto come si possono utilizzare funzioni di I/O per i file: open, read, write, lseek e close Vogliamo ora analizzare ulteriori caratteristiche del filesystem e proprietà dei file La struttura che contiene gli attributi dei file è stat Esamineremo ciascun membro di stat e le funzioni che operano su tali attributi; analizzeremo quindi le funzioni che operano su file e directory M. Guarracino - File e Directory 2
File e Directory (cont.) La gran parte dei file che risiedono in un filesystem sono file di dati regolari, ma ci sono anche altri tipi di file: file speciali a caratteri file speciali a blocchi FIFO socket link simbolici Il kernel di Unix non fa distinzione tra file di testo e binari Come possiamo ottenere quest informazione? M. Guarracino - File e Directory 3
Funzioni stat fstat lstat #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int int stat stat (const char *file_name, struct stat *buf); int int fstat (int (int filedes, struct stat *buf); int int lstat (const char *file_name, struct stat *buf); Queste funzioni ritornano informazioni sul file Non è necessario avere permessi di lettura sul file, per accedere a queste informazioni I permessi necessari sono di ricerca su tutte le directory nominate nel path M. Guarracino - File e Directory 4
Funzioni stat fstat lstat #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int int stat stat (const char *file_name, struct stat *buf); int int fstat (int (int filedes, struct stat *buf); int int lstat (const char *file_name, struct stat *buf); stat fstat lstat ritorna informazioni sul file file_name ritorna informazioni sul file aperto sul descrittore fildes ritorna informazioni sul link simbolico, non sul file puntato da esso M. Guarracino - File e Directory 5
La struttura stat struct stat { dev_t st_dev; /* device */ ino_t st_ino; /* inode */ mode_t st_mode; /* file type & protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device type (if inode device) */ off_t st_size; /* total size, in bytes */ unsigned long st_blksize; /* blocksize for filesystem I/O */ unsigned long st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ }; time_t st_ctime; /* time of last change */ M. Guarracino - File e Directory 6
Tipi di file struct stat { dev_t st_dev; /* device */ ino_t st_ino; /* inode */ mode_t st_mode; /* file type & protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device type (if inode device) */ off_t st_size; /* total size, in bytes */ unsigned long st_blksize; /* blocksize for filesystem I/O */ unsigned long st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ }; time_t st_ctime; /* time of last change */ M. Guarracino - File e Directory 7
Tipi di file (cont.) L'informazione sul tipo di file si trova nel membro st_mode della struttura stat Per determinare il tipo di file si utilizzano le seguenti macro, definite in <sys/stat.h> S_ISLNK( ) S_ISREG( ) S_ISDIR( ) symbolic link regular file directory S_ISCHR( ) character device S_ISBLK( ) block device S_ISFIFO( ) FIFO* S_ISSOCK( ) socket* M. Guarracino - File e Directory 8 *Non POSIX
#include <sys/types.h> #include <sys/stat.h> #include "ourhdr.h" Esempio int main(int argc, char *argv[]) { int i; struct stat buf; char *ptr; #ifdef #endif } for (i = 1; i < argc; i++) { printf("%s: ", argv[i]); if (lstat(argv[i], &buf) < 0) { } S_ISSOCK } exit(0); err_ret("lstat error"); continue; if (S_ISREG(buf.st_mode)) ptr = "regular"; else if (S_ISSOCK(buf.st_mode)) ptr = "socket"; else ptr = "** unknown mode **"; printf("%s\n", ptr); M. Guarracino - File e Directory 9
Permessi di accesso ai file Come si è visto, st_mode contiene l'informazione relativa al tipo di file (regular file, directory,...) Il valore di st_mode codifica anche i bit di permesso di accesso ai file. S_IRUSR 00400 owner read S_IWUSR 00200 owner write S_IXUSR 00100 owner execute S_IRGRP 00040 group read S_IWGRP 00020 group write S_IXGRP 00010 group execute S_IROTH 00004 others read S_IWOTH 00002 others write S_IXOTH 00001 others execute M. Guarracino - File e Directory 10
Permessi e creazione dei file #include <sys/types.h> #include <sys/stat.h> mode_t umask(mode_t mask); La funzione umask viene utilizzata da open e creat per assegnare i permessi ad un file creato Ad esempio, se il valore di default di umask viene inizializzato a 022, un nuovo file creato con permessi 666 avrà 666 & ~ 022 = 644 = r w - r - - r - - La funzione ritorna il valore precedente della maschera di creazione (mode creation mask) dei file. M. Guarracino - File e Directory 11
Esempio #include #include #include #include <sys/types.h> <sys/stat.h> <fcntl.h> "ourhdr.h" int main(void) { umask(0); if (creat("foo", S_IRUSR S_IWUSR S_IRGRP S_IWGRP S_IROTH S_IWOTH) < 0) err_sys("creat error for foo"); umask(s_irgrp S_IWGRP S_IROTH S_IWOTH); if (creat("bar", S_IRUSR S_IWUSR S_IRGRP S_IWGRP S_IROTH S_IWOTH) < 0) err_sys("creat error for bar"); exit(0); } M. Guarracino - File e Directory 12
Funzioni chmod fchmod #include <sys/types.h> #include <sys/stat.h> int int chmod (const char *path, mode_t mode); int int fchmod (int fildes, mode_t mode); Queste funzioni permettono di cambiare i permessi di accesso ad un file M. Guarracino - File e Directory 13
#include #include #include int main(void) { struct stat <sys/types.h> <sys/stat.h> "ourhdr.h" statbuf; Esempio /* set absolute mode to "rw-r--r--" */ if (chmod("bar", S_IRUSR S_IWUSR S_IRGRP S_IROTH) < 0) err_sys("chmod error for bar"); /* turn on set-group-id and turn off group-execute */ if (stat("foo", &statbuf) < 0) err_sys("stat error for foo"); if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) S_ISGID) < 0) err_sys("chmod error for foo"); exit(0); } M. Guarracino - File e Directory 14
User ID e Group ID struct stat { dev_t st_dev; /* device */ ino_t st_ino; /* inode */ mode_t st_mode; /* file type & protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device type (if inode device) */ off_t st_size; /* total size, in bytes */ unsigned long st_blksize; /* blocksize for filesystem I/O */ unsigned long st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ }; time_t st_ctime; /* time of last change */ M. Guarracino - File e Directory 15
Funzioni chown fchown lchown #include <sys/types.h> #include <unistd.h> int int chown (const char *path, uid_t owner, gid_t group); int int fchown (int fd, fd, uid_t owner, gid_t group); int int lchown (const char *path, uid_t owner, gid_t group); Tali funzioni permettono di cambiare lo user ID ed il group ID di un file Solo il superutente può modificarne il proprietario Un utente può solo modificarne il gruppo, con uno tra quelli supplementari a cui appartiene M. Guarracino - File e Directory 16
Set UID e Set GID A ciascun processo vengono associati i seguenti identificativi: real user ID e real group ID identificano l'utente effective user ID, effective group ID, e supplementary group ID determinano i permessi di accesso ai file saved set-user-id e saved set-group-id contengono copia dell effective user ID e effective group ID di un programma in esecuzione M. Guarracino - File e Directory 17
Set UID e Set GID Ogni file ha un proprietario ed un gruppo che lo possiede Tali informazioni si trovano in st_uid e st_gid di stat Quando si lancia un programma, questo viene eseguito con i permessi di chi lo manda in esecuzione, non di chi lo possiede Si può inizializzare un flag in st_mode in modo che, quando un determinato file di programma viene eseguito, l'effective user ID del processo sia quello di chi possiede il file. Tale flag è detto set-user-id flag. M. Guarracino - File e Directory 18
Esempio [mariog]$ ls -la /usr/bin/passwd -r-s--x--x 3 root sys 96416 Dec 10 1999 /usr/bin/passwd [mariog]$ passwd (Ctrl Z) [1]+ Stopped passwd [mariog]$ ps -efa grep passwd root 13816 13555 0 17:32:52 pts/2 0:00 passwd mariog 13818 13555 0 17:33:02 pts/2 0:00 grep passwd [mariog]$ M. Guarracino - File e Directory 19
Set UID e Set GID Analogamente è possibile mandare in esecuzione un processo con un effective group ID uguale a quello del file di programma Il relativo flag è detto set-group-id flag Se il set-group-id è applicato ad una directory, i file creati in quella directory ereditano il group ID dalla directory, non dall'effective group ID del processo che li ha creati S_ISUID S_ISGID 0004000 set UID bit 0002000 set GID bit S_ISVTX 0001000 sticky bit M. Guarracino - File e Directory 20
Esempio [mariog]$ uname -a SunOS 5.6 Generic_105181-20 sun4u sparc SUNW,Ultra-4 [mariog]$ umask 0 [mariog]$ touch prova [mariog]$ ls -la prova -rw-rw-rw- 1 mariog math 0 Dec 5 09:24 prova [mariog]$ chmod 7744 prova [mariog]$ ls -la prova -rwsr-lr-- 1 mariog math 0 Dec 5 09:24 prova [mariog]$ M. Guarracino - File e Directory 21
Esempio [mariog]$ uname -a Linux deneb0 2.2.16-22 #1 Tue Aug 22 16:49:06 EDT 2000 i686 [mariog]$ umask 022 [mariog]$ touch prova [mariog]$ ls -la prova -rw-r--r-- 1 mariog users 0 Dec 5 09:14 prova [mariog]$ chmod 7744 prova [mariog]$ ls -la prova -rwsr-sr-t 1 mariog users 0 Dec 5 09:14 prova [mariog]$ M. Guarracino - File e Directory 22
Grandezza dei file struct stat { dev_t st_dev; /* device */ ino_t st_ino; /* inode */ mode_t st_mode; /* file type & protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device type (if inode device) */ off_t st_size; /* total size, in bytes */ unsigned long st_blksize; /* blocksize for filesystem I/O */ unsigned long st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ }; time_t st_ctime; /* time of last change */ M. Guarracino - File e Directory 23
Grandezza dei file Il membro st_size di stat contiene la grandezza in byte del file. Ha senso solo per file regolari, directory e link simbolici Se presenti, st_blksize e st_blocks si riferiscono rispettivamente al migliore fattore di blocco per eseguire operazioni di I/O sul file e al numero di blocchi da 512 byte allocati per il file La libreria standard del C utilizza tale fattore di blocco per eseguire le operazioni su file M. Guarracino - File e Directory 24
Troncamento #include <unistd.h> int inttruncate (const char *path, off_t length); int int ftruncate (int fd, fd, off_t length); Queste funzioni troncano un file esistente a length byte Se il file ha meno di length byte, il comportamento della funzione dipende dall'implementazione Per troncare un file è preferibile copiarne solo la parte desiderata M. Guarracino - File e Directory 25
Filesystem M. Guarracino - File e Directory 26
Filesystem M. Guarracino - File e Directory 27
Link hard e simbolici struct stat { dev_t st_dev; /* device */ ino_t st_ino; /* inode */ mode_t st_mode; /* file type & protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device type (if inode device) */ off_t st_size; /* total size, in bytes */ unsigned long st_blksize; /* blocksize for filesystem I/O */ unsigned long st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ }; time_t st_ctime; /* time of last change */ M. Guarracino - File e Directory 28
Link hard e simbolici E' possibile che due directory puntino allo stesso i-node (hard link). Ciascun i-node ha un contatore che contiene il numero di directory che puntano all'i-node. Solo quando il contatore è 0, i blocchi associati al file possono essere rilasciati Un link simbolico è un file in cui è memorizzato il nome di un file, a cui punta il link M. Guarracino - File e Directory 29
Esempio lrwxrwxrwx 1 mariog user 17 Mar 20 22:42 zzz -> /users/mariog/tmp zzz è un file in cui i 17 byte di dati contengono /users/mariog/tmp (non viene memorizzato il carattere di terminazione) Non è possibile che una directory punti ad un i-node al di fuori del filesystem a cui appartiene M. Guarracino - File e Directory 30
Funzioni link E' possibile far puntare più directory all'i-node di un file La maniera per creare un hard link ad un file esistente è quella di usare la funzione link Solo il superutente può creare gli hard link #include <unistd.h> int intlink (const char *oldpath, const char *newpath); Alcune implementazioni richiedono che oldpath e newpath risiedano nello stesso filesystem. M. Guarracino - File e Directory 31
Funzioni unlink Per rimuovere un elemento dalla tabella della directory si utilizza la funzione unlink #include <unistd.h> int intunlink (const char *pathname); La funzione decrementa il numero di link del file puntato da pathname. Il file risulta ancora accessibile, se il numero di link è non nullo. M. Guarracino - File e Directory 32
Funzioni unlink Quando il numero di link del file è 0, il contenuto del file può essere cancellato Ciò non accade se un processo ha aperto il file Quando il file viene chiuso, il kernel conta il numero di processi che hanno aperto il file: se questo è zero ed il numero di link del file è zero, allora il file è cancellato Tale proprietà viene utilizzata per creare file accessibili solo da un determinato processo. M. Guarracino - File e Directory 33
Link Simbolici I link simbolici sono servono per aggirare il fatto che 1. un hard link non può essere fatto tra filesystem differenti 2. solo il superutente può creare un link tra directory Non ci sono limitazioni di filesystem per i link simbolici e qualsiasi utente può crearli. Essi sono normalmente utilizzati per spostare un file o un intero sottoalbero in un'altra posizione nel filesystem. M. Guarracino - File e Directory 34
Esempio temp [mariog]$ mkdir temp [mariog]$ touch temp/a test a [mariog]$ ln -s../temp temp/test [mariog]$ ls -l temp total 0 -rw-rw-r-- 1 mariog user 44 Mar 19 18:30 a lrwxrwxrwx 1 mariog user 7 Mar 19 18:31 test ->../temp [mariog]$ M. Guarracino - File e Directory 35
Funzioni symlink readlink #include <unistd.h> int int symlink (const char *oldpath, const char *newpath); int int readlink (const char *path, char *buf, size_t bufsiz); symlink viene utilizzata per creare un link simbolico. Non è necessario che oldpath esista Per leggere un link simbolico, è necessario utilizzare readlink, che apre il link, legge il contenuto e lo chiude Il contenuto del link è posto in buf, senza carattere di terminazione M. Guarracino - File e Directory 36
Sommario Abbiamo visto in dettaglio la struttura stat Abbiamo analizzato gli attributi dei file Unix e le funzioni che ci permettono di eseguire operazioni su di essi M. Guarracino - File e Directory 37