UNIXwork

Extended Attributes Teil 8: macOS Syscalls

2017-12-10 21:05:43.0

Für den Zugriff auf Extended Attributes hat macOS die Syscalls listxattr, getxattr, setxattr und removexattr. Sie heißen genauso wie die Linux-Syscalls und funktionieren auch fast genauso, nur haben sie ein paar Parameter für Options mehr. Die Syscalls finden sich im Header sys/xattr.h.

Um den Inhalt eines Attributs zu erhalten, benutzen wir den Syscall getxattr:

ssize_t
getxattr(const char *path, const char *name, void *value, size_t size,
        u_int32_t position,
        int options);

Dabei gibt man den Dateipfad, den Namen des Attributs, einen Pointer auf einen Buffer sowie dessen Größe an. Wie im vorherigen Artikel erwähnt, haben macOS Extended Attributes keinen Namespace, daher ist name ein frei wählbarer Name. Mit value und size gibt man einen vorher allozierten Puffer und seine Größe an. Falls value NULL ist, wird von der Funktion nur die Länge des Inhalts zurück gegeben. Der Parameter position funktioniert nicht mit allen Typen von Attributen und sollte daher 0 sein. Der Parameter options kann abgesehn von 0 noch XATTR_NOFOLLOW oder XATTR_SHOWCOMPRESSION sein.

char *buf = malloc(1024);
ssize_t attrlen = ("file.txt", "myattribute", buf, 1024, 0, 0);
if(attrlen > 0) {
    printf("myattribute: %.*s\n", (int)attrlen, buf);
}

Attribute hinzufügen oder verändern geht mit setxattr.

int setxattr(const char *path, const char *name, void *value, size_t size,
        u_int32_t position,
        int options);

position sollte auch hier wieder 0 sein. Bei den options gibt es wieder XATTR_NOFOLLOW und die interessanten Options XATTR_CREATE, um zu erzwingen, dass das Attribut nur gesetzt wird, falls es noch nicht existiert, oder XATTR_REPLACE, um nur den Inhalt eines bereits existierenden Attributs zu ändern.

char *value = "Hello World!";
setxattr("file.txt", "myattribute", value, strlen(value), 0, 0);

Alle existierenden Attribute auflisten geht mit listxattr.

ssize_t listxattr(const char *path, char *namebuf, size_t size, int options);

Dies schreibt in den vorher allozierten Buffer die Namen aller Attribute, getrennt durch ein 0-Byte. Hier findet sich ein Beispielprogramm, welches alle Attribute einer Datei auflistet.

Autor: Olaf | 0 Kommentare | Tags: macos, xattr, c

Extended Attributes Teil 7: macOS Commandline Tools

2017-12-09 19:31:52.0

Unter macOS sind Extended Attributes wie unter den meisten Betriebsystemen einfache name/value-Paare. Im unterschied zu Linux oder FreeBSD haben die Attribute keinen Namespace wie user oder system sondern einfach nur einen frei wählbaren Namen.

Extended Attributes können mit dem Tool xattr angezeigt und modifiziert werden. Außerdem kann auch ls Extended Attributes anzeigen. Eine kleine Übersicht über xattr:

Namen aller Attribute oder oder mehrerer Dateien auflisten:

xattr file ...

Value eines Attributs ausgeben:

xattr -p attr_name file ...

Attribut setzen:

xattr -w attr_name attr_value file ...

Attribut entfernen:

xattr -d attr_name file ...

Alle Attribute entfernen:

xattr -c file ...

Außerdem zeigt ls -l@ an, ob und welche Attribute eine Datei hat.

Ein kleines Beispiel:

$ echo "hello" > test.txt
$ rm test.txt 
$ echo "Hello World" > hello.txt
$ echo test > test.txt
$ xattr -w mime_type "text/plain" hello.txt 
$ xattr -w author Olaf hello.txt 
$ xattr -w testxattr testvalue test.txt 
$ ls -l@
total 16
-rw-r--r--@ 1 olaf  staff  12  9 Dez 19:18 hello.txt
    author   4 
    mime_type   10 
-rw-r--r--@ 1 olaf  staff   5  9 Dez 19:18 test.txt
    testxattr    9 
$ xattr -p mime_type hello.txt 
text/plain

Positiv ist, dass das macOS tar Extended Attributes im Archiv speichert. Auch cp kopiert sie standardmäßig. Insgesammt scheinen Extended Attributes unter macOS generell ein lebendigeres Feature als unter anderen Betriebsystemen zu sein, denn sie werden vom Finder oder anderen Programmen auch benutzt.

Autor: Olaf | 0 Kommentare | Tags: macos, xattr, shell

C: Attribute von allen Dateien im Verzeichnis

2016-12-23 21:06:16.0

Wenn man ein Verzeichnis liest und von allen enthaltenen Dateien die Extended Attributes erhalten will, gibt es zwei Möglichkeiten:

  1. Man fügt zum Verzeichnispfad den Dateinamen hinzu und nutzt den neu erhaltenen Pfad mit den Syscalls listxattr oder getxattr.
  2. Mit dem Filedescriptor des Verzeichnisses und openat öffnet man die Dateien und nutzt dann flistxattr und getxattr.

Ich hab mich gefragt was schneller ist. Dazu habe ich ein kleines Testprogramm geschrieben. Dieses kann mit unterschiedlichen Preprocessor-Optionen kompiliert werden. So habe ich 4 Testprogramme erstellt. Für getxattr und fgetxattr jeweils ein Programm, das ein Attribut liest und eines das 32 Attribute liest.

Bei einem Verzeichnis mit 128.000 Dateien hab ich folgende Werte erhalten:

getxattr:1  getxattr:32  fgetattr:1  fgetattr:32
------------------------------------------------
246100055   654704421    456172044   749849574
230183311   663632162    457183706   769223423
247109480   654775136    440397212   743349119

Die Datei erst zu öffnen um dann fgetxattr zu nutzen ist also langsamer. Erst als ich das Programm so modifiziert habe, dass es mehrere hundert Attribute liest, war es etwas schneller. Das ist jedoch ein eher unrealistisches Szenario. Allerdings war das ganze generell sehr schnell, so dass es eigentlich egal ist, welche Methode man anwendet.

Autor: Olaf | 0 Kommentare | Tags: linux, c, xattr, benchmark

Linkdump

2016-12-15 22:38:36.0
Autor: Olaf | 0 Kommentare | Tags: links, xattr, macos

Extended Attributes Teil 6: Solaris Syscalls

2016-12-13 18:07:26.0

Programmiertechnisch sind Extended Attributes unter Solaris nur Dateien, daher gibt es keine speziellen Syscalls für den Zugriff darauf.

Eine Attribut-Datei öffnen kann man mit openat. Hierfür benötigt man nur einen File-Descriptor der Datei, von der man ein Attribut öffnen will. Es muss dann nur noch das O_XATTR-Flag zusätzlich angegeben werden. Man erhält einen gewöhnlichen File-Descriptor, aus dem wie gewohnt gelesen und geschrieben werden kann.

Hier ist ein kleines Beispielprogramm, dass ein Attribut ausliest und auf der Konsole ausgibt.

Die Liste aller Attribute erhält man, in dem man das Attribut-Verzeichnis ließt. Der Trick ist hier, dass man das “.“-Verzeichnis relativ zur Datei mit dem O_XATTR-Flag öffnet.

int attrdir = openat(file, ".", O_RDONLY|O_XATTR);

Hier ist ein Beispiel dafür.

Für andere Dateisystemoperationen wie z.B. unlink oder chown gibt es ebenfalls *at-Funktionen, die man in Kombination mit einem File-Desriptor des Attribut-Verzeichnis benutzen kann. Siehe unlinkat, fstatat, fchownat.

Anstatt zuerst eine Datei mit open und danach mit openat das Attribut zu öffnen, kann man auch attropen benutzen, die das ganze in einer Funktion zusammenfasst.

Autor: Olaf | 0 Kommentare | Tags: solaris, xattr, c
Weiter