Anzeige:
Ergebnis 1 bis 7 von 7

Thema: read() nach popen() schreibt "GNU" in den Puffer

  1. #1
    Registrierter Benutzer
    Registriert seit
    04.01.2006
    Beiträge
    25

    read() nach popen() schreibt "GNU" in den Puffer

    Ahoi!

    Ich würde gern popen() einsetzen, nach dem darauf folgenden read() steht aber nur "GNU" im Puffer.
    So sieht mein Programm aus:

    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    
    int main( int argc, char *argv[] )
    {
    
      FILE *fd;
      char buffer[1024];
    
      fd = popen("ls", "r");
    
      read( (int) fd, buffer, sizeof(buffer) );
    
    
      printf("%s", buffer ); /* gibt "GNU" aus */
    
      exit(0);
    
    }
    Warum tut es das?

  2. #2
    Registrierter Benutzer Avatar von jeebee
    Registriert seit
    01.01.2005
    Ort
    Bern || Zürich
    Beiträge
    540
    Dir ist bewusst, dass ein FILE* nicht ein Filedeskriptor ist, sondern ein File-Handle den du z.B. für fread() und co. brauchst. Wogegen read() einen FD haben will (dies ist einfach eine Zahl die beim Öffnen einer Datei vom Kernel vergeben wird...)

    Code:
    #include <stdio.h>
    /* unistd.h brauchst du gar nicht ... */
    #include <stdlib.h>
    
    
    int main( int argc, char *argv[] )
    {
    
      FILE *fd;
      /* Buffer mit 0 initialisieren, dann kommt nicht am Schluss noch Müll
       * wenn der Buffer zu gross ist.
       */
      char buffer[1024] = {0};
    
      fd = popen("ls", "r");
    
      /* fread anstatt read
       * Argument 1: Zielbuffer
       * Argument 2: Blockgrösse zum Lesen
       * Argument 3: Anzahl Blöcke zum Lesen
       * Argument 4: FILE* Struktur von welcher gelesen wird
       */
      fread(buffer, 512, sizeof(buffer)/512, fd );
    
    
      printf("%s", buffer ); /* gibt "GNU" aus */
    
      /* wenn schon exit() -- return 0 würde auch reichen --
       * dann doch auch gerade mit den Standard-Exit-Werten EXIT_SUCCESS
       * und EXIT_FAILURE, dann funktionierts nämlich auch auf
       * einem System das nicht 0 als OK beim Rückgabewert hat wie
       * erwartet
       */
      exit(EXIT_SUCCESS);
    
    }
    Ist ganz kurz getestet. Wenn allerdings die Ausgabe von ls länger als dein Buffer ist wird einfach abgeschnitten.
    my very own 128 bit integer
    C4 D3 B8 A8 9E A0 C6 EC 7D EC A8 15 28 D1 92 58
    more information

  3. #3
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Einiges wurde schon gesagt, noch zwei Sachen:

    Ich würde z.B. bei ls jetzt eher ein
    Code:
      fgets(buffer, sizeof(buffer), fd);
    verwenden, das liest dir genau eine Zeile aufs Mal aus der Datei.

    Ausserdem würde ich, sobald ich das Zeugs nicht mehr benötige, die Pipe wie sichs gehört schliessen:
    Code:
      pclose(fd);
    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  4. #4
    Registrierter Benutzer
    Registriert seit
    04.01.2006
    Beiträge
    25
    Das leuchtet ein. Ich danke euch beiden!

  5. #5
    Registrierter Benutzer Avatar von jeebee
    Registriert seit
    01.01.2005
    Ort
    Bern || Zürich
    Beiträge
    540
    @peschmae:
    1) stimmt, dann hast du immer alles was ls ausgibt.
    2) das pclose wollte ich eigentlich noch hinzufügen, ging dann aber vergessen.
    my very own 128 bit integer
    C4 D3 B8 A8 9E A0 C6 EC 7D EC A8 15 28 D1 92 58
    more information

  6. #6
    Registrierter Benutzer
    Registriert seit
    20.03.2006
    Beiträge
    54
    Zitat Zitat von peschmae Beitrag anzeigen
    Einiges wurde schon gesagt, noch zwei Sachen:

    Ich würde z.B. bei ls jetzt eher ein
    Code:
      fgets(buffer, sizeof(buffer), fd);
    verwenden, das liest dir genau eine Zeile aufs Mal aus der Datei.
    Bei meinen Projekten die auf mehreren Plattformen (Linux, Windows, Amiga) laufen, gab es mit "fgets" Probleme beim Linefeed.

    Bei der Windowsversion wurde nur "CR LF" als Linefeed erkannt.
    Dateien die z. B. unter Linux erstellt wurden und nur LF am Ende hatten
    wurden nicht richtig gelesen.

    Spätestens bei Projekten die auf mehreren OS laufen sollen, geht mit
    fgets nichts mehr!
    "... der Großteil hier hat einfach keine Lust, jede Pore einer Brotscheibe mit Butter auszuschmieren." - Susu

  7. #7
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Naja, es geht um den Output von einem ls, das hat natürlich einen Linefeed wie alles andere auf der Plattform auch - und gets erkennt den auch gleich

    Wenn man Plattformen mixerlt wirds natürlich übel.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •