Not logged in. · Lost password · Register
Forum: Grundstudium 2. Semester Informatik (GDI II) SPiC RSS
Juli 2009 2b
Dani #1 -- for 2 months · 8 posts
Show profile · Link to this post
Subject: Juli 2009 2b
Hi,
mal die Aufgabe 2b aus der Klausur vom Juli 2009 durchgearbeitet.
Wär nett wenn jemand meine Lösung mal überprüft.
Vor allem bei dem Warten auf ein Signal vom Kindprozess bin ich mir noch unsicher.
Danke
lg Dani =)

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <sys/types.h>
  6. #include <dirent.h>
  7.  
  8. int main(int argc, char *argv[]) {
  9.  
  10.  
  11.         DIR *dirp;
  12.         struct dirent *entry;
  13.  
  14.         dirp = Opendir(".");//Zeiger dirp kriegt die Adresse vom aktuellen Verzeichnis
  15.         if(dirp == NULL){   // Fehlerabfrage
  16.             perror("opendir");
  17.             exit(EXIT_FAILURE);
  18.         }
  19.  
  20.         while (errno=0, (entry = readdir(dirp))!=NULL){ //entry zeigt auf die nächste Datei in dirp
  21.             pid_t pid;
  22.             pid = fork();   //erzeugt Kind-Prozess und speichert dessen ID in pid
  23.             if (pid == -1) { //Fehlerabfrage
  24.                 perror("fork failed");
  25.                 exit(EXIT_FAILURE);
  26.             }
  27.             else if (pid == 0) {    //im Kindprozess
  28.                 if(entry-->d_name[0] != '.')    // Verzeichnis mit . ausschließen
  29.                 {
  30.                     execl("/usr/bin/backup/", entry-->d_name);  //Backup wird mit name der Datei gestartet               
  31.                 }               
  32.                 exit(); //beenden vom Kindprozess
  33.             }
  34.             else {  //im Vaterprozess
  35.                 sigsuspend(); // warten auf den Kind Prozess
  36.                
  37.             }
  38.      
  39.         }
  40.        
  41.     if (errno != 0){    //bei veränderung von errno Fehlerbahandlung
  42.  
  43.         perror("readdir");
  44.         exit(EXIT_FAILURE);
  45.  
  46.     }
  47.        
  48.     if(closedir(dirp)==-1){// Schließt das Verzeichnis und macht bei Rückgabewert -1Fehlerbehandlung
  49.         perror("closedir");
  50.         exit(EXIT_FAILURE);
  51.  
  52.         }
  53.  
  54. }
This post was edited on 2010-07-26, 09:18 by morty.
Edit reason: Highlighting vom Code aktiviert.
morty (Administrator) #2 -- since Sep 2003 · 730 posts · Location: Erlangen
Show profile · Link to this post
Ne, das funktioniert so noch nicht ganz.  Jag's doch mal durch den Compiler - der findet bestimmt einige Syntaxfehler
Ansosnten:
  • warum machst du erst einen fork und beendest dann das neu erstellte Kind.
  • execl und nochmal anschauen.
  • Das mit dem auf das Kind waren solltest du ja eigentlich in der fish/tqsh gemacht haben.
Dani #3 -- for 2 months · 8 posts
Show profile · Link to this post
Hi,
hab das Programm nochmal optimiert.

warum machst du erst einen fork und beendest dann das neu erstellte Kind
Nach dem Fork() wird bei einem Kind prozess doch die usr/bin/backup/ ausgeführt, oder beim Vater auf den Kind proz. gewartet. Passt dies jetzt soweit??

execl und nochmal anschauen.
excel und jetzt durch NULL terminiert?!

Das mit dem auf das Kind waren solltest du ja eigentlich in der fish/tqsh gemacht haben.
Hab das Skript nochmal durchgelesen und hab das jetzt mit wait und dem status pointer übergeben gemacht. Eine Fehlerabfrage ist nicht nötig, da dem Vater prozess es ja egal ist was mit dem Kind passiert.

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <sys/types.h>
  6. #include <dirent.h>
  7.  
  8. int main(int argc, char *argv[]) {
  9.  
  10.  
  11.         DIR *dirp;
  12.         struct dirent *entry;
  13.  
  14.         dirp = opendir(".");//Zeiger dirp kriegt die Adresse vom aktuellen Verzeichnis
  15.         if(dirp == NULL){   // Fehlerabfrage
  16.             perror("opendir");
  17.             exit(EXIT_FAILURE);
  18.         }
  19.  
  20.         while (errno=0, (entry = readdir(dirp))!=NULL){ //entry zeigt auf die nächste Datei in dirp
  21.             pid_t pid;
  22.             pid = fork();   //erzeugt Kind-Prozess und speichert dessen ID in pid
  23.  
  24.             if (pid == (pid_t) 0)
  25.             {   //im Kindprozess
  26.                 if(entry ->d_name[0] != '.')
  27.                 {   // Verzeichnis mit . ausschließen
  28.                     execl("/usr/bin/backup/", entry->d_name, NULL);     //Backup wird mit name der Datei gestartet
  29.                     perror("execl usr/bin/backup");     
  30.                 }
  31.                 exit(EXIT_FAILURE);
  32.                
  33.             }
  34.             else if (pid != (pid_t) -1)
  35.             {           //im Vaterprozess
  36.                 int status;
  37.                         wait(&status);                                   // warten auf den Kind Prozess
  38.             }
  39.             else
  40.             {                                              //Fehlerarbfrage
  41.                        perror("fork failed");
  42.                        exit(EXIT_FAILURE);     
  43.                     }
  44.      
  45.         }
  46.        
  47.     if (errno != 0){    //bei veränderung von errno Fehlerbahandlung
  48.  
  49.         perror("readdir");
  50.         exit(EXIT_FAILURE);
  51.  
  52.     }
  53.        
  54.     if(closedir(dirp)==-1){// Schließt das Verzeichnis und macht bei Rückgabewert -1Fehlerbehandlung
  55.         perror("closedir");
  56.         exit(EXIT_FAILURE);
  57.  
  58.     }
  59. }

Vielen Dank fürs Anschauen,
lg Dani =)
Raim #4 -- User title: SPiC-Übungsleiter · for 2 months · 2 posts
Show profile · Link to this post
Den Vergleich entry ->d_name[0] == '.' kannst du bereits vor dem fork() durchführen und diese Datei mit einem continue einfach überspringen. Sonst erzeugst du ja unnötigerweise einen Kindprozess.

Bei "/usr/bin/backup" handelt es sich um eine (ausführbare) Datei, der Pfadname wird dabei ohne Schrägstrich am Ende angegeben. execl() nimmt als ersten Parameter den Pfad des auszuführenden Programms, danach Argumente. Als nulltes Argument wird immer nochmal der Name des Programms übergeben: execl("/usr/bin/backup", "/usr/bin/backup", entry->d_name, NULL);

Ganz am Ende fehlt noch ein return 0; für die main().
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please note the verification code from the picture into the text field next to it.
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Go to forum
Unclassified NewsBoard 1.6.4 © 2003-5 by Yves Goergen
Page created in 578.5 ms (372.3 ms) · 63 database queries in 62 ms
Current time: 2010-09-10, 04:08:21 (UTC +02:00)