Thema IPC hilfe brauch

Hector

Active Member
hallo hab ihr nen klein programmcode allerdings werd ich nicht so wirklich schlau raus, was dup/dup2 da machen, sie sind zum kopieren vvon fd's das weiss ich wohl aber ich steig dennoch nicht dahinter was im programm genau sie da machen, hoffe kann mir jemand erklären

Code:
int main ( ) {
   pid_ t pid ;
   int fd [2] , fdf ;
   pid = fork( );

   if ( pid == 0 ) {
       pipe(fd) ;
       pid = fork( ) ;
      
     i f ( pid == 0 ) {
         close(fd[0]) ;
         dup2(fd[1],STDOUT_FILENO);
         close(fd[1]);
         fdf = open ( "x" , O_RDONLY );
         dup2 (fdf ,STDIN_FILENO ) ;
         close(fdf) ;
         execlp("cat" , "cat" , NULL) ;
     }


  close(fd[1]) ;
  dup2(fd[0],STDIN_FILENO ) ;
  close(fd[0]) ;
  execlp("wc" , "wc" , "-w",NULL) ;
}
wait(NULL);
}
 
in "man dup" steht da etwas:
#include <unistd.h>

int
dup(int oldd);

int
dup2(int oldd, int newd);

DESCRIPTION
The dup() system call duplicates an existing object descriptor and
returns its value to the calling process (newd = dup(oldd)). The argu-
ment oldd is a small non-negative integer index in the per-process
descriptor table. The value must be less than the size of the table,
which is returned by getdtablesize(2). The new descriptor returned by
the call is the lowest numbered descriptor currently not in use by the
process.

The object referenced by the descriptor does not distinguish between oldd
and newd in any way. Thus if newd and oldd are duplicate references to
an open file, read(2), write(2) and lseek(2) calls all move a single
pointer into the file, and append mode, non-blocking I/O and asynchronous
I/O options are shared between the references. If a separate pointer
into the file is desired, a different object reference to the file must
be obtained by issuing an additional open(2) system call. The close-on-
exec flag on the new file descriptor is unset.

In dup2(), the value of the new descriptor newd is specified. If this
descriptor is already in use and oldd != newd, the descriptor is first
deallocated as if the close(2) system call had been used. If oldd is not
a valid descriptor, then newd is not closed. If oldd == newd and oldd is
a valid descriptor, then dup2() is successful, and does nothing.
 
Vielleicht hilft es dir, wenn du die Shellsyntax betrachtest, die in etwa das gleiche macht:

Code:
$ cat < x | wc -w

Schrittweise Analyse:

  • Hauptprozess initialisiert die Variablen
  • Hauptprozess forkt sich selbst und wartet anschließend
  • 1. Fork erstellt eine Pipe
  • 1. Fork forkt sich ein weiteres Mal
  • 2. Fork setzt den Dateideskriptor für Datei x als Standardeingabe und nutzt die Eingabe der Pipe als Standardausgabe
  • 2. Fork führt cat aus (mit angepasster Ein/Ausgabe) "cat < x |"
  • 1. Fork setzt die Ausgabe der Pipe als Standardeingabe
  • 1. Fork führt wc -w aus (mit angepasster Eingabe) "| wc -w"
 
danke,

glaub weiss jetzt was der Haken war, die stdout/in muessen immer erst auf den fd gesetzt werden oder? also deswegen dup2(fd[1],stdout...); ?
weil ich hatte es bis her immer so verstanden, dass auf var[0], var[1] und var[3] in,out und err vorbelegt sind ;)
 
Ja, stdout und stdin müssen umbelegt werden, da Dateideskriptoren (und da zählen sie ja zu) vom fork() mit an den neuen Prozess übergeben werden. Normalerweise hängen sie ja mit deinem Terminal zusammen (Ein/Ausgabe), daher müssen die erstmal auf die Pipe gelegt werden.

Und wie in der Manualseite für pipe() nachgelesen werden kann, werden dort zwei Dateideskriptoren in den übergebenen Array geschrieben: lesen und schreiben.
 
Zurück
Oben