pub fn fchmodat2(
dirfd: DirFd<'_>,
path: &CStr,
mode: Mode,
flags: ChmodFlags,
) -> Result<(), Errno>Expand description
Modifie les permissions d’un fichier en honorant les drapeaux AT_*.
Wrappeur de fchmodat2(2) (numéro 452 sur x86_64 et aarch64, Linux ≥ 6.6).
§Pourquoi un second wrapper de chmod par chemin
Le syscall noyau fchmodat historique ne prend que 3 arguments
(dirfd, path, mode) : la couche C ajoute bien un paramètre flags dans
sa signature, mais le noyau ne le reçoit jamais — AT_SYMLINK_NOFOLLOW y est
donc silencieusement ignoré, et le chemin est toujours re-résolu en
suivant le lien symbolique final. C’est le même piège que
faccessat / [faccessat2], résolu de la même façon : un syscall à 4
arguments qui, lui, applique les drapeaux.
ChmodFlags::SYMLINK_NOFOLLOW ferme donc une fenêtre TOCTOU : entre le
moment où l’on crée un nœud (un socket Unix, par exemple) et celui où l’on
restreint ses permissions, un tiers ayant droit d’écriture sur le répertoire
conteneur peut substituer un lien symbolique et détourner le chmod vers un
fichier tiers. Avec ce drapeau, la substitution ne réussit pas : Linux ne sait
pas changer les permissions d’un lien symbolique et rend EOPNOTSUPP.
L’appelant obtient donc, en plus du chmod, la preuve que le chemin
désignait bien le nœud attendu — ou une erreur qu’il peut traiter.
EINTR est remonté tel quel : aucun retry automatique en couche 0 (ADR-021).
§Errors
EOPNOTSUPP:SYMLINK_NOFOLLOWdemandé et le chemin final est un lien symbolique (Linux ne modifie pas les permissions d’un lien).ENOENT: chemin inexistant.EPERM/EACCES: pas le droit de modifier ce nœud.ENOSYS: noyau < 6.6 (Air cible 6.12+, cf. ADR-004).
§Examples
use air_sys_syscall::fs::fchmodat2;
use air_sys_types::fs::{ChmodFlags, DirFd};
// Restreint le socket que nous venons de lier — sans jamais suivre un lien.
let result = fchmodat2(DirFd::Cwd, c"/run/air/forward.sock", 0o600, ChmodFlags::SYMLINK_NOFOLLOW);