Obtenir les attributs étendus du fichier en C
-
Utilisez les fonctions
getxattr
etlistxattr
pour obtenir les attributs étendus du fichier -
Utilisez la fonction
setxattr
pour définir les attributs étendus sur le fichier
Cet article explique plusieurs méthodes pour obtenir des attributs étendus d’un fichier en C.
Utilisez les fonctions getxattr
et listxattr
pour obtenir les attributs étendus du fichier
Certains systèmes UNIX fournissent des attributs étendus pour les fichiers, représentant des paires nom-valeur de métadonnées pouvant être associées au fichier. Les attributs étendus nécessitent la prise en charge du système de fichiers sous-jacent, mais les types de systèmes de fichiers courants ont cette fonctionnalité. Les attributs étendus ont le format spécifique de type - namespace.name
, où namespace
est utilisé pour regrouper des attributs fonctionnellement similaires, tandis que la partie name
identifie un attribut étendu individuel. Un espace de noms peut avoir les valeurs suivantes: user
, trusted
, system
et security
, qui distinguent plusieurs types d’autorisations par convention (décrit en détail sur la page). Dans ce cas, nous implémentons un exemple de programme qui prend plusieurs noms de fichiers comme arguments de ligne de commande et récupère par conséquent tous les attributs étendus pour chaque fichier. Notez que le programme traite les multiples arguments du fichier avec la fonction getopt
.
La fonction getxattr
prend quatre arguments pour récupérer une valeur d’attribut étendue. Le premier argument spécifie un chemin dans le système de fichiers pour indiquer le fichier pour lequel les EA doivent être récupérés, et le second argument spécifie un nom d’attribut. Les deux derniers arguments sont le pointeur vers l’emplacement où la valeur sera stockée par getxattr
et la taille du buffer disponible sur cette adresse. Notez que la taille de la valeur d’attribut peut être récupérée en passant la valeur 0
comme argument de taille et la valeur de retour de l’appel est le nombre d’octets pour le tampon nécessaire. Bien que, lorsque le deuxième appel est appelé pour récupérer la valeur, il peut être modifié et avoir une taille différente; il est donc préférable de vérifier les codes d’erreur pour garantir une exécution sans faute.
Par contre, la fonction listxattr
récupère la liste des noms d’attributs étendus pour le chemin de fichier donné. Il prend trois arguments, dont le premier est le chemin du fichier. Les deux arguments suivants représentent le tampon dans lequel la liste récupérée sera stockée et sa taille spécifiée en octets. Notez que cette mémoire tampon est allouée à l’appelant et que l’appelant est responsable d’allouer suffisamment de mémoire. De plus, comme pour le getxattr
, on peut passer la valeur 0
comme troisième argument à cette fonction, et la valeur retournée sera la taille du tampon nécessaire pour stocker la liste complète.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/xattr.h>
#include <unistd.h>
#define XATTR_SIZE 10000
#define errExit(msg) \
do { \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
static void usageError(char *progName) {
fprintf(stderr, "Usage: %s [-x] file...\n", progName);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
char list[XATTR_SIZE], value[XATTR_SIZE];
ssize_t listLen, valueLen;
int ns, j, k, opt;
bool hexDisplay;
hexDisplay = 0;
while ((opt = getopt(argc, argv, "x")) != -1) {
switch (opt) {
case 'x':
hexDisplay = 1;
break;
case '?':
usageError(argv[0]);
}
}
if (optind >= argc) usageError(argv[0]);
for (j = optind; j < argc; j++) {
listLen = listxattr(argv[j], list, XATTR_SIZE);
if (listLen == -1) errExit("listxattr");
printf("%s:\n", argv[j]);
for (ns = 0; ns < listLen; ns += strlen(&list[ns]) + 1) {
printf(" name=%s; ", &list[ns]);
valueLen = getxattr(argv[j], &list[ns], value, XATTR_SIZE);
if (valueLen == -1) {
printf("couldn't get value");
} else if (!hexDisplay) {
printf("value=%.*s", (int)valueLen, value);
} else {
printf("value=");
for (k = 0; k < valueLen; k++) printf("%02x ", (unsigned char)value[k]);
}
printf("\n");
}
printf("\n");
}
exit(EXIT_SUCCESS);
}
Utilisez la fonction setxattr
pour définir les attributs étendus sur le fichier
Alternativement, nous pouvons définir des attributs arbitraires pour les fichiers en utilisant la fonction setxattr
, qui prend le chemin du fichier, la paire nom-valeur comme arguments séparés, la taille de la valeur, un entier qui spécifie les valeurs prédéfinies pour différentes opérations d’ensemble. Si le dernier argument est zéro, qui est la valeur par défaut, l’attribut étendu est créé s’il n’existe pas; sinon, la valeur est remplacée. La macro XATTR_CREATE
peut être spécifiée pour indiquer uniquement l’option de création, qui échouera si l’attribut existe, et XATTR_REPLACE
pour effectuer un remplacement qui échoue si l’attribut n’existe pas.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/xattr.h>
#define errExit(msg) \
do { \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
static void usageError(char *progName) {
fprintf(stderr, "Usage: %s file\n", progName);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
char *value;
if (argc < 2 || strcmp(argv[1], "--help") == 0) usageError(argv[0]);
value = "x attribute value";
if (setxattr(argv[1], "user.x", value, strlen(value), 0) == -1)
errExit("setxattr");
value = "y attribute value";
if (setxattr(argv[1], "user.y", value, strlen(value), 0) == -1)
errExit("setxattr");
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook