Alternative File-Systeme im Griff

Spätestens seit dem Erscheinen von MagiC 3, das wie MiNT die Einbindung alternativer File-Systeme erlaubt, ist das Interesse daran, wie man diese in eigenen Programmen korrekt unterstützt, stark gestiegen. Der folgende Artikel soll einen Einblick verschaffen und bietet ein kleines Beispiel-Listing, damit auch die praxisnahe Anwendung deutlich wird.

Interessierten Programmierern hilft es wenig, wenn man immer wieder liest, das GEMDOS von MagiC 3 verhalte sich MiNT-kompatibel, man müsse eben einfach die bekannten GEMDOS-Aufrufe ohne spezielle MiNT-Abfrage benutzen, denn schließlich hat sich nicht jeder bereits mit MiNT auseinandergesetzt, und zudem läßt die zu MiNT gehörende Dokumentation stark zu wünschen übrig.

Es ist übrigens sehr begrüßenswert, daß MagiC 3 bei der Ansteuerung alternativer File-Systeme auf GEMDOS-Ebene kein eigenes Süppchen kocht (ähnliches gilt jetzt zum Glück auch weitestgehend für die AES), denn sonst wäre eine allgemeine Unterstützung wesentlich schwiegeriger, was sicherlich nicht zu einer großen Akzeptanz auf seiten der Programmierer geführt hätte. Daß MagiC intern andere Wege geht, führt zwar leider dazu, daß man vorhandene MiNT-File-Systeme nicht direkt in MagiC einbinden kann; allerdings gehe ich davon aus, daß es nicht lange dauern wird, bis eine MagiC-Version des unter MiNT so beliebten Minix-File-Systems vorhanden ist.

Los geht’s

Jetzt aber genug der Vorrede, auf in den Kampf... Sämtliche im folgenden vorgestellten Funktionen sind GEMDOS-Aufrufe, was uns in die glückliche Lage versetzt, ihr Vorhandensein durch einen einfachen Testaufruf zu prüfen. Erhält man als Rückgabewert -32 (als Long!), ist die entsprechende Funktion nicht implementiert. Leider versagt das Verfahren, wenn man z.B. feststellen will, ob ein Standard-GEMDOS-Aufruf um gewisse Features erweitert ist (beispielsweise Pexec mit neuen Modi oder Mxalloc mit Speicherschutz). Für die Unterstützung alternativer File-Systeme ist dies aber nicht von Bedeutung, also können wir loslegen ...

Der Einfachheit halber sind die C-Prototypen der Funktionen und ihre GEMDOS-Nummern in Tabelle 1 aufgeführt, somit bleibt dieser Text frei von lästigen Codeeinschüben. Es folgt jetzt zuerst eine Beschreibung aller Funktionen, danach die Erläuterung, wie man im einzelnen vorzugehen hat.

Pdomain

Mittels Pdomain läßt sich unter MiNT kontrollieren, in welcher „Domain“ ein Prozeß läuft. Bislang sind nur 0 (TOS-Domain) und 1 (MiNT-Domain) definiert. In ersterer verhalten sich alle GEMDOS-Aufrufe vollkommen TOS-kompatibel, insbesondere Fsfirst und Fsnext. Von in der MiNT-Domain laufenden Prozessen hingegen erwartet das Betriebssystem, daß sie mit alternativen File-Systemen zurechtkommen. Daneben werden auch noch andere Dinge beeinflußt, die an dieser Stelle aber nicht von Interesse sind.

Mit dem Parameter dom legt man die neue Domain fest. Als Rückgabewert erhält man, wenn die Funktion implementiert ist, stets die alte Domain. Möchte man nur die momentan gültige ermitteln, ist für dom ein Wert kleiner Null zu übergeben. Gibt man einen ungültigen Wert (bisher: größer als 1) für dom an, sind das Verhalten der Funktion und des Kernels Undefiniert!

Man sollte immer versuchen, zu Programmbeginn in die MiNT-Domain zu schalten, da die meisten File-Systeme sonst nur verstümmelte TOS-File-Namen liefern. Auch das Vorhandensein von Pdomain sollte man nur durch einen Testaufruf [Pdomain(-1)] ermitteln und dann gegebenenfalls in die MiNT-Domain wechseln, da auch andere Betriebssysteme einen ähnlichen Mechanismus zur Verfügung stellen könnten.

Dpathconf

Diese Funktion erlaubt es, Informationen über Eigenschaften und Beschränkungen des File-Systems zu ermitteln, auf dem die Datei bzw. der Pfad name liegt. Der Parameter mode bestimmt dabei, was man wissen möchte, im einzelnen:

-1 (DP_MAXREQ): Rückgabewert, gibt den maximal zulässigen Wert von mode an (auch dieser ist abhängig vom File-System!)

Wird ein zu großer Wert für mode gewählt, liefert Dpathconf EINVFN zurück. In Tabelle 3 finden sich übrigens alle GEMDOS-Fehlermeldungen und ihre symbolischen Namen.

0 (DP_IOPEN): ermittelt die Höchstzahl gleichzeitig geöffneter Dateien auf dem betroffenen Dateisystem (muß keinesfalls mit dem GEMDOS-Filehandle-Limit übereinstimmen, das mit Sysconf ermittelt werden kann, worauf ich aber nicht weiter eingehen werde).

1 (DP_MAXLINKS): ermittelt die maximale Zahl von „echten" Links auf ein File.

2 (DP_PATHMAX): Rückgabewert, enthält maximale Länge eines kompletten Pfadnamens.

3 (DP_NAMEMAX): ermittelt maximale Länge eines einzelnen File-Namens.

4 (DP_ATCOMIC): Rückgabewert, gibt an, wie viele Bytes höchstens „atomar“, also an einem Stück, geschrieben werden können.

5 (DP_TRUNC): ermittelt Informationen über die Behandlung (zu) langer File-Namen.

6 (DP_CASE): ermittelt Informationen darüber, wie das File-System Grofr/Kleinschreibung behandelt.

7 (DP_MODEATTR): liefert Informationen, welche TOS-Attribute, welche Unix-File-Modi und welche File-Typen das File-System verwalten kann.

8 (DP_XATTRFIELDS): Mit diesem Modus kann man ermitteln, welche Felder der XATTR-Struktur (siehe auch Fxattr und Tabelle 3) tatsächlich unterstützt, also nicht einfach mit möglichst passenden Werten gefüllt werden.

Dpathconf liefert bei den Modi 0 bis 4 0x7fffffffL (UNLIMITED), um „unendlich“ anzuzeigen.

Die Rückgabewerte von Modus 5 sind wie folgt:

0 (DP_NOTRUNC): File-Namen werden nie abgeschnitten; ist der File-Name bei einer Dateioperation zu lang, wird ERANGE geliefert.

1 (DP_AUTOTRUNC): File Namen werden automatisch auf die maximale Länge gestutzt.

2 (DP_TOSTRUNC): File-Namen werden auf TOS-Format gewandelt, also maximal 8 Zeichen File-Name und 3 Zeichen Endung.

Für Modus 6 sind die folgenden Rückgabewerte definiert:

0 (DP_CASESENS): Das File-System ist voll „case sensitive“, unterscheidet also Groß- und Kleinschreibung bei File- bzw. Pfadnamen.

1 (DP_CASECONV): Das File-System ist nicht „case sensitive“, die Originalschreibweise wird nicht übernommen. Beispiel ist das TOS-Dateisystem: Alle File-und Pfadnamen werden grundsätzlich in Großbuchstaben umgewandelt.

2 (DP_CASEINSENS): Das File-System ist nicht „case sensitive“, die Originalschreibweise wird jedoch übernommen. Eine Datei, die mit dem Namen „File“ angelegt wurde, erscheint so im Verzeichnis, kann aber auch als „file“, „fILE“, usw. angesprochen werden. Beispiel hierfür ist u:\proc unter MiNT.

Modus 7 liefert eine Bit-Datenstruktur: Die Bits 0 bis 7 geben an, welche TOS-Attribute erlaubt sind, Bits 8-19 enthalten die erlaubten Unix-File-Modi, und in den Bits 20 - 31 ist angegeben, welche File-Typen Vorkommen können (als Bit-Vektor). Sie finden sie in Tabelle 2.

Modus 8 liefert im unteren Wort einen Bit-Vektor, der die tatsächlich benutzten erweiterten Attribute angibt. Die Belegung:

0x0001 (DP_INDEX]
0x0002 (DP_DEV)
0x0004 (DP_RDEV)
0x0008 (DP_NLINK1 
0x0010 (DP_UID)
0x0020 (DP_GID)
0x0040 (DP_BLKSIZE) 
0x0080 (DP_SIZE)
0x0100 (DP_NBLOCKS) 
0x0200 (DP_ATIME]
0x0400 (DP_CTIME)
0x0800 (DP_MTIME)

Anhand der symbolischen Namen kann man erkennen, welche Felder der XATTR-Struktur gemeint sind.

Tabelle 1

Pdomain (GEMDOS 281)
C-Prototyp:
LONG Pdomain(WORD dom);

Dpathconf (GEMDOS 292)*
C-Prototyp:
LONG Dpathconf(char *name, WORD mode);

Dopendir (GEMDOS 296)
C-Prototyp:
LONG Dopendir(char *name, WORD flag);

Dreaddir (GEMDOS 297)
C-Prototyp:
LONG Dreaddir(WORD len, LONG dirhandle, char *buf);

Drewinddir (GEMDOS 298)
C-Prototyp:
LONG Drewinddir(LONG dirhandle);

Dclosedir (GEMDOS 299)
C-Prototyp:
LONG Dclosedir(LONG dirhandle);

Fxattr (GEMDOS 300)
C-Prototyp:
LONG Fxattr(WORD flag, char *name, XATTR *xattr);

Dgetcwd (GEMDOS 315)
C-Prototyp:
LONG Dgetcwd(char *path, WORD drive, WORD size);

Dxreaddir (GEMDOS 322)
C-Prototyp:
LONG Dxreaddir(WORD len, LONG dirhandle, char *buf,+ XATTR *xattr, LONG *xret);

Dreadlabel (GEMDOS 338)
C-Prototyp:
LONG Dreadlabel(char *path, char *label,+WORD length)?

Dwritelabel (GEMDOS 339)
C-Prototyp:
LONG Dwritelabel(char *path, char *label);

Tabelle 2

0x00100000L	(DP_FT_DIR, Verzeichnisse)
0x00200000L	(DP_FT_CHR, spezielle zeichenorientierte Files, z.B. BIGS-Geräte)
0x00400000L	(DP_FT_BLK, spezielle blockorientierte Files)
0x00S00000L	(DP_FT_REG, normale Files)
0x01000000L	(DP_FT_LNK, symbolische Links)
0x02000000L	(DP_FT_SOCK, Sockets)
0x040000001	(DP_FT_FIFO, Pipes)
0x08000000L	(DP_FT_MEM, Shared-Memory- oder Prozeß-Files)

Es ist übrigens nicht ratsam, wie in [2] beschrieben, am Anfang des Programms mit Dpathconf die maximale Pfad- und Dateilänge zu ermitteln. Man sollte lieber vor jedem Einlesen eines Verzeichnisses die jeweils gültigen Werte ermitteln und darauf reagieren können, daß die Puffer, die man bisher benutzt hat, nicht mehr groß genug sind. Das ist deshalb nötig, da man alternative File-Systeme auch auf wechselbaren Medien anlegen kann, somit kann es also passieren, daß der Benutzer zwischenzeitlich ein neues Medium eingelegt hat, das die anfangs ermittelten Maximallängen überschreitet (der Autor von [2] hatte darauf allerdings auch hingewiesen).

Es empfiehlt sich auch, wenn man Informationen über die in einem Verzeichnis enthaltenen Files ermitteln möchte, dies nicht durch Angabe des Pfades für name zu tun. Besser ist es, mit Dsetpath in das entsprechende Verzeichnis zu wechseln und dann Informationen über '.' anzufordern. Der Sinn liegt darin, daß das gewünschte Directory ein symbolischer Link auf ein Verzeichnis auf einem ganz anderen File-System sein kann. Benutzt man den Pfadnamen bei Dpathconf, erhält man jedoch nur Informationen über das File-System, auf dem der Link liegt, und nicht über das, auf das der Link zeigt. Mit der zweiten Methode erhält man stets das gewünschte Ergebnis. Den gleichen Effekt hat natürlich auch das Anhängen von „.“ an den zu untersuchenden Pfad.

Beim Benutzen von Dpathconf sollte man auch immer den Rückgabewert von Modus -1 beachten, denn es ist beispielsweise nicht garantiert, daß die Modi > 4 (insbesondere 7 und 8) für alle Dateisysteme vorhanden sind.

Tabelle 3

EINVFN (-32), „Invalid function“
Unbekannte Funktion. Entweder ist die gewünschte GEMDOS-Funktion überhaupt nicht vorhanden oder wird vom betroffenen Filesystem nicht unterstützt

EFILNF (-33), „File not found“
Angesprochene Datei existiert nicht.

EPTHNF (-34), „Path not found“
Pfad nicht gefunden.

ENHNDL (-35), „No more handles“
Keine Dateikennungen mehr verfügbar, weil der Prozeß bereits die Höchstzahl von Dateien geöffnet hat.

EACCDN (-36), „Access denied“
Zugriff nicht erlaubt (beispielsweise beim Versuch, eine schreibgeschützte Datei zu löschen).

EIHNDL (-37), „Invalid handle“
Angegebenes Datei-Handle ist falsch.

ENSMEM (-39), „Insufficient memory“
Nicht genug Speicher frei.

EIMBA (-40), „Invalid memory block address“
Falsche Speicherblockadresse (beispielsweise bei Mfree).

EDRIVE (-46), „Invalid drive specification“
Angegebenes Laufwerk ungültig.

ENSAME (-48), „Not the same drive“, auch EXDEV
Dateien nicht auf gleichem physikalischen Laufwerk (beispielsweise bei Frename oder Flink).

ENMFIL (-49), „No more files“
Keine weiteren Dateien (beim Verzeichnislesen).

ELOCKED (-58), „Record is locked“
Versuch, auf geschützten Bereich einer Datei zuzugreifen oder dort einen eigenen Schutz einzurichten.

ENSLOCK (-59), „No such lock“
Versuch, einen nicht existenten Schutz zu entfernen.

ERANGE (-64), „Range error“, auch ENAMETOOLONG
Bereichsüberschreitung, beispielsweise bei Fseek oder zu langen Datei- bzw. Pfadnamen.

EINTRN (-65), „Internal error“
Interner Fehler im GEMDOS.

EPLFMT (-66), „Invalid program load format“, auch ENOEXEC
Datei für Pexec hat falsches Format (ist nicht ausführbar).

EGSBF (-67), „Memory block growth failure“
Versuch, Speicherblock mit Mshrink zu vergrößern.

ELOOP (-80), „Too many symbolic links“
Endlosschleife mit symbolischen Links.

Dopendir

Mittels Dopendir wird das Verzeichnis name zum Lesen geöffnet. Mit flag legt man dabei fest, ob man im „Kompatibilitätsmodus“ arbeiten will (flag = 1) oder nicht (flag = 0). Wenn ja, arbeiten Dopendir & Co. wie Fsfirst und Fsnext, d.h., File-Namen werden nach Möglichkeit ins 8+3-Schema gequetscht und sind immer in Großbuchstaben gehalten. Im „normalen“ Modus hingegen werden File-Namen immer so geliefert, wie sie das Dateisystem verwaltet (und daher sollte auch nur dieser Modus benutzt werden). Außerdem wird dann bei Dreaddir bzw. Dxreaddir im Filenamen noch ein Index mitgeliefert, der in etwa mit der Unix-Inode-Nummer vergleichbar ist.

Dopendir liefert im Erfolgsfall als Ergebnis ein 32-Bit-Verzeichnis-Handle, das auch negativ sein kann. Zur Unterscheidung von Fehlermeldungen, die ja auch 32-Bit-negativ sind, haben die Handles niemals Oxff im höchstwertigen Byte, was bei Fehlern immer der Fall ist. Diese Regelung wird unter MiNT übrigens deshalb gewählt, weil das Directory-Handle ein Zeiger auf eine interne Verwaltungsstruktur ist, die auch im Alternate-RAM liegen kann. Darauf darf man sich jedoch keinesfalls verlassen, sondern immer nur das beschriebene Entscheidungskriterium verwenden.

Mögliche Fehler sind EP_THNF, wenn es das angegebene Verzeichnis nicht gibt, EACCDN, wenn das Verzeichnis nicht geöffnet werden kann, oder ENSMEM, wenn nicht genügend Speicher für das Anlegen der internen Verwaltungsstruktur vorhanden ist. Bei allen genannten Funktionen bedeutet „mögliche Fehler“ übrigens nicht, daß keine anderen Returncodes denkbar sind. Man sollte also auch auf andere Fehler, insbesondere vom BIOS, reagieren können.

Dreaddir

Mittels dieser Funktion wird der nächste Eintrag aus dem Verzeichnis geliefert, das vorher mit Dopendir geöffnet wurde und das Handle dirhandle hat. Len gibt an, wieviel Platz im Namenspuffer buf vorhanden ist.

In buf wird, wenn das Verzeichnis im normalen Modus geöffnet wurde, ein 4-Byte-Index und direkt dahinter der nullterminierte File-Name geschrieben. Im „Kompatibilitätsmodus“ wird kein Index geliefert. Für den Index gilt folgendes: Haben zwei File-Namen den gleichen Index, bezeichnen sie ein- und dasselbe physikalische File, die Umkehrung gilt jedoch nicht.

Die nötige Länge für len berechnet sich aus der maximalen File-Namenslänge + 5 (4 Bytes Index und der Nullterminator), wenn man im „normalen“ Modus arbeitet. Im „Kompatibilitätsmodus“ werden nur 13 Bytes benötigt (maximal 8 Zeichen Basisname, Punkt, maximale 3 Zeichen Endung, Null als String-Ende).

Mit jedem Aufruf von Dreaddir wird ein weiteres File aus dem jeweiligen Verzeichnis geliefert, bis entweder alle Namen gelesen wurden oder der Auslesezeiger durch einen Drewinddir-Aufruf wieder auf den Verzeichnisanfang gesetzt wurde.

Dreaddir liefert 0L, wenn kein Fehler aufgetreten ist. Bietet len nicht genügend Platz, um den File-Namen (und gegebenenfalls den Index) samt abschließender Null aufzunehmen, erhält man ERANGE geliefert. Sind keine weiteren Files mehr vorhanden, ist der Rückgabewert ENMFIL. Die ersten Versionen des Mac-File-Systems für MagiCMac lieferten für diesen Fall übrigens irrtümlicherweise EPTHNF.

Tabelle 4

typedef struct {
    UWORD mode; /* Filetyp und -modus */
/* Mögliche Filetypen */
#define S_IFMT 0170000 /* Maske zur Isolierung des File-Typs */
#define S_IFCHR 0020000 /* Spezielles BIOS-File (z.B. Device) */
#define S_IFDIR 0040000 /* Verzeichnis */
#define S_IFREG 0100000 /* Normale Datei */
#define S_IFIFO 0120000 /* FIFO (Pipe mit Namen) */
#define S_IMEM 0140000 /* Speicherblock- oder Prozeß-File */
#define S_IFLNK 0160000 /* Symbolischer Link */
/* Spezielle Bits */
#define S_ISUID 04000 /* Set user-ID on execution */
#define S_ISGID 02000 /* Set group-ID on execution */
#define S_ISVTX 01000 /* Sticky bit */
/* Zugriffsrechte */
#define S_IRUSR 0400 /* Eigentümer darf Datei lesen */
#define S_IWUSR 0200 /* Eigentümer darf Datei beschreiben */
#define S_IXUSR 0100 /* Eigentümer darf Datei ausführen */
#define S_IRGRP 0040 /* Gruppenmitglieder dürfen Datei lesen */
#define S_IWGRP 0020 /* Gruppenmitglieder dürfen Datei beschreiben */
#define S_IXGRP 0010 /* Gruppenmitglieder dürfen Datei ausführen */
#define S„IROTH 0004 /* Andere dürfen Datei lesen */
#define S_IWOTH 0002 /* Andere dürfen Datei beschreiben */
#define S_IXOTH 0001 /* Andere dürfen Datei ausführen */
    LONG    index;          /* File-Index, wie bei Dreaddir */
    UWORD   dev;            /* Gerät, auf dem die Datei liegt */
    UWORD   rdev;           /* Tatsächliches Gerät (z.B. bei BIOS-Files) */
    UWORD   nlink;          /* Zahl der „echten" Links auf dieses File */
    UWORD   uid;            /* User-ID des Eigentümers */
    UWORD   gid;            /* Gruppen-ID für dieses File */
    LONG    size;           /* Länge in Bytes */
    LONG    blksize;        /* Größe eines Blocks in Bytes */
    LONG    nblocks;        /* Anzahl von Blocks, die die Datei belegt */
    WORD    intime;         /* Uhrzeit der letzten Modifikation */
    WORD    mdate;          /* Datum der letzten Modifikation */
    WORD    atime;          /* Uhrzeit des letzten Zugriffs auf die Datei */
    WORD    adate;          /* Datum des letzten Zugriffs */
    WORD    ctime;          /* Erzeugungszeit */
    WORD    cdate;          /* Erzeugungsdatum */
    WORD    attr;           /* standard-TOS-Attribute (wie bei Fattrib) */
    WORD    reserved2;      /* bislang reserviert */
    LONG    reserved3[2];   /* dito */
} XATTR;

Die Werte der #define's sind oktal, also nicht mit Dezimal- oder Hexadezimalzahlen verwechseln! Kennzeichen dafür ist übrigens die führende Null. Sämtliche Zeit- und Datumswerte sind im GEMDOS-Format, also wie bei Tgettimebm. Tgetdate. Bei File-Systemen, die atime/adatebm. ctime/ cdate nicht unterstützen, werden diese Angaben auf die Werte von mtime/ mdate gesetzt.

Modus 7 von Dpathconf erlaubt es, im Voraus zu ermitteln, welche Werte in mode und attr Vorkommen können.

Mittels Modus 8 von Dpathconf kann, falls vorhanden, festgestellt werden, welche der Felderder XATTR-Strukturtatsächlich vom File-System unterstützt und nicht nur, wie beispielsweise bei den Zeit- und Datumsfeldern, mit möglichst passenden Werten belegt werden.

Drewinddir

Mit diesem Aufruf kann man den Auslesezeiger des durch dirhandle (von Dopendir) indentifizierten Verzeichnisses auf den Anfang zurücksetzen, das Lesen mit Dreaddir beginnt also wieder beim ersten Eintrag.

Drewinddir liefert 0L, wenn der Aufruf erfolgreich war. EINVFN wird hier auch für den Fall geliefert, daß das betroffene File-System diese Operation nicht unterstützt (es muß also nicht bedeuten, daß der Aufruf vom Kernel überhaupt nicht unterstützt wird).

Dclosedir

Schließt ein mittels Dopendir geöffnetes Verzeichnis wieder. Bei Erfolg erhält man 0L geliefert, sonst EiHNDL (dirhandle war ungültig).

Fxattr

Mit Fxattr ist es möglich, detaillierte Informationen über ein File/Directory zu erhalten. Diese werden in derXATTR-Struktur, auf die xattr zeigt, abgelegt. Die Komponenten der Struktur sind in Tabelle 4 genau erläutert. Der Parameter name gibt dabei den gewünschten File-Namen an; mit fiag legt man fest, ob Fxattr bei symbolischen Links Informationen über den Link-Eintrag selbst (flag = 1) oder über das File, auf das der Link zeigt (flag = 0) liefern soll.

Wenn man sich die XATTR-Struktur genauer ansieht, sieht man, daß hier teilweise File-Attribute zur Verfügung gestellt werden, die man vom normalen TOS-Dateisystem überhaupt nicht kennt. Damit eröffnen sich, z.B. mit dem Minix-File-System, ganz neue Möglichkeiten bei der Datensicherung (beispielsweise Sichern aller Dateien, die in den letzten zwei Tagen angelegt wurden), beim „Sauberhalten“ der Platte(n) (alle Dateien löschen, die seit 6 Monaten nicht mehr benutzt wurden) oder für den Zugriffsschutz (Wem „gehört“ die Datei, was darf er und was dürfen andere damit machen?). ATARI-Software, die von diesen Möglichkeiten Gebrauch macht, ist noch relativ rar (ich zähle die GNU-Fileutilities und andere aus dem Unix-Bereich portierte Programme hier nicht mit), allerdings ist zu erwarten, daß sich die Situation in absehbarer Zeit verbessert.

Dgetcwd

Diese Funktion entspricht weitgehend Dgetpath, bietet jedoch den großen Vorteil, daß man angeben kann, wieviel Platz im Puffer, auf den path zeigt, vorhanden ist. Bei Dgetpath muß man immer darauf hoffen, daß man genügend Platz zur Verfügung gestellt hat, sonst wird über das Ende des Puffers hinaus geschrieben. Dgetcwd hingegen meldet einen Fehler, wenn der aktuelle Pfad des Laufwerks drive (0 = aktuelles Laufwerk, 1 = A, etc.) mehr als size Zeichen lang ist.

Im Erfolgsfall liefert Dgetcwd OL, ist size zu klein, erhält man ERANGE als Rückgabewert, wenn drive kein gültiges GEMDOS-Laufwerk ist, wird EDRIVE zurückgegeben.

Dxreaddir

Diese Funktion stellt eine praktische Verknüpfung von Dreaddir und Fxattr dar, denn sie erledigt beides in einem Durchgang, was eine Beschleunigung beim Directory-Lesen zur Folge hat. Wichtig: Diese Funktion steht nicht automatisch zur Verfügung, wenn Dreaddir vorhanden ist. Es muß also immer separat geprüft werden, ob Dxreaddir benutzt werden kann.

Bei dem internen Aufruf von Fxattr, das seine Informationen in der XATTR-Struktur, auf die xattr zeigt, ablegt, werden keine symbolischen Links verfolgt. Dxreaddir verhält sich also wie ein Fxattr-Aufruf mit flag = 1. Möchte man Link-Verfolgung haben, sollte man prüfen, ob das gerade gelesene File ein Link ist [(xattr->mode & SJFMT) == SJFLNK] und dann gegebenenfalls Fxattr mit flag = 0 für dieses File aufrufen.

Die Größe des Puffers buf, der den zu lesenden Namen aufnehmen soll, wird in len angegeben. Gelesen werden die Files aus dem Verzeichnis, dessen Dopendir-Handle dirhandle ist.

Dxreaddir gibt das Ergebnis des internen Dreaddir-Aufrufs zurück, man kann die möglichen Fehler also dort nachlesen. Der Return-Code des Fxattr-Aufrufs hingegen wird in dem Long, auf den xret zeigt, abgelegt, mögliche Fehler hierfür sollte man bei der Fxattr-Beschreibung nachlesen. Es ist wichtig, stets beide Returncodes zu prüfen, denn es kann durchaus möglich sein, daß das Lesen des Verzeichniseintrags erfolgreich war, das Ermitteln der Attribute jedoch fehlgeschlagen ist.

Dreadlabel

Mit Dreadlabel ist es sehr bequem möglich, File-System-Labels zu ermitteln. Dabei zeigt path auf den Pfad, in dem das Label gesucht werden soll, label zeigt auf den Puffer, in dem es gegebenenfalls abgelegt wird, und length gibt die Größe dieses Puffers an.

Nicht jedes File-System unterstützt Labels, und wenn, dann auch nicht unbedingt in jedem Pfad. Für ein TOS-File-System beispielsweise sind Labels nur für das Wurzelverzeichnis dokumentiert, also sollte man auch nur hier danach suchen. Weitere bekannte File-Systeme mit Label-Unterstützung sind das ISO9660-CD-R0M-Dateisystem oder das File-System der Macs (HFS).

Dreadlabel gibt bei Erfolg OL zurück, mögliche Fehlersind ENAMETOOLONG, wenn das Label mehr als length -1 Zeichen hat, oder EFILNF, wenn kein Label vorhanden ist.

Dwritelabel

Das Gegenstück zu Dreadlabel. Mit dieser Funktion kann das Label label im Pfad path angelegt bzw. geändert werden. Im Erfolgsfall erhält man 0L als Returncode, ENAMETOOLONG wird geliefert, wenn label zu lang für das betroffene File-System ist, EACCDN zeigt an, daß das File-System keine Labels unterstützt.

Und die Praxis?

Die Beschreibung der benötigten GEMDOS-Funktionen ist jetzt abgeschlossen, im zweiten Teil des Artikels geht es dann um die konkrete Anwendung, d.h., wie man beim Lesen eines Verzeichnisses vorgeht und wie man darauf reagiert, wenn gewisse Funktionen nicht vorhanden sind. Außerdem wird dann das bereits erwähnte Beispielprogramm vorgestellt.


Thomas Binder
Aus: ST-Computer 11 / 1995, Seite 44

Links

Copyright-Bestimmungen: siehe Über diese Seite