Advertisement
Guest User

interpretiere.c

a guest
Jun 12th, 2014
346
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.89 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/wait.h>
  8. #include <fcntl.h>
  9. #include <errno.h>
  10.  
  11.  
  12. #include "utils.h"
  13. #include "listen.h"
  14. #include "wortspeicher.h"
  15. #include "kommandos.h"
  16. #include "frontend.h"
  17. #include "parser.h"
  18. #include "variablen.h"
  19.  
  20. int interpretiere(Kommando k, int forkexec);
  21. int interpretiere_einfach(Kommando k, int forkexec);
  22. int getStatus();
  23.  
  24. Liste procTable;
  25.  
  26. void do_execvp(int argc, char **args){
  27.   execvp(*args, args);
  28.   perror("exec-Fehler");
  29.   fprintf(stderr, "bei Aufruf von \"%s\"\n", *args);
  30.   exit(1);
  31. }
  32.  
  33. int interpretiere_pipeline(Kommando k){
  34.   /* NOT IMPLEMENTED */
  35.  
  36.     int fd1[] = { -1, -1 };
  37.     int fd2[] = { -1, -1 };
  38.     int i = 0;
  39.     int status = 0;
  40.     int pid = -2;
  41.     Liste l = k->u.sequenz.liste;
  42.     Kommando ko;
  43.     Pstatus pDesk;
  44.     int laenge = k->u.sequenz.laenge;
  45.  
  46.     printf("Länge: %i!\n", laenge);
  47.  
  48.     for (i = 0; i < laenge; i++) {
  49.         ko = (Kommando) listeKopf(l);
  50.         fd2[0] = fd1[0];
  51.         fd2[1] = fd1[1];
  52.  
  53.         if (i > 0) {
  54.             close(fd2[1]);
  55.         }
  56.  
  57.         if (pipe(fd1) < 0) {
  58.             perror("Pipe-Fehler");
  59.             exit(1);
  60.         }
  61.         pid = fork();
  62.  
  63.         switch (pid) {
  64.         case -1:
  65.             perror("Fehler bei fork");
  66.             return (-1);
  67.         case 0:
  68.             /*1. Prozess? Dann den Lesestrom von FD2 nicht umlegen.:*/
  69.             if (fd2[0] != -1) {
  70.                 dup2(fd2[0], STDIN_FILENO);
  71.             }
  72.  
  73.             /*Letzter Prozess? Dann den Schreibstrom von FD1 nicht umlegen:*/
  74.             if (i < laenge - 1) {
  75.                 dup2(fd1[1], STDOUT_FILENO);
  76.             }
  77.             interpretiere_einfach(ko, 0);
  78.             exit(1);
  79.             break;
  80.         default:
  81.             /*pDesk = erzeugeProzess (pid, k->u.einfach.worte[0], "RUNNING");
  82.             procTable = listeAnfuegen(procTable, &pDesk); */
  83.             pDesk = erzeugeProzess( pid, "test", "RUNNING");
  84.             procTable = listeAnfuegen(procTable, &pDesk);
  85.  
  86.             sleep(1);
  87.             break;
  88.         }
  89.         l = listeRest(l);
  90.     }
  91.     return status;
  92. }
  93.  
  94. int umlenkungen(Kommando k){
  95.     Umlenkung *u;       /* Objekt vom Typ Umlenkung (kommandos.h) */
  96.     Modus modus;        /* Objekt vom Typ Modus (kommandos.h) */
  97.     Liste neueListe;    /* Objekt vom Typ Liste (listen.h) */
  98.     FILE *f;            /* File zum erstellen einer eventuellen Datei */   
  99.     /*int fd;           Filedescriptor zum Überprüfen der Datei*/
  100.     char *pfad;         /* Pfad und Dateiname der Datei */
  101.    
  102.     /**
  103.     typedef     struct {
  104.         int         filedeskriptor;  beliebige Deskriptoren können umgelenkt werden
  105.         Modus       modus;           Umlenkungsart
  106.         char *      pfad;            Datei von der / in die umgelenkt wird
  107.     } Umlenkung;
  108.     * */
  109.     /*
  110.      *  Wenn Umlenkungen vorhanden sind, hole die Umleitungen aus der Liste
  111.      *  und wandle sie um in ein struct Umleitungen
  112.      **/
  113.     if(k->u.einfach.umlenkungen != NULL){
  114.         fprintf(stdout, "Es sind Umleitungen vorhanden\n");
  115.         neueListe = k->u.einfach.umlenkungen;
  116.        
  117.         u = (Umlenkung *) neueListe->kopf;
  118.         modus = u->modus;   /* Modi: read, write, append*/
  119.         pfad = u->pfad;     /* Pfad zur Datei*/
  120.    
  121.    
  122.         /* Modi definiert in kommandos.h */
  123.         switch(modus) {
  124.         case READ: /* stellt die Standarteingabe auf die angegeben Datei 'pfad'*/
  125.             fprintf(stdout, "Modus Read\n");
  126.             if(freopen(pfad, "r", stdin) == NULL){
  127.                 fprintf(stderr, "Fehler beim Lesen der Datei. \nErrno: %d \n", errno);
  128.                 return 1;
  129.             }
  130.             break;
  131.            
  132.         case WRITE: /* Standartausgabe wird auf die Datei Pfad gestellt. Existiert die Datei noch nicht, wird sie erstellt. */
  133.             fprintf(stdout, "Modus Write\n");
  134.             /*fd = open(pfad, O_RDWR | O_CREAT | O_TRUNC, S_IWGRP | S_IRGRP | S_IXGRP);
  135.                 if(fd == -1) {
  136.                     fprintf(stdout, "Fehler beim Erstellen der Datei.\n Errno: %d", errno);
  137.                 exit(1);
  138.             }*/
  139.             if ((f = fopen(pfad, "w+")) == NULL) {
  140.                 fprintf(stderr, "Fehler beim Erstellen der Datei. \nErrno: %d \n", errno);
  141.                 return 1;
  142.             }
  143.             if(freopen(pfad, "w", stdout) == NULL){
  144.                 fprintf(stderr, "Fehler beim Erstellen der Datei. \nErrno: %d \n", errno);
  145.                 return 1;
  146.             }
  147.             break;
  148.            
  149.         case APPEND:
  150.             fprintf(stdout, "Modus Append\n");
  151.             /*fd = open(pfad, O_RDWR | O_CREAT | O_APPEND, S_IWGRP | S_IRGRP | S_IXGRP | S_IWUSR | S_IRUSR | S_IXUSR | S_IWOTH | S_IROTH | S_IXOTH);
  152.                 if(fd == -1) {
  153.                     fprintf(stdout, "Fehler beim Erstellen der Datei");
  154.                 exit(1);
  155.             }*/
  156.             if ((f = fopen(pfad, "a+")) == NULL) {
  157.                 fprintf(stderr, "Fehler beim Erstellen der Datei. \nErrno: %d \n", errno);
  158.                 return 1;
  159.             }
  160.             if(freopen(pfad, "a", stdout) == NULL){
  161.                 fprintf(stderr, "Fehler beim Erstellen der Datei. \nErrno: %d \n", errno);
  162.                 return 1;
  163.             }
  164.             break;
  165.            
  166.         default:
  167.             fprintf(stderr, "Modus default.\n No Options defined for default.\n");
  168.             fprintf(stdout, "Modus default nicht verfuegbar.\n");
  169.             break;
  170.         }
  171.      
  172.     }
  173.   return 0;
  174. }
  175.  
  176. int aufruf(Kommando k, int forkexec){
  177.    
  178.     Pstatus p;
  179.     Pstatus *test;
  180.     int kind_status, i;
  181.  
  182.   /* Programmaufruf im aktuellen Prozess (forkexec==0)
  183.      oder Subprozess (forkexec==1)
  184.   */
  185.      
  186.   if(forkexec){
  187.     int pid=fork();
  188.  
  189.     switch (pid){
  190.     case -1:
  191.       perror("Fehler bei fork");
  192.       return(-1);
  193.     case 0:
  194.       if(umlenkungen(k))
  195.     exit(1);
  196.       do_execvp(k->u.einfach.wortanzahl, k->u.einfach.worte);
  197.       abbruch("interner Fehler 001"); /* sollte nie ausgeführt werden */
  198.     default:
  199.       if(k->endeabwarten) {
  200.           /* So einfach geht das hier nicht! */
  201.            
  202.           /* schreibt die PID, den Namen und den Status in die Tabelle */  
  203.           p = erzeugeProzess (pid, k->u.einfach.worte[0], "RUNNING"); /*k->u.einfach.worte[0] */
  204.           /* Debug: print
  205.           printf("\npid: %d\tstatus: %s\n", p.pid, p.status);
  206.           */
  207.           i = listeLaenge(procTable);
  208.           procTable = listeAnfuegen(procTable, &p);
  209.           if(listeLaenge(procTable) <= i) {
  210.             fprintf(stderr, "Fehler beim Schreiben in die Liste!");
  211.           }
  212.          
  213.           /* Debug printf: Bis hierhin wird alles ordentlich in die Liste geschrieben!
  214.           test = listeKopf(procTable);
  215.           printf("\npid: %d\tstatus: %s\n", test->pid, test->status);
  216.           */
  217.          
  218.           waitpid(pid, &kind_status, 0);
  219.             if(WIFEXITED(kind_status)){
  220.                 printf("Kind mit der PID %d wurde beendet\n",pid);
  221.             }
  222.             else if(WIFSIGNALED(kind_status)){
  223.                 printf("Kind mit der PID %d wurde durch Signal abgebrochen. Signalnummer: %d\n",pid, WTERMSIG(kind_status));
  224.             }
  225.       }
  226.       else {
  227.         fprintf(stderr, "Programm nicht beendet\n");
  228.         fprintf(stdout, "PID: %i\n", pid);
  229.       }  
  230.       return 0;
  231.     }
  232.   }
  233.  
  234.   /* nur exec, kein fork */
  235.   if(umlenkungen(k))
  236.     exit(1);
  237.   do_execvp(k->u.einfach.wortanzahl, k->u.einfach.worte);
  238.   abbruch("interner Fehler 001"); /* sollte nie ausgeführt werden */
  239.   exit(1);
  240. }
  241.  
  242.  
  243. int interpretiere_einfach(Kommando k, int forkexec){   
  244.  
  245.   char **worte = k->u.einfach.worte;
  246.   int anzahl=k->u.einfach.wortanzahl;
  247.             /*pDesk = erzeugeProzess( pid, ko, "RUNNING");
  248.             procTable = listeAnfuegen(procTable, &pDesk);*/
  249.  
  250.   if (strcmp(worte[0], "exit")==0) {
  251.     switch(anzahl){
  252.     case 1:
  253.       exit(0);
  254.     case 2:
  255.       exit(atoi(worte[1]));
  256.       printf("Dies ist ein test");
  257.     default:
  258.       fputs( "Aufruf: exit [ ZAHL ]\n", stderr);
  259.       return -1;
  260.     }
  261.   }
  262.  
  263.   if (strcmp(worte[0], "cd")==0) {
  264.     switch(anzahl){
  265.     case 1:
  266.       return chdir(getenv("HOME"));
  267.     case 2:
  268.       return chdir(worte[1]);
  269.     default:
  270.       fputs("Aufruf: cd [ PFAD ]\n", stderr);
  271.       return -1;
  272.     }
  273.   }
  274.  
  275.   /* gibt den Status der Subprozesse zurück */
  276.   if (strcmp(worte[0], "status")==0){
  277.      
  278.       /* NYI */
  279.     getStat(procTable);
  280.    
  281.   }
  282.  
  283.   return aufruf(k, forkexec);
  284. }
  285.  
  286. int getStatus() {
  287.    
  288.     Pstatus *p;
  289.     Liste temp;
  290.    
  291.     fprintf(stdout, "---------------------\n----Statustabelle----\n---------------------\n");
  292.    
  293.     temp = procTable;
  294.    
  295.     printf("laenge der liste: %d\n",listeLaenge(temp));
  296.    
  297.    
  298.     /*fprintf(stdout, "Pid: %d", p->pid);*/
  299.    
  300.    
  301.    
  302.     if(listeLaenge(temp) < 1) {
  303.         fprintf(stdout, "Liste ist leer.\n");
  304.         return 0;
  305.     }
  306.    
  307.      
  308.     while(temp != NULL){
  309.          
  310.         /*fprintf(stdout, "%s", listeKopf(temp));  */
  311.         p = listeKopf(temp);
  312.        
  313.         /*if(p->check < 1) {*/
  314.         fprintf(stdout,"PID: %d, Programm: %s, Status: %s\n",p->pid, p->name, p->status);
  315.         /*} */
  316.        
  317.         /* wenn status != running -> p.checked() */
  318.        
  319.         temp = listeRest(temp);
  320.       }
  321.     return 0;
  322. }
  323.  
  324. int interpretiere(Kommando k, int forkexec){
  325.   int status;
  326.  
  327.   switch(k->typ){
  328.   case K_LEER:
  329.     return 0;
  330.   case K_EINFACH:
  331.     return interpretiere_einfach(k, forkexec);
  332.   case K_SEQUENZ:
  333.     {
  334.       Liste l = k->u.sequenz.liste;
  335.       while(!listeIstleer(l)){
  336.         status=interpretiere ((Kommando)listeKopf(l), forkexec);
  337.         l=listeRest(l);
  338.       }
  339.     }
  340.     return status;
  341.   /*
  342.    * Status wird auf 0 gesetzt. While Schleife arbeitet Befehle
  343.    * ab solange der return Wert (status) 0 ist.
  344.    * Erreicht der status den Wert ungleich 0, wird die Funktion mit
  345.    * return 1 abgebrochen.
  346.    **/
  347.   case K_UND:
  348.    {
  349.       Liste l = k->u.sequenz.liste;
  350.       status = 0;
  351.       while(!listeIstleer(l) && status == 0){
  352.         status=interpretiere ((Kommando)listeKopf(l), forkexec);
  353.         l=listeRest(l);
  354.         if(status != 0) {
  355.             return 1;
  356.         }
  357.       }
  358.        /*printf("UND noch nicht implementiert");*/  
  359.    }
  360.    return 0;
  361.   /*
  362.    * Status wird auf 1 gesetzt. While Schleife arbeitet Befehle
  363.    * ab solange der return Wert (status) nicht 0 ist.
  364.    * Erreicht der status den Wert 0, wird die Funktion mit return 1
  365.    * abgebrochen.
  366.    **/
  367.   case K_ODER:
  368.    {
  369.       Liste l = k->u.sequenz.liste;
  370.       status = 1;
  371.       while(!listeIstleer(l) && status != 0){
  372.         status=interpretiere ((Kommando)listeKopf(l), forkexec);
  373.         l=listeRest(l);
  374.         if(status == 0) {
  375.             return 1;
  376.         }
  377.       }
  378.        /*printf("ODER noch nicht implementiert");*/
  379.    }
  380.    return 0;
  381.   /*
  382.    * UND Befehl. Noch nicht implementiert!
  383.    * return Wert überarbeiten!
  384.    **/
  385.   case K_PIPE:
  386.    {
  387.        /*printf("Pipeline noch nicht implementiert");*/
  388.        return interpretiere_pipeline(k);
  389.    }
  390.    return 0;
  391.   default:
  392.     fputs("unbekannter Kommandotyp, Bearbeitung nicht implementiert\n", stderr);
  393.     break;
  394.   }
  395.   return 0;
  396. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement