• Diese Seite verwendet Cookies. Indem du diese Website weiterhin nutzt, erklärst du dich mit der Verwendung von Cookies einverstanden. Erfahre mehr

Verständnisproblem mit open()

Tulkas

Well-Known Member
Themenstarter #1
Hi,
ich hab ein kleines C-Programm geschrieben, was eine Textdatei auslesen soll. Leider nimmt es immer STDIN als Quelle, obwohl mir open() keinen Fehler meldet. Wenn ich STDIN schliesse, dann klappt das Programm wunschgemäß. Nur dachte ich, open() nähme den nächst freien Filedeskriptor. Warum muss ich also STDIN erst schliessen bevors klappt? Ich schicke mal die entsprechenden Teile des Quelltextes mit.

Danke && Gruß

Tulkas


Code:
void readsig(void){
   
   int sigfd;
   ssize_t n;
   
   char* home = getenv("HOME");
   strcat(home, SIGNAME);
   close(STDIN_FILENO);/* Dann gehts....*/


   if ((sigfd = open(home, O_RDONLY) < 0)){
      perror("Fehler beim Öffnen der Signatur");
      exit(2);
#ifdef DEBUG
   }else{
      printf("Erfolg beim Öffnen: %s\n", home);
      printf("sigfd: %d\n",sigfd);
#endif
   }

   while((n = read(sigfd, signatur, sizeof(signatur))) > 0){
      if( (write(STDOUT_FILENO, signatur, n )) != n){
               perror("Fehler beim Schreiben");
               exit(2);
      }
   }
   close(sigfd);
}
 

CW

Netswimmer
#2
Original geschrieben von Tulkas
Hi,
ich hab ein kleines C-Programm geschrieben, was eine Textdatei auslesen soll. Leider nimmt es immer STDIN als Quelle, obwohl mir open() keinen Fehler meldet. Wenn ich STDIN schliesse, dann klappt das Programm wunschgemäß. Nur dachte ich, open() nähme den nächst freien Filedeskriptor. Warum muss ich also STDIN erst schliessen bevors klappt? Ich schicke mal die entsprechenden Teile des Quelltextes mit.

Danke && Gruß

Tulkas


Code:
void readsig(void){
   
   int sigfd;
   ssize_t n;
   
   char* home = getenv("HOME");
   strcat(home, SIGNAME);
   close(STDIN_FILENO);/* Dann gehts....*/


   if ((sigfd = open(home, O_RDONLY) < 0)){
      perror("Fehler beim Öffnen der Signatur");
      exit(2);
#ifdef DEBUG
   }else{
      printf("Erfolg beim Öffnen: %s\n", home);
      printf("sigfd: %d\n",sigfd);
#endif
   }

   while((n = read(sigfd, signatur, sizeof(signatur))) > 0){
      if( (write(STDOUT_FILENO, signatur, n )) != n){
               perror("Fehler beim Schreiben");
               exit(2);
      }
   }
   close(sigfd);
}
Wie wäre es mit fopen()?

Du willst doch eine datei aufmachen, oder? ;)

Grüße

CW
 
#3
Das ist einfach nur Operator-Präzedenz, du weisst an sigfd den Wert von open(..) < 0 zu. Was du hast ist:
Code:
sigfd = (open(home, O_RDONLY) < 0)
und was du meinst ist
Code:
(sigfd = open(home, O_RDONLY)) < 0
Merke: nicht mit Klammern sparen oder jeden Abend die Operatorpräzedenzen aus K&R studieren :)
 

Tulkas

Well-Known Member
Themenstarter #4
@CW Is klar.... ;)

Aber eigentlich wollte ich gerne wissen, warum es mit open() nicht geht. Ich kann einfach nicht erkennen, was an meiner Version falsch ist. Ich hab schon einige Veränderungen getätigt. Ich hab z.B. den Pfad zu der Datei fest angegeben. Aber immer muss ich vorher STDIN_FILENO schliessen, damit es klappt. Vorher geht es einfach nicht.

Gruß
Tulkas

[edit]
@current
Vielen Dank. Nun kann ich Nachts wieder ruhig schlafen. War mir klar, dass es so was "simples" war. ;) Aber ich werde in Zukunft lieber mehr Klammern setzen als jeden Abend die Operatorenpriorietäten zu lernen ;)

THX
Tulkas
 
Zuletzt bearbeitet:
#5
Na ja, wenn das open funktioniert, ist der Vergleich "Rückgabewert von open() kleiner 0" falsch, also ist sigfd=0. Der spätere read() liest also vom Filedescriptor 0, und das ist stdin.

Wenn du stdin vorher schliesst, gibt das open() den nächsten freien fd, also 0 zurück. Und "per Zufall" liest du dann von der Datei, da dann filedescriptor der Datei und sigfd übereinstimmen...
 

Tulkas

Well-Known Member
Themenstarter #6
@current
Jupp, als du auf die Klammern aufmerksam gemacht hattest, war mir klar, warum es nicht ging. Meine Frage bezog sich auf CWs antwort, und da wir beide fast gleichzeitig gepostet hatten kannte ich die Lösung meines Problems noch nicht...

Aber trotzdem nochmals danke :)

Gruß
Tulkas