1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

fork() und pipes

    • Frage
  • NonSense
  • 28. Mai 2007 um 14:17
  • Unerledigt
  • NonSense
    4
    NonSense
    Mitglied
    Punkte
    145
    Beiträge
    20
    • 28. Mai 2007 um 14:17
    • #1

    Hallo, ich versuche 2 Kindprozesse von dem urspünglichen Prozess zu erzeugen die folgende Funktionalität haben:
    Der Vater liest zeichenweise von stdin und schreibt die eingelesene Zeichen in der ersten Pipe. Das erste Kind liest von dieser Pipe die Zeichen aus und gibt diese weiter an die zweite Pipe. Das zweite Kind liest diese Zeichen von der zeiten Pipe und gibt diese auf stdout aus.

    Ich bin nicht sicher ob ich das zweite fork() an der richtigen Stelle habe, bzw. das zweite wait().

    Kompilierbar ist es problemlos aber nach der ausführung werden die zeichen nur gelesen aber nichts wird ausgegeben. Den Programm kann man auch nicht mit strg+D terminieren.

    Hat jemand eine Idee was ich da falsch mache?

    Source:

    C
    /* Program:    mygzip
     * Author:    Filip Hianik 0426173
     * Date:    27.05.2007
     * Purpose:    Der Programm liest von stdin Files die mit gzip zu komprimieren sind und komprimiert diese in einem File (falls dessen Name als Argument übergeben wird) oder in stdout.
     * Usage:    mygzip [file]
     * Beispiel:    3b_mygzip
     */
    
    
    /*
     * ******************************************************************************************* defines ****
     */
    
    
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <limits.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    
    /*
     * ******************************************************************************************** globals ***
     */
    
    
    const char *szCommand = "<not yet set>";                        /* command name */
    static int pPipe[2];
    static int pPipe2[2];
    static pid_t pid, pid2;
    static FILE *pStream = (FILE *) 0;
    static FILE *pStream2 = (FILE *) 0;
    FILE *fdopen (int filedes, const char *mode);
    
    
    /*
     * ***************************************************************************************** prototypes ***
     */
    
    
    void BailOut (const char *szMessage);                        /* forward declaration */
    
    
    /*
     * ****************************************************************************************** functions ***
     */
    
    
    void PrintError (const char *szMessage)
    {
       if (errno != 0)
       {
          (void) fprintf (stderr, "%s: %s - %s\n", szCommand, szMessage, strerror (errno));
       }
       else
       {
          (void) fprintf (stderr, "%s: %s\n", szCommand, szMessage);
       }
    }
    
    
    void FreeResources (void)
    {
       if (pStream != (FILE *) 0)
       {
          if (fclose ((FILE *) pStream) == EOF)
          {
             pStream = (FILE *) 0;
             BailOut ("Can not close pipe stream!");
          }
          pStream = (FILE *) 0;                                /* pipe no longer open */
       }
    
    
       if (pStream2 != (FILE *) 0)
       {
          if (fclose ((FILE *) pStream2) == EOF)
          {
             pStream2 = (FILE *) 0;
             BailOut ("Can not close pipe stream 2");
          }
          pStream2 = (FILE *) 0;
       }
    }
    
    
    void BailOut (const char *szMessage)
    {
       if (szMessage != (const char *) 0)                        /* print error message? */
       {
          PrintError (szMessage);
       }
       FreeResources ();
       exit (EXIT_FAILURE);
    }
    
    
    void AllocateResources (void)
    {
       if (pipe (pPipe) == -1)
       {
          BailOut ("Can not create pipe!");
       }
    
    
       if (pipe (pPipe2) == -1)
       {
          BailOut ("Can not create pipe 2!");
       }
    }
    
    
    void Usage (void)
    {
       (void) fprintf (stderr, "USAGE: %s [file]\n", szCommand);
       BailOut ((const char *) 0);
    }
    
    
    void FatherProcess (void)
    {
       int c;
    
    
       if (close (pPipe[0]) == -1)
       {
          BailOut ("Error closing the read descriptor!");
       }
    
       if ((pStream = fdopen (pPipe[1], "w")) == (FILE *) NULL)
       {
          BailOut ("Can not open pipe for writing");
       }
    
       while ((c = fgetc (stdin)) != EOF)
       {
          fputc (c, pStream);
       }
    
    
       FreeResources ();
    }
    
    
    void ChildProcess (void)
    {
       int c;
    
    
       if (close (pPipe[1]) == -1)
       {
          BailOut ("Error closing the write descriptor!");
       }
    
    
       if ((pStream = fdopen (pPipe[0], "r")) == (FILE *) NULL)
       {
          BailOut ("Can not open pipe for reading!");
       }
    
    
       if (close (pPipe2[0]) == -1)
       {
          BailOut ("Error closing the write descriptor 2!");
       }
    
    
       if ((pStream2 = fdopen (pPipe2[1], "w")) == (FILE *) NULL)
       {
          BailOut ("Can not open pipe2 for writing!");
       }
    
    
       while ((c = fgetc (pStream)) != EOF)
       {
          fputc (c, pStream2);
       }
    
    
       if (ferror (pStream))
       {
          BailOut ("Can not read from pipe!");
       }
    
    
       FreeResources ();
    }
    
    
    void ChildProcess2 (void)
    {
       int c;
       if (close (pPipe2[1]) == -1)
       {
          BailOut ("Error closing the write descriptor!");
       }
    
    
       if ((pStream2 = fdopen (pPipe2[0], "r")) == (FILE *) NULL)
       {
          BailOut ("Can not open pipe2 for reading!");
       }
    
    
       while ((c = fgetc (pStream2)) != EOF)
       {
          fputc (c, stdout);
       }
    
    
       if (ferror (pStream2))
       {
          BailOut ("Can not read from pipe2!");
       }
    
    
       FreeResources ();
    }
    
    
    int main (int argc, char **argv)
    {
       pid_t wpid, wpid2;
       int status, status2;
    
    
       szCommand = argv[0];
    
    
       if (argc > 2)
       {
          Usage();
       }
    
    
       AllocateResources ();
    
    
       switch (pid = fork ())
       {
          case -1:
             BailOut ("Fork failed!");
          break;
    
    
          case 0:
             ChildProcess ();
          break;
    
    
          default:
    
    
             switch (pid2 = fork ())
             {
                case -1:
                   BailOut ("Fork2 failed!");
                break;
    
    
                case 0:
                   ChildProcess2 ();
                break;
    
    
                default:
                   FatherProcess ();               
                break;
             }
    
             while ((wpid = wait (&status)) != pid)
             {
                if (wpid != -1)
                {
                   continue;
                }
                if (errno == EINTR)
                {
                   continue;
                }
                BailOut ("Error waiting for child process 1!");
             }
    
    
             while ((wpid2 = wait (&status2)) != pid2)
             {
                if (wpid2 != -1)
                {
                  continue;
                }
    
    
                if (errno == EINTR)
                {
                  continue;
                }
    
    
                BailOut ("Error waiting for child process 2!");
             }
    
    
    
    
          break;      
       }
       exit (EXIT_SUCCESS);
    }
    Alles anzeigen

    danke für jede Hilfe.
    mfg NonSense

    Experience is what you get when you are expecting something else.
    -Ivor Horton-

  • Rumpl
    2
    Rumpl
    Mitglied
    Punkte
    15
    Beiträge
    3
    • 4. Juni 2007 um 15:45
    • #2

    Hmm, ich hab das Beispiel jetzt nicht so ganz genau durchgesehen, aber vielleicht liegts daran, dass du in den Prozessen die bestimmte Pipes nicht brauchen, diese nicht schließt? Probier mal, beispielsweise im Fatherprocess auch pipe2 zu schließen. Ist jetzt aber nur eine Vermutung. Hatte in Sysprog ein ähnliches Bsp, wenn ichs noch find, guck ich mal nach was ich damals geschrieben hab, sah jedenfalls ungefähr so aus.

  • xxsuddendeathxx
    2
    xxsuddendeathxx
    Mitglied
    Punkte
    30
    Beiträge
    5
    • 12. Juni 2007 um 11:35
    • #3
    Zitat von NonSense

    Kompilierbar ist es problemlos aber nach der ausführung werden die zeichen nur gelesen aber nichts wird ausgegeben. Den Programm kann man auch nicht mit strg+D terminieren.


    Hi!

    Also ich hätt mal gesagt, dass das Problem wahrscheinlich an den Streams liegen wird, die gepuffert werden - und somit nicht direkt beim Aufruf von fputc geschrieben werden.

    Mach nach jedem Schreibvorgang ein fflush(stream) und es sollte funktionieren!
    Aja - im Fatherprocess fehlt die Fehlerprüfung beim fputc!

    lg
    Martin

    In zweifenhaften Fällen entscheide man sich für das Richtige!

  • NonSense
    4
    NonSense
    Mitglied
    Punkte
    145
    Beiträge
    20
    • 12. Juni 2007 um 11:40
    • #4

    Danke es hat sich schon erledigt.

    Experience is what you get when you are expecting something else.
    -Ivor Horton-

  • Maximilian Rupp 27. Dezember 2024 um 12:05

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Benutzer online in diesem Thema

  • 1 Besucher

Rechtliches

Impressum

Datenschutzerklärung