Guillaume Chanel
Remerciements à Jean-Luc Falcone
Cours système d'exploitation by Guillaume Chanel, Jean-Luc Falcone and University of Geneva is licensed under CC BY-NC-SA 4.0
device ID
)Un inode contient trois temps différents:
atime | date du dernier accès à l'inode (ou aux données) |
---|---|
mtime | date de la dernière modification des données |
ctime | date de la dernière modifications des méta-données |
stat
)La commande stat
permet d'afficher des données sur un inode.
$ touch /tmp/myfile # met à jour les dates (crée un fichier si inexistant)
$ stat /tmp/myfile
File: /tmp/myfile
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 2fh/47d Inode: 422766 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ chanel) Gid: ( 1000/ chanel)
Access: 2019-07-19 16:56:35.540113838 +0200
Modify: 2019-07-19 16:56:35.540113838 +0200
Change: 2019-07-19 16:56:35.540113838 +0200
Birth: -
inodes
.unlink
).On peut créer un lien dur avec la commande ln
:
$ ln /tmp/myfile /tmp/newlink
$ stat /tmp/newlink
File: /tmp/myfile
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 2fh/47d Inode: 422766 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 1000/ chanel) Gid: ( 1000/ chanel)
Access: 2019-07-19 16:56:35.540113838 +0200
Modify: 2019-07-19 16:56:35.540113838 +0200
Change: 2019-07-19 16:56:35.540113838 +0200
Birth: -
On peut créer un lien dur avec la commande ln
en utilisant l'option -s
:
$ ln -s /tmp/myfile /tmp/newlink # (le lien dure précédent à été supprimé)
$ stat /tmp/newlink # comme indiqué ci-dessous on a bien à faire à un autre inode
File: /tmp/newlink -> /tmp/myfile
Size: 11 Blocks: 0 IO Block: 4096 symbolic link
Device: 2fh/47d Inode: 563876 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 1000/ chanel) Gid: ( 1000/ chanel)
Access: 2019-07-19 18:16:26.343945684 +0200
Modify: 2019-07-19 18:16:13.240259297 +0200
Change: 2019-07-19 18:16:13.240259297 +0200
Birth: -
link
, symlink
)unlink
)int unlink(const char *pathname);
pathname
est le nom à supprimerman 2 unlink
pour les codes d'erreursfsck
), il sera copié dans le répertoire lost+found
à la racine du système de fichier.sys/stat.h
)struct stat{
dev_t st_dev; //device ID
ino_t st_ino; //i-node number
mode_t st_mode; //protection and type
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 special file)
off_t st_size; //total size, in bytes
blksize_t st_blksize; //blocksize for filesystem I/O
blkcnt_t st_blocks; //number of 512B blocks
time_t st_atime; //time of last access
time_t st_mtime; //time of last modification
time_t st_ctime; //time of last change
};
stat
L'appel système stat()
permet de garnir une structure stat:
int stat(const char *path, struct stat *buf);
La fonction retourne 0 si tout s'est bien passé ou -1 en cas d'erreur (cf. errno
)
struct stat infos;
char *filename = "/tmp/foo.txt";
if( stat( filename, &infos ) < 0 )
fprintf( stderr, "Cannot stat %s: %s\n", filename, strerror(errno) );
else
printf( "Filesize: %d\n", infos.st_size );
st_mode
est un champs de bits contenant les permissions et le type d'un inode.S_ISREG(m) | fichier de données ? |
S_ISDIR(m) | répertoire ? |
S_ISCHR(m) | character device ? |
S_ISBLK(m) | block device ? |
S_ISFIFO(m) FIFO (named pipe) ? | |
S_ISLNK(m) | lien symbolique ? |
S_ISSOCK(m) socket? | |
if( S_ISDIR( info.st_mode ) ) {
printf( "L'inode est un repertoire.\n" );
}
On peut utiliser plusieurs flags pour accéder aux valeurs du champs de bits:
S_IRUSR | 00400 | owner has read permission |
S_IWUSR | 00200 | owner has write permission |
S_IXUSR | 00100 | owner has execute permission |
S_IRGRP | 00040 | group has read permission |
S_IWGRP | 00020 | group has write permission |
S_IXGRP | 00010 | group has execute permission |
S_IROTH | 00004 | others have read permission |
S_IWOTH | 00002 | others have write permission |
S_IXOTH | 00001 | others have execute permission |
lstat
stat("A",...)
retourne les informations sur l'inode de B.lstat()
:int lstat(const char *path, struct stat *buf);
stat()
.fstat
fstat()
fonctionne comme stat()
mais permet d'utiliser un descripteur de fichier à la place d'un nom:int fstat(int fd, struct stat *buf);
access
access()
:int access(const char *pathname, int mode);
mode
est un champs de bits formés des flags:
R_OK | lecture possible |
W_OK | écriture possible |
X_OK | éxécution possible |
F_OK
(seulement) qui indique si le fichier existe.access()
retourne 0 si le test réussit, -1 sinon (cf errno
)access
(2)char *fn = "/tmp/foo.txt";
if ( access( fn, R_OK|W_OK ) == 0 )
printf( "On peut lire et ecrire sur %s\n", fn );
else if ( errno == EACCES )
printf("Pas le droit de lire et/ou d'ecrire sur %s\n", fn);
else
perror( fn );
chmod
On peut changer les permissions d'un fichier grâce à l'appel système chmod
, similaire à la commande shell du même nom:
int chmod(const char *path, mode_t mode);
//Utilise un descripteur de fichier ouvert
int fchmod(int fd, mode_t mode);
Le paramètre mode
est un champs de bits formés des mêmes flags que le champs st_mode
de la structure stat
.
dirent
associants un lien à un inode.
et ..
dirent
Les entrées d'un répertoire sont représentées par la structure:
struct dirent { /* dirent.h */
ino_t d_ino; /* inode number */
off_t d_off; /* opaque value used to get next dirent (do not use) */
unsigned short d_reclen; /* length of this record */
unsinged char d_type; /* type of file; not supported by all file systems */
char d_name[256]; /* filename (NULL terminated), sometimes d_name[0] */
};
Seulement deux champs sont décrit par POSIX: d_ino
et d_name
.
Ne jamais compter sur la taille du tableau d_name
, uniquement sur la constante MAX_NAME
qui indique la longueur maximale des noms d'entrées ou sur strlen
dir_ent
(3)Le champs d_type
est un champs de bits contenant des informations sur le type de l'inode associé:
DT_DIR | Répertoire |
DT_LNK | Lien symbolique |
DT_REG | Fichier de données |
DT_UNKNOWN | Type inconnu |
DT_... | Voir man readdir pour tous les types. |
Pour accéder aux entrées d'un répertoire, il faut:
opendir()
readdir()
closedir()
opendir
)
DIR *opendir(const char *name);
DIR *fdopendir(int fd);
DIR
est un type opaqueDIR
sera NULL
man
):EACCESS | opération interdite (permissions) | ENOENT | Le répertoire n'existe pas ou le nom est une chaîne vide. | ENOTDIR | Le nom existe mais n'est pas un répertoire. |
readdir
)struct dirent *readdir(DIR *dirp);
dirent
NULL
s'il n'y a plus d'entrée ou en cas d'erreur.EBADF | Le descripteur dirp n'est pas valide. |
readdir
)closedir
)int closedir(DIR *dirp);
EBADF | Le descripteur dirp n'est pas valide. |
examples/listDir.c
)
mkdir
)int mkdir(const char *pathname, mode_t mode);
pathname
est le nom du répertoiremode
spécifie les permissions à utiliser, il est modifié par le umask
du processus:mode & ~umask & 0777
man 2 mkdir
pour les codes d'erreursrmdir
)int rmdir(const char *pathname);
man 2 rmdir
pour les codes d'erreurs