Re: comment utiliser symlinkat(2) en programmation C
Pierre-Elliott Bécue <[email protected]>
| Newsgroups | gmane.linux.debian.user.french |
|---|---|
| Message-ID | <[email protected]> |
Salut ! Basile STARYNKEVITCH <[email protected]> wrote on 20/08/2026 at 10:18:30+0200: > Bonjour la liste, > > je cherche à comprendre (à travers un exemple de code en C ou C++ en > logiciel libre existant) l'utilisation de l'appel système symlinkat(2). symlinkat est juste symlink quand tu veux éviter de changer de CWD avant de faire ton appel. Je fais fi de la signature des fonctions pour la lisibilité symlink(target, linkpath) => inscrit la valeur de target (sans contrôle autre que vérifier que c'est un path valide) dans le fichier désigné par linkpath. linkpath peut être relatif ou absolu. S'il est relatif, c'est par rapport au CWD. S'il est absolu… il est absolu. symlinkat(target, newdirfd, linkpath) => tout comme symlink. Si linkpath est relatif, on exécute symlink depuis le fd ouvert dans newdir, et donc le fichier est créé relativement au newdir. S'il est absolu, alors newdirfd est ignoré. > (je peux aussi lire du Ocaml, Rust, à l'extrême rigueur python...) > > Celui ci prend en deuxième argument un descripteur de fichier vers un > répertoire existant. > > https://man7.org/linux/man-pages/man2/symlinkat.2.html > > J'ai l'impression (mais puis me tromper) que celui-ci s'obtient quez ce > descripteur de fichier doit avoir été le resultat d'un open(2) avec > l'option O_DIRECTORY C'est exact. Note que si le dossier n'existe pas, il faut le créer avec un autre syscall d'abord, et qu'un dossier existant s'ouvre toujours en lecture seule (sous peine de prendre un E_ISDIR) > un petit exemple de code en C me serait très utile (sur un Linux et des > systèmes de fichiers natifs et locaus: ext4, btrfs ou autre, pas VFAT > ou NFS) Pour l'exemple: mkdir "${HOME}/tmp/a" -p mkdir "${HOME}/tmp/b" -p touch "${HOME}/tmp/c" cd "${HOME}/tmp/a" Tu peux déposer et compiler le fichier en PJ avec gcc et le tester. Il fait ce qu'il raconte. -- PEB
play_symlinks.c
(text/x-csrc, 1.2 KB)
// À un printf de pouvoir éviter stdio :o
#include <stdio.h>
// symlink/symlinkat vivent ici
#include <unistd.h>
// Gestion des erreurs
#include <errno.h>
#include <string.h>
// Nécessaire pour les constantes AT_ dans les Xat même si ici on s'en sert pas
#include <fcntl.h>
int main(int argc, char **argv){
int mysmoothfd;
if((mysmoothfd = open("../b", O_DIRECTORY | O_RDONLY)) == -1){
printf("AAAAAAAAAA FFS %s\n", strerror(errno));
}
// Crée le symlink relatif d vers ../c
symlink("../c", "d");
// Crée le symlink absolu homeptr dans le dossier courant vers /home
symlink("/home", "homeptr");
// Crée le symlink relatif /home/XXX/tmp/b/d vers ../c (attention, ../c est relatif à /home/peb/tmp/b)
symlink("/home", "/home/peb/tmp/b/d");
// Crée le symlink relatif à ../b e vers ../c (attention, ../c est au sens de ../b)
symlinkat("../c", mysmoothfd, "e");
// Crée le symlink relatif à ../b f vers /home
symlinkat("/home", mysmoothfd, "f");
// Crée le symlink dans /home/peb/tmp/a e vers ../c (relatif à a, donc) en ignorant le fd b
symlinkat("../c", mysmoothfd, "/home/peb/tmp/a/e");
return 0;
}
signature.asc
(application/pgp-signature, 853 B)
-----BEGIN PGP SIGNATURE----- iQJDBAEBCgAtFiEE5CQeth7uIW7ehIz87iFbn7jEWwsFAmqGxUAPHHBlYkBkZWJp YW4ub3JnAAoJEO4hW5+4xFsLn9gP+weSDhSNsp/js4vTYqMOTVgbxScnYRpuVmGs yqy2z53KWCoXc8GlxvcUw+jBEf0k9nqKwTzXEwUYN4e3nIZpT2RrXDqL+Ps5PAVu pM9Nwj5bZIwo0+Mx6J3QEWlI2Tehjds+6DERA1oNsBLjcknZVUnR5jpb+gBflu4P 5X1XIyuQfaiRXUr2jaQJB+2nSCkN8Q0RB89QSR4zZJCM+gR7ZZJXPo3iZW3+Ly2c s0Pje5nhCcaP8B7w56FGanh8WhWW3qwxmcPcQ7CZLUpXwTKfwOzG3ArcvucA3D++ yLz9NpGKkrwpNwbvK7loEUGO6q8Ir4EcameBD+qOOQ+Wd74GcdxDo00R39DlbgKp OyLXAhje5mGtqgIKNL/v150Jz2lzOw4UMUPgcPc34DGt7ojCh+OcoYVnpBjWwpp1 Cc8rJiADGBgTKDfslcB1FIwX7yijuptvcNJhdNpUryyIC8Idg2qkB5k9GFxUa09H KWwuF8eQXMej3VLOOW8sscO2i0zmyylJnMYP7t2sSvotQ8f0WqPg+VA+nZR/72nC EaxOa98cyYf8iH2GA4/EZLw6PCqFeTKt87Bbu6mg80kN3m2eRXTEsaWG2J9rSmRz /+l0w2LkdNOTmGcxswdGsQa2/sOfUrpU3x1jxRbDapPgHrF/Shg6T0RRV2xYFy5b IoYuZ8/I =fu5w -----END PGP SIGNATURE-----