© D. Mathieu
mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique
Créé le 04/08/2000 -
Dernière mise à jour : 07/09/2001
|
|
chmod() | /usr/include/sys/stat.h |
close() | /usr/include/unistd.h |
creat() | /usr/include/fcntl.h [2] |
dup() | /usr/include/unistd.h |
dup2() | /usr/include/unistd.h |
fchmod() | /usr/include/sys/stat.h |
fcntl() | /usr/include/fcntl.h |
flock() | /usr/include/sys/file.h |
fstat() | /usr/include/sys/stat.h |
lseek() | /usr/include/unistd.h |
open() | /usr/include/fcntl.h |
pipe() | /usr/include/unistd.h |
read() | /usr/include/unistd.h |
stat() | /usr/include/sys/stat.h |
umask() | /usr/include/sys/stat.h |
unlink() | /usr/include/unistd.h |
write() | /usr/include/unistd.h |
Pour pouvoir être utilisées, certaines de ces fonctions peuvent de plus nécessiter l'inclusion d'autres fichiers parmi lesquels :
/usr/include/g++-2[3]/cerrno[4]
// conformément à la norme C++
/usr/include/g++-2/climits[5] // conformément à la norme C++ /usr/include/sys/types.h // types comme mode_t, etc. /usr/include/posix1_lim.h |
En cas d'erreur en cours d'exécution, la plupart des fonctions système renvoient la valeur -1 et positionnent dans la variable errno (accessible par inclusion du fichier <cerrno>, mais défini dans le fichier <asm/errno.h>), un code d'erreur précisant la cause exacte de l'erreur. Cette information n'est parfois pas assez précise et doit être complétée par la consultation du manuel (man 2 nom_de_la_fonction ou commande xman).
bits 0, 1, 2
bits 3, 4, 5 bits 6, 7, 8 bit 9 bit 10 bit 11 |
exécution, accès en écriture et lecture
pour tous les utilisateurs,
exécution, accès en écriture et lecture pour le groupe du propriétaire, exécution, accès en écriture et lecture pour le propriétaire, bit de "collage" (sticky-bit) bit SET-GUID bit SET-UID |
On a l'habitude de représenter les neuf premiers bits des masques de protection dans l'ordre des bits décroissants, en représentant l'état des bits par les symboles r, w et x lorsque les bits sont positionnés et - lorsqu'ils sont à la valeur 0. Ainsi, rwxrw-r-- est un masque autorisant l'accès du fichier correspondant en lecture à tout le monde, en écriture seulement au propriétaire et au groupe auquel il appartient, et limite les droits d'exécution au seul propriétaire.
i Il est fréquent d'exprimer un masque de droits d'accès directement par la valeur numérique des groupes de trois bits, en utilisant la numération octale. Ainsi, la valeur du masque ci-dessus (rwxrw-r--) correspond à 0764. Attention : seul le 0 qui précède le nombre indique qu'il s'agit d'une valeur octale.
i Les trois bits de fort poids n'ont de signification que pour un fichier exécutable. S'ils sont positionnés, les bits SET-UID/SET-GUID sont représentés par s à la place des x correspondants. S'il est positionné, le sticky-bit est représenté par t à la place de x des utilisateurs :
-rwxr-xr-t 2 root
root 3398964 Apr 19 18:24 emacs
-rwxr-xr-t 2 root root 3398964 Apr 19 18:24 emacs-20.3 |
-r-s--x--x 1 root
root 10704 Apr 14 23:21 passwd
... -r-sr-sr-x 1 uucp uucp 127924 Mar 22 08:07 cu[7] |
Le fichier /usr/include/linux/stat.h contient toutes les constantes symboliques permettant de positionner ou d'extraire ces différents bits, par exemple :
#define S_IRWXU 00700 /* read,write,execute perm: owner
*/
#define S_IRUSR 00400 /* read, permission: owner */ #define S_IWUSR 00200 /* write, permission: owner */ #define S_IXUSR 00100 /* execute/search, permission: owner */ #define S_IRWXG 00070 /* read,write,execute perm: group */
#define S_IRWXO 00007 /* read,write,execute perm: other */
|
ainsi que des macros permettant de tester le type du fichier :
#define S_IFMT 00170000
#define S_IFSOCK 0140000 #define S_IFLNK 0120000 #define S_IFREG 0100000 #define S_IFBLK 0060000 #define S_IFDIR 0040000 #define S_IFCHR 0020000 #define S_IFIFO 0010000 #define S_ISUID 0004000 #define S_ISGID 0002000 #define S_ISVTX 0001000 #define S_ISLNK(m) (((m) & S_IFMT)
== S_IFLNK)
|
La signification de ces macros est obtenu par la commande man 2 stat :
S_ISLNK(m) is it a symbolic link?
S_ISREG(m) regular file? S_ISDIR(m) directory? S_ISCHR(m) character device? S_ISBLK(m) block device? S_ISFIFO(m) fifo? S_ISSOCK(m) socket? |
où m est la valeur du champ st_mode de la structure stat renvoyée par la fonction système stat() :
struct stat
{ ...... umode_t st_mode; /* protection */ ...... }; |
... open ("/users/prof/mathieu/PRIVE/tp/tpsys/dirfile/exo_01.cxx", ... |
A tout fichier (au sens large : périphérique, fichier disque, socket, pipe, etc.) ouvert correspond un entier qui doit être utilisé dans toutes les opérations à effectuer sur ce fichier : le descripteur de fichier (file descriptor). Cet entier est attribué par le système lorsque le fichier est ouvert.
La majorité des types importants sont à rechercher dans la hiérarchie[8] suivante :
<sys/types.h>
<features.h> <bits/types.h> |
Voici quelques types définis dans le fichier <sys/types.h> :
...
#include <features.h> #include <bits/types.h> typedef __u_char u_char; typedef __u_short u_short; ... #ifdef __USE_BSD ... # include <endian.h> ... #endif /* Use BSD. */ |
Le fichier <features.h> contient de nombreuses macros qui définissent l'environnement :
/* These
are defined by the user (or the compiler) to specify the desired environment:
__STRICT_ANSI__ ISO Standard C. _ISOC9X_SOURCE Extensions to ISO C 89 from ISO C 9x. _POSIX_SOURCE IEEE Std 1003.1. _POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if >=2 add IEEE Std 1003.2; if >=199309L, add IEEE Std 1003.1b-1993; if >=199506L, add IEEE Std 1003.1c-1995 _XOPEN_SOURCE Includes POSIX and XPG things. Set to 500 if Single Unix conformance is wanted. _XOPEN_SOURCE_EXTENDED XPG things and X/Open Unix extensions. _LARGEFILE_SOURCE Some more functions for correct standard I/O. _LARGEFILE64_SOURCE Additional functionality from LFS for large files. _FILE_OFFSET_BITS=N Select default filesystem interface. _BSD_SOURCE ISO C, POSIX, and 4.3BSD things. _SVID_SOURCE ISO C, POSIX, and SVID things. _GNU_SOURCE All of the above, plus GNU extensions. _REENTRANT Select additionally reentrant object. _THREAD_SAFE Same as _REENTRANT, often used by other systems. ... These are defined by this file and are used by the header files to decide what to declare or define: __USE_ISOC9X Define ISO C 9X things. __USE_POSIX Define IEEE Std 1003.1 things. __USE_POSIX2 Define IEEE Std 1003.2 things. __USE_POSIX199309 Define IEEE Std 1003.1, and .1b things. __USE_POSIX199506 Define IEEE Std 1003.1, .1b, .1c and .1i things. __USE_XOPEN Define XPG things. __USE_XOPEN_EXTENDED Define X/Open Unix things. __USE_UNIX98 Define Single Unix V2 things. __USE_LARGEFILE64 Define LFS things with separate names. __USE_FILE_OFFSET64 Define 64bit interface as default. __USE_BSD Define 4.3BSD things. __USE_SVID Define SVID things. __USE_MISC Define things common to BSD and System V Unix. __USE_GNU Define GNU extensions. __USE_REENTRANT Define reentrant/thread-safe *_r functions. __USE_REENTRANT Define reentrant/thread-safe *_r functions. __FAVOR_BSD Favor 4.3BSD things in cases of conflict. ... #if (_POSIX_C_SOURCE - 0) >= 199309L # define __USE_POSIX199309 1 #endif #if (_POSIX_C_SOURCE - 0) >= 199506L # define __USE_POSIX199506 1 #endif ... |
Le fichier <bits/types.h> contient quelques types utilisés dans différents fichiers en fonction des macros qui définissent l'environnement.
L'utilisateur ne devrait pas avoir à les utiliser :
...
/* Convenience types. */ typedef unsigned char __u_char; typedef unsigned short __u_short; typedef unsigned int __u_int; typedef unsigned long __u_long; ... |
De nombreuses constantes importantes sont à rechercher dans la hiérarchie suivante :
<limits.h>
<bits/posix1_lim.h> <sys/file.h> voir plus loin la fonction flock() ... |
Voici quelques types définis dans le fichier <limits.h> :
...
#ifdef __USE_POSIX /* POSIX adds things to <limits.h>. */ # include <bits/posix1_lim.h> #endif ... /* Number of bits in a `char'. */ # define CHAR_BIT 8 /* Minimum and maximum values a `signed char' can hold. */ # define SCHAR_MIN (-128) # define SCHAR_MAX 127 /* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ # define UCHAR_MAX 255 /* Minimum and maximum values a `char' can hold. */ # ifdef __CHAR_UNSIGNED__ # define CHAR_MIN 0 # define CHAR_MAX UCHAR_MAX # else # define CHAR_MIN SCHAR_MIN # define CHAR_MAX SCHAR_MAX # endif /* Minimum and maximum values a `signed short int' can hold. */ # define SHRT_MIN (-32768) # define SHRT_MAX 32767 .... /* Minimum and maximum values a `signed int' can hold. */ # define INT_MIN (-INT_MAX - 1) # define INT_MAX 2147483647 |
Le fichier <bits/posix1_lim.h> contient des constantes définies dans la norme Posix :
...
#define _POSIX_FD_SETSIZE _POSIX_OPEN_MAX /* Number of bytes in a filename. */ #define _POSIX_NAME_MAX 14 /* Number of bytes in a pathname. */ #define _POSIX_PATH_MAX 255 #define SSIZE_MAX INTMAX ... |
Le fichier <bits/stdio_lim.h> contient quelques constantes concernant les fichiers :
...
# define L_tmpnam 20 # define TMP_MAX 238328 # define FILENAME_MAX 4095 ... #if defined __need_FOPEN_MAX || defined _STDIO_H # undef FOPEN_MAX # define FOPEN_MAX 256 ... |
Tous les codes d'erreurs sont déclarés dans le fichier <asm/errno.h> :
#ifndef _I386_ERRNO_H
#define _I386_ERRNO_H #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */ #define EIO 5 /* I/O error */ ... ... #define ENOTNAM 118 /* Not a XENIX named type file */ #define ENAVAIL 119 /* No XENIX semaphores available */ #define EISNAM 120 /* Is a named type file */ #define EREMOTEIO 121 /* Remote I/O error */ #define EDQUOT 122 /* Quota exceeded */ #define ENOMEDIUM 123 /* No medium found */ #define EMEDIUMTYPE 124 /* Wrong medium type */ #endif |
Il est souvent nécessaire de s'y référer pour trouver la signification d'une erreur système lorsque seule la valeur numérique de la variable errno est connue. Rappelons encore que errno est accessible par le fichier /usr/include/g++-2/cerrno, qui inclut le fichier /usr/include/errno.h, qui inclut lui-même /usr/include/asm/errno.h.
Les mécanismes mis en place par ces trois fonctions sont semblables. Cependant il est extrêmement important de noter que les opérations de (dé)verrouillage des fichiers mis en place par les fonctions fcntl(2) et lockf(3) sont compatibles entre eux (un fichier verrouillé par la fonction fcntl() peut être déverrouillé par la fonction lockf(3), et inversement). En revanche, les opérations réalisées au moyen de la fonction flock(2) sont totalement ignorées par la fonction fcntl(2) et inversement. Ces mécanismes de protection/exclusion mutuelle (advisory lock) ne sont actifs qu'entre processus qui les utilisent : s'il n'utilise pas ces fonctions, un processus peut lire/écrire sans gène un fichier par ailleurs verrouillé.
Avant de présenter les détails des différentes fonctions, il faut rappeler le principe des " lecteurs-rédacteurs" : lorsqu'un lecteur lit une information, il ne la modifie pas, donc un nombre quelconque de lecteurs peut être autorisé à lire simultanément la même information. Au contraire un rédacteur, modifiant l'information, ne peut être autorisé à écrire que si aucun autre rédacteur n'est déjà en train de la modifier lui-même, et si aucun lecteur n'est en train de la consulter. C'est exactement à ce schéma que doit correspondre l'utilisation en lecture/écriture d'un fichier simultanément par plusieurs processus. Les différentes fonctions de dé/verrouillage des fichiers présentent donc des caractéristiques générales :
Comme sous Unix, ces fonctions positionnent la variable globale errno en cas d'erreur et renvoient la valeur –1. De plus les trois flux standard ouverts au lancement d'une application sont :
[1] Toutes les informations dans ce document sont conformes à l'installation RedHat Linux Release 6.0 - Kernel 2.2.15 sur un i686.
[2] En fait, le fichier <fcntl.h> sert de relais pour inclure de nombreux autres fichiers y compris <sys/fcntl.h>
[3] Noter que le compilateur g++ est à peu près conforme à la norme C++. A ce titre, il interprète les directives d'inclusion de fichiers selon qu'ils ont ou non l'extension .h :
#include <cerrno> est équivalent à
#include "/usr/include/g++-2/cerrno" et
#include <errno.h> est équivalent à
#include "/usr/include/errno.h"
[4] en C standard, fichier /usr/include/errno.h
[5] en C standard, fichier /usr/include/limits.h
[6] lié au fichier, donc stocké dans son i-node.
[7] cu(1) est une commande permettant d’appeler un système distant (par téléphone)
[8] tous ces fichiers sont dans le nœud /usr/include/ qui est représenté par <>
© D. Mathieu
mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique