Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Linux-UNIX-Programmierung von Jürgen Wolf
Das umfassende Handbuch – 2., aktualisierte und erweiterte Auflage 2006
Buch: Linux-UNIX-Programmierung

Linux-UNIX-Programmierung
1216 S., mit CD, 49,90 Euro
Rheinwerk Computing
ISBN 3-89842-749-8
gp Kapitel 2 E/A-Funktionen
  gp 2.1 Elementare E/A-Funktionen
  gp 2.2 Filedeskriptor
    gp 2.2.1 Verwaltung für offene Deskriptoren
  gp 2.3 Funktionen, die den Filedeskriptor verwenden
    gp 2.3.1 Datei öffnen – open()
    gp 2.3.2 Anlegen einer neuen Datei – creat()
    gp 2.3.3 Datei schließen – close()
    gp 2.3.4 Schreiben von Dateien – write()
    gp 2.3.5 Lesen von Dateien – read()
    gp 2.3.6 Schreib-/Lesezeiger positionieren – lseek()
    gp 2.3.7 Duplizieren von Filedeskriptoren – dup() und dup2()
    gp 2.3.8 Ändern oder Abfragen der Eigenschaften eines Filedeskriptors – fcntl()
    gp 2.3.9 Record Locking – Sperren von Dateien einrichten
    gp 2.3.10 Multiplexing E/A – select()
    gp 2.3.11 Unterschiedliche Operationen – ioctl()
    gp 2.3.12 Lesen und Schreiben mehrerer Puffer – writev() und readv()
    gp 2.3.13 Übersicht zu weiteren Funktionen, die den Filedeskriptor verwenden
  gp 2.4 Standard-E/A-Funktionen
    gp 2.4.1 Der FILE-Zeiger
    gp 2.4.2 Öffnen und Schließen von Dateien
    gp 2.4.3 Formatierte Ausgabe
    gp 2.4.4 Formatierte Eingabe
    gp 2.4.5 Binäres Lesen und Schreiben
    gp 2.4.6 Zeichen- und zeilenweise Ein-/Ausgabe
    gp 2.4.7 Status der Ein-/Ausgabe überprüfen
    gp 2.4.8 Stream positionieren
    gp 2.4.9 Puffer kontrollieren
    gp 2.4.10 Datei löschen und umbenennen
    gp 2.4.11 Temporäre Dateien erstellen
  gp 2.5 Mit Verzeichnissen arbeiten
    gp 2.5.1 Ein neues Verzeichnis anlegen – mkdir()
    gp 2.5.2 In ein Verzeichnis wechseln – chdir(), fchdir()
    gp 2.5.3 Ein leeres Verzeichnis löschen – rmdir()
    gp 2.5.4 Format eines Datei-Eintrags in struct dirent
    gp 2.5.5 Einen Verzeichnisstream öffnen – opendir()
    gp 2.5.6 Lesen aus dem DIR-Stream – opendir() und Schließen des DIR-Streams – closedir()
    gp 2.5.7 Positionieren des DIR-Streams
    gp 2.5.8 Komplettes Verzeichnis einlesen – scandir()
    gp 2.5.9 Ganze Verzeichnisbäume durchlaufen – ftw()
  gp 2.6 Fehlerbehandlung
  gp 2.7 Ausblick


Rheinwerk Computing

2.6 Fehlerbehandlung  toptop

Gewöhnlich überprüft man bei vielen Funktionen durch den Rückgabewert, ob diese erfolgreich ausgeführt wurden. Bei den meisten Funktionen der Bibliotheken werden dabei im Falle eines Fehlers -1, ein NULL-Zeiger oder eine symbolische Konstante zurückgegeben. Dieser Rückgabewert sagt Ihnen zwar, dass ein Fehler aufgetreten ist, aber nicht genau welcher Fehler. Dabei sind die Bibliotheksfunktionen sehr viel auskunftsfreudiger, als man annehmen würde. Tritt z. B. bei der Funktion open() ein Fehler auf, gibt es mindestens zehn verschiedene Fehler, die dabei erscheinen können. Um herauszufinden, warum eine Funktion fehlschlug, müssen Sie einen Blick auf den Fehlercode der Variablen errno werfen. Diese Variable ist in der Headerdatei <errno.h> definiert. Außer dass Sie damit die Art des Fehlers ermitteln können, können Sie hiermit sogar theoretisch den Fehler umgehen. Viele Bibliotheksfunktionen können diese Variable (errno) auf einen positiven Wert setzen, wenn ein Funktionsaufruf fehlschlug.


Tipp für eine eigene Fehlerbehandlung   Nur -1 und 0 für Fehler/Erfolg zu verwenden ist häufig eine Verschwendung. Funktionen, die einen Status zurückgeben, geben 1 für Erfolg, 0 für Fehler (z. B. Suchwort nicht gefunden) und negativ für Hard Error aus (errno durch Syscalls, z. B. konnte kein temporärer Speicher für eine Kopie des Suchwortes eingeholt werden). Der Vorteil liegt darin, dass nur eine statt zwei (Rückgabewert und errno) Variablen verbraucht werden.


Auf Linux-Systemen finden Sie die Definitionen aller Fehlercodes in der Headerdatei <errno.h>. Alle dieser Fehlercodes haben neben der (positiven) Nummer einen symbolischen Namen, die mit dem Präfix E beginnen.

Auf alle diese Fehlercodes jetzt einzugehen, wäre wohl etwas zu viel des Guten und ist im Prinzip auch hier nicht sinnvoll. Wenn Sie z. B. für die Funktion open() die Fehlercodes wissen wollen (müssen), sollten Sie die Man-Pages dazu verwenden. Ziemlich am Ende finden Sie hierbei die möglichen Fehlercodes von errno und deren Bedeutungen.

errno wird beim Programmstart standardmäßig auf 0 (ESUCCESS) gesetzt, da es keinen (echten) Fehlercode mit dieser Nummer gibt. Zur Rekonstruktion von Fehlern kann es recht sinnvoll sein, errno nach einem Fehler wieder auf 0 (oder eben auch ESUCCESS) zu setzen oder den Wert in eine lokale Variable zu kopieren. Dies deshalb, weil errno nach jedem misslungenen Systemaufruf von einem neuen Fehlercode überschrieben werden kann.

Hierzu ein einfaches Listing, mit dem Sie überprüfen können, ob eine Datei existiert oder nicht. Wenn Sie z. B. eine Datei öffnen wollen, die nicht existiert, wird der Fehlercode ENOENT zurückgeliefert. Somit könnten Sie praktisch anschließend eine solche Datei erzeugen.

/* filetest.c */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define TRUE  1
#define FALSE 0
#define BOOL int
static int if_exist_file( const char *filename ) {
   FILE *f = fopen( filename, "r" );
   if( errno != ENOENT ) {
         fclose(f);
         return TRUE; /* Datei existiert */
      } 
   else
      return FALSE; /* Datei existiert nicht */
}    
int main(void) {
   BOOL ex = if_exist_file( "testfile" );
   if( ex )
      printf("'testfile' existiert\n");
   else
      printf("'testfile' existiert nicht\n"); 
   return EXIT_SUCCESS;
}

Das Programm bei der Ausführung:

$ gcc -o filetest filtest.c
$ ./filetest
'testfile' existiert nicht
$ cat > testfile
Hallo Welt
STRG+D
$ ./filetest
'testfile' existiert

Eine andere Möglichkeit, den Fehlercode zu verwenden, ohne diesen genauer zu analysieren, wäre die Verwendung der Funktion perror():

void perror (const char *message);

Diese Funktion gibt eine Nachricht auf die Standardfehlerausgabe (stderr) aus, die den Fehler beschreibt. Wenn Sie die Funktion mit einer Nachricht (message) aufrufen – anstatt mit NULL oder einem leeren String –, wird message plus einem Doppelpunkt und Leerzeichen noch vor dem eigentlichen String ausgegeben, der den Fehler beschreibt. perror() fügt der Ausgabe ein Newline-Zeichen und den Doppelpunkt an. Hierzu das vorherige Beispiel, mit der Funktion perror() und ohne errno.

/* filetest2.c */
#include <stdio.h>
#include <stdlib.h>
#define TRUE  1
#define FALSE 0
#define BOOL int
static int if_exist_file( const char *filename ) {
   FILE *f = fopen( filename, "r" );
   if( f != NULL ) {
         fclose(f);
         return TRUE; /* Datei existiert */
      } 
   else
      return FALSE; /* Datei existiert nicht */
}    
int main(void) {
   BOOL ex = if_exist_file( "testfile" );
   if( ex )
      printf("'testfile' existiert\n");
   else
      perror("'testfile'"); 
   return EXIT_SUCCESS;
}

Das Programm bei der Ausführung:

$ gcc -o filetest2 filtest2.c
$ ./filetest2
'testfile' existiert
$ rm testfile
$ ./filetest
'testfile' : No such file oder directory
 << zurück
  
  Zum Rheinwerk-Shop
Neuauflage: Linux-UNIX-Programmierung
Neuauflage:
Linux-UNIX-
Programmierung

bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-
 Programmierung


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
Info





Copyright © Rheinwerk Verlag GmbH 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern