Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <fcntl.h>
- #include <errno.h>
- #include "utils.h"
- #include "listen.h"
- #include "wortspeicher.h"
- #include "kommandos.h"
- #include "frontend.h"
- #include "parser.h"
- #include "variablen.h"
- int interpretiere(Kommando k, int forkexec);
- int interpretiere_einfach(Kommando k, int forkexec);
- int getStatus();
- Liste procTable;
- void do_execvp(int argc, char **args){
- execvp(*args, args);
- perror("exec-Fehler");
- fprintf(stderr, "bei Aufruf von \"%s\"\n", *args);
- exit(1);
- }
- int interpretiere_pipeline(Kommando k){
- /* NOT IMPLEMENTED */
- int fd1[] = { -1, -1 };
- int fd2[] = { -1, -1 };
- int i = 0;
- int status = 0;
- int pid = -2;
- Liste l = k->u.sequenz.liste;
- Kommando ko;
- Pstatus pDesk;
- int laenge = k->u.sequenz.laenge;
- printf("Länge: %i!\n", laenge);
- for (i = 0; i < laenge; i++) {
- ko = (Kommando) listeKopf(l);
- fd2[0] = fd1[0];
- fd2[1] = fd1[1];
- if (i > 0) {
- close(fd2[1]);
- }
- if (pipe(fd1) < 0) {
- perror("Pipe-Fehler");
- exit(1);
- }
- pid = fork();
- switch (pid) {
- case -1:
- perror("Fehler bei fork");
- return (-1);
- case 0:
- /*1. Prozess? Dann den Lesestrom von FD2 nicht umlegen.:*/
- if (fd2[0] != -1) {
- dup2(fd2[0], STDIN_FILENO);
- }
- /*Letzter Prozess? Dann den Schreibstrom von FD1 nicht umlegen:*/
- if (i < laenge - 1) {
- dup2(fd1[1], STDOUT_FILENO);
- }
- interpretiere_einfach(ko, 0);
- exit(1);
- break;
- default:
- /*pDesk = erzeugeProzess (pid, k->u.einfach.worte[0], "RUNNING");
- procTable = listeAnfuegen(procTable, &pDesk); */
- pDesk = erzeugeProzess( pid, "test", "RUNNING");
- procTable = listeAnfuegen(procTable, &pDesk);
- sleep(1);
- break;
- }
- l = listeRest(l);
- }
- return status;
- }
- int umlenkungen(Kommando k){
- Umlenkung *u; /* Objekt vom Typ Umlenkung (kommandos.h) */
- Modus modus; /* Objekt vom Typ Modus (kommandos.h) */
- Liste neueListe; /* Objekt vom Typ Liste (listen.h) */
- FILE *f; /* File zum erstellen einer eventuellen Datei */
- /*int fd; Filedescriptor zum Überprüfen der Datei*/
- char *pfad; /* Pfad und Dateiname der Datei */
- /**
- typedef struct {
- int filedeskriptor; beliebige Deskriptoren können umgelenkt werden
- Modus modus; Umlenkungsart
- char * pfad; Datei von der / in die umgelenkt wird
- } Umlenkung;
- * */
- /*
- * Wenn Umlenkungen vorhanden sind, hole die Umleitungen aus der Liste
- * und wandle sie um in ein struct Umleitungen
- **/
- if(k->u.einfach.umlenkungen != NULL){
- fprintf(stdout, "Es sind Umleitungen vorhanden\n");
- neueListe = k->u.einfach.umlenkungen;
- u = (Umlenkung *) neueListe->kopf;
- modus = u->modus; /* Modi: read, write, append*/
- pfad = u->pfad; /* Pfad zur Datei*/
- /* Modi definiert in kommandos.h */
- switch(modus) {
- case READ: /* stellt die Standarteingabe auf die angegeben Datei 'pfad'*/
- fprintf(stdout, "Modus Read\n");
- if(freopen(pfad, "r", stdin) == NULL){
- fprintf(stderr, "Fehler beim Lesen der Datei. \nErrno: %d \n", errno);
- return 1;
- }
- break;
- case WRITE: /* Standartausgabe wird auf die Datei Pfad gestellt. Existiert die Datei noch nicht, wird sie erstellt. */
- fprintf(stdout, "Modus Write\n");
- /*fd = open(pfad, O_RDWR | O_CREAT | O_TRUNC, S_IWGRP | S_IRGRP | S_IXGRP);
- if(fd == -1) {
- fprintf(stdout, "Fehler beim Erstellen der Datei.\n Errno: %d", errno);
- exit(1);
- }*/
- if ((f = fopen(pfad, "w+")) == NULL) {
- fprintf(stderr, "Fehler beim Erstellen der Datei. \nErrno: %d \n", errno);
- return 1;
- }
- if(freopen(pfad, "w", stdout) == NULL){
- fprintf(stderr, "Fehler beim Erstellen der Datei. \nErrno: %d \n", errno);
- return 1;
- }
- break;
- case APPEND:
- fprintf(stdout, "Modus Append\n");
- /*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);
- if(fd == -1) {
- fprintf(stdout, "Fehler beim Erstellen der Datei");
- exit(1);
- }*/
- if ((f = fopen(pfad, "a+")) == NULL) {
- fprintf(stderr, "Fehler beim Erstellen der Datei. \nErrno: %d \n", errno);
- return 1;
- }
- if(freopen(pfad, "a", stdout) == NULL){
- fprintf(stderr, "Fehler beim Erstellen der Datei. \nErrno: %d \n", errno);
- return 1;
- }
- break;
- default:
- fprintf(stderr, "Modus default.\n No Options defined for default.\n");
- fprintf(stdout, "Modus default nicht verfuegbar.\n");
- break;
- }
- }
- return 0;
- }
- int aufruf(Kommando k, int forkexec){
- Pstatus p;
- Pstatus *test;
- int kind_status, i;
- /* Programmaufruf im aktuellen Prozess (forkexec==0)
- oder Subprozess (forkexec==1)
- */
- if(forkexec){
- int pid=fork();
- switch (pid){
- case -1:
- perror("Fehler bei fork");
- return(-1);
- case 0:
- if(umlenkungen(k))
- exit(1);
- do_execvp(k->u.einfach.wortanzahl, k->u.einfach.worte);
- abbruch("interner Fehler 001"); /* sollte nie ausgeführt werden */
- default:
- if(k->endeabwarten) {
- /* So einfach geht das hier nicht! */
- /* schreibt die PID, den Namen und den Status in die Tabelle */
- p = erzeugeProzess (pid, k->u.einfach.worte[0], "RUNNING"); /*k->u.einfach.worte[0] */
- /* Debug: print
- printf("\npid: %d\tstatus: %s\n", p.pid, p.status);
- */
- i = listeLaenge(procTable);
- procTable = listeAnfuegen(procTable, &p);
- if(listeLaenge(procTable) <= i) {
- fprintf(stderr, "Fehler beim Schreiben in die Liste!");
- }
- /* Debug printf: Bis hierhin wird alles ordentlich in die Liste geschrieben!
- test = listeKopf(procTable);
- printf("\npid: %d\tstatus: %s\n", test->pid, test->status);
- */
- waitpid(pid, &kind_status, 0);
- if(WIFEXITED(kind_status)){
- printf("Kind mit der PID %d wurde beendet\n",pid);
- }
- else if(WIFSIGNALED(kind_status)){
- printf("Kind mit der PID %d wurde durch Signal abgebrochen. Signalnummer: %d\n",pid, WTERMSIG(kind_status));
- }
- }
- else {
- fprintf(stderr, "Programm nicht beendet\n");
- fprintf(stdout, "PID: %i\n", pid);
- }
- return 0;
- }
- }
- /* nur exec, kein fork */
- if(umlenkungen(k))
- exit(1);
- do_execvp(k->u.einfach.wortanzahl, k->u.einfach.worte);
- abbruch("interner Fehler 001"); /* sollte nie ausgeführt werden */
- exit(1);
- }
- int interpretiere_einfach(Kommando k, int forkexec){
- char **worte = k->u.einfach.worte;
- int anzahl=k->u.einfach.wortanzahl;
- /*pDesk = erzeugeProzess( pid, ko, "RUNNING");
- procTable = listeAnfuegen(procTable, &pDesk);*/
- if (strcmp(worte[0], "exit")==0) {
- switch(anzahl){
- case 1:
- exit(0);
- case 2:
- exit(atoi(worte[1]));
- printf("Dies ist ein test");
- default:
- fputs( "Aufruf: exit [ ZAHL ]\n", stderr);
- return -1;
- }
- }
- if (strcmp(worte[0], "cd")==0) {
- switch(anzahl){
- case 1:
- return chdir(getenv("HOME"));
- case 2:
- return chdir(worte[1]);
- default:
- fputs("Aufruf: cd [ PFAD ]\n", stderr);
- return -1;
- }
- }
- /* gibt den Status der Subprozesse zurück */
- if (strcmp(worte[0], "status")==0){
- /* NYI */
- getStat(procTable);
- }
- return aufruf(k, forkexec);
- }
- int getStatus() {
- Pstatus *p;
- Liste temp;
- fprintf(stdout, "---------------------\n----Statustabelle----\n---------------------\n");
- temp = procTable;
- printf("laenge der liste: %d\n",listeLaenge(temp));
- /*fprintf(stdout, "Pid: %d", p->pid);*/
- if(listeLaenge(temp) < 1) {
- fprintf(stdout, "Liste ist leer.\n");
- return 0;
- }
- while(temp != NULL){
- /*fprintf(stdout, "%s", listeKopf(temp)); */
- p = listeKopf(temp);
- /*if(p->check < 1) {*/
- fprintf(stdout,"PID: %d, Programm: %s, Status: %s\n",p->pid, p->name, p->status);
- /*} */
- /* wenn status != running -> p.checked() */
- temp = listeRest(temp);
- }
- return 0;
- }
- int interpretiere(Kommando k, int forkexec){
- int status;
- switch(k->typ){
- case K_LEER:
- return 0;
- case K_EINFACH:
- return interpretiere_einfach(k, forkexec);
- case K_SEQUENZ:
- {
- Liste l = k->u.sequenz.liste;
- while(!listeIstleer(l)){
- status=interpretiere ((Kommando)listeKopf(l), forkexec);
- l=listeRest(l);
- }
- }
- return status;
- /*
- * Status wird auf 0 gesetzt. While Schleife arbeitet Befehle
- * ab solange der return Wert (status) 0 ist.
- * Erreicht der status den Wert ungleich 0, wird die Funktion mit
- * return 1 abgebrochen.
- **/
- case K_UND:
- {
- Liste l = k->u.sequenz.liste;
- status = 0;
- while(!listeIstleer(l) && status == 0){
- status=interpretiere ((Kommando)listeKopf(l), forkexec);
- l=listeRest(l);
- if(status != 0) {
- return 1;
- }
- }
- /*printf("UND noch nicht implementiert");*/
- }
- return 0;
- /*
- * Status wird auf 1 gesetzt. While Schleife arbeitet Befehle
- * ab solange der return Wert (status) nicht 0 ist.
- * Erreicht der status den Wert 0, wird die Funktion mit return 1
- * abgebrochen.
- **/
- case K_ODER:
- {
- Liste l = k->u.sequenz.liste;
- status = 1;
- while(!listeIstleer(l) && status != 0){
- status=interpretiere ((Kommando)listeKopf(l), forkexec);
- l=listeRest(l);
- if(status == 0) {
- return 1;
- }
- }
- /*printf("ODER noch nicht implementiert");*/
- }
- return 0;
- /*
- * UND Befehl. Noch nicht implementiert!
- * return Wert überarbeiten!
- **/
- case K_PIPE:
- {
- /*printf("Pipeline noch nicht implementiert");*/
- return interpretiere_pipeline(k);
- }
- return 0;
- default:
- fputs("unbekannter Kommandotyp, Bearbeitung nicht implementiert\n", stderr);
- break;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement