Kommandointerpreter: strtok() richtig verwenden und Umlenkung von Ein- und Ausgabe



  • Hallo,

    ich bin neu hier und muss sagen tolles Forum.

    Leider habe ich ein Problem mit einer Aufgabe aus meinem Studium. Wir sollen einen Kommandointerpreter in C programmieren.

    Ich meinem Programm suche ich schon seit einigen Stunden einen Fehler. Wenn er einen Kindprozess erstellt führt er immer nur den Befehl aus. Die Flags werden nicht mit übergeben. Könnte mir vielleicht einer helfen den Fehler zu finden?

    Könnte mir vielleicht auch einer einen Tipp geben wie ich das mit der Dateiumlenkung(<>) hinkriegen könnte. Mir ist bis jetzt nicht eingefallen wie ich das lösen soll.

    Hier mal den Code den ich bis jetzt habe.

    #include <stdio.h>
    #include <unistd.h>
    #include <syslog.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/wait.h>
    
    static void prozess(const char *log_name) {
       int i;
       pid_t pid;
    
       if ((pid = fork ()) != 0)
          exit (EXIT_FAILURE);
    
       if (setsid() < 0) {	// neue Sitzung wird angelegt
          printf("%s kann nicht Sitzungsführer werden!\n", log_name);
          exit (EXIT_FAILURE);
       }
    
    }
    
    void execute (char* befehl, char *buf) {
    
      char *flags[10];
      int i = 0;
    
      flags[i++] = (char *) strtok (buf, " ");
    
      while (i < 10) {
    
        flags[i++] = (char *) strtok(NULL, " ");
    
      }
    
      execvp(flags[0], flags);
      exit(1);
    
    }
    
    int main (void) {
       	pid_t pid;
    	char command[30];
    	int j = 0;	
    	char * befehl;
    	char * verzeichnis;
    	char *flags[10];
    	int i=0;
    
       	printf("Kommando: ");
    	gets(command);
    
    	do{
    		befehl = (char *) strtok (befehl," ");
    
    		if (strcmp(befehl, "exit") == 0){
    
    			exit(0);
    
    		}
    
    		else if (strcmp(befehl, "cd") == 0){
    
    			verzeichnis = (char *) strtok(NULL, " ");
    
    			if(verzeichnis != NULL){
    
    				chdir(verzeichnis);
    
    			}
    
    			else{
    
    				printf("Kein Verzeichnis angegeben!\n");
    
    			}	
    
    		}
    
    		else{
    			pid = fork(); 							//Neuer Prozess wird erzeugt
    
    			if (pid == 0) {
    
    				if ((char *)strchr(command,'&') != 0) {		// falls "&" im Kommando vorkommt
    
    					prozess ("Prozess");				// wird Prozess im Hintergrund gestartet
    					execute(((char *) strtok(command, "&")))				// Starte Funktion mit eingelesenem Befehl
    
    				}
    
    				else{
    
    				  execute(command);
    
    				}
    			}
    
    			else if (pid > 0) {
    
    				wait(0);
    
    			}
    
    			else if (pid < 0) { 						//Fehler beim erzeugen eines neuen Prozesses
    
    				printf("Fehler beim erzeugen eines Prozesses");
    
    			}
    		}
    
    		printf("weiteres Komando: ");
    		gets(command);
    
    	}while(strcmp(command,"exit")!=0);
    
    return 1;	
    }
    

    Dankbar für jede Hilfe,

    syn_c



  • syn_c schrieb:

    ich bin neu hier und muss sagen tolles Forum.

    Woher weißt du das, wenn du neu bist?

    #include <unistd.h>
    

    POSIX Zeugs, falsches Forum.

    char * befehl;
    ...
    
    	do{
    		befehl = (char *) strtok (befehl," ");
    

    befehl ist beim 1.Aufruf von strtok undefiniert.
    strtok und fork kann ziemlich hakelig werden.



  • Zeile 56: Welchen Wert hat befehl beim ersten Durchlauf?

    Des weitern ist execute() mit 2 Parametern definiert.
    Du rufst es aber immer nur mit einem Parameter auf.

    Bitte Stelle den Code ein den du auch nutzt.



  • Wutz schrieb:

    syn_c schrieb:

    ich bin neu hier und muss sagen tolles Forum.

    Woher weißt du das, wenn du neu bist?

    Theorie 1: Ich bin Hellseher. ^^

    Theorie 2: Ich bin schon öfters hier gelandet, ohne mich zu registrieren, und einige Beiträge haben mir schon mal geholfen. Neu ist relativ.

    Nimm die Theorie, die dir am besten gefällt.

    DirkB schrieb:

    Des weitern ist execute() mit 2 Parametern definiert.
    Du rufst es aber immer nur mit einem Parameter auf.

    Danke das du mich darauf aufmerksam gemacht hast, hatte ich vergessen wieder zu ändern als ich rumgespielt habe.

    Ich hab mein erstes Problem jetzt gelöst, indem ich alles von execute() mit in main() geschrieben habe. Ich bin noch sehr sehr bei C, vieles, wie strtok(), wirkt anders als ich dachte.

    #include <stdio.h>
    #include <unistd.h>
    #include <syslog.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/wait.h>
    
    static void prozess(const char *log_name) {
       int i;
       pid_t pid;
    
       if ((pid = fork ()) != 0)
          exit (EXIT_FAILURE);
    
       if (setsid() < 0) {	// neue Sitzung wird angelegt
          printf("%s kann nicht Sitzungsführer werden!\n", log_name);
          exit (EXIT_FAILURE);
       }
    
    }
    
    int main (void) {
       	pid_t pid;
    	char command[30];
    	char * flags[10];
    	int i = 0;	
    	char * verzeichnis;
    
       	printf("Kommando: ");
    	gets(command);
    
    	do{
    		flags[i++] = (char *) strtok (command," ");
    
    		while (i < 10) {
    
    		  flags[i++] = (char *) strtok(NULL, " ");
    
    		}
    
    		if (strcmp(flags[0], "exit") == 0){
    
    			exit(0);
    
    		}
    
    		else if (strcmp(flags[0], "cd") == 0){
    
    			verzeichnis = (char *) strtok(NULL, " ");
    
    			if(verzeichnis != NULL){
    
    				chdir(verzeichnis);
    
    			}
    
    			else{
    
    				printf("Kein Verzeichnis angegeben!\n");
    
    			}	
    
    		}
    
    		else{
    			pid = fork(); 							//Neuer Prozess wird erzeugt
    
    			if (pid == 0) {
    
    				if ((char *)strchr(command,'&') != 0) {		// falls "&" im Kommando vorkommt
    
    					prozess ("Prozess");				// wird Prozess im Hintergrund gestartet
    					execvp(flags[0], flags);		// Starte Funktion mit eingelesenem Befehl
    					exit(1);
    
    				}
    
    				else{
    
    				    execvp(flags[0], flags);
    				    exit(1);
    
    				}
    			}
    
    			else if (pid > 0) {
    
    				wait(0);
    
    			}
    
    			else if (pid < 0) { 						//Fehler beim erzeugen eines neuen Prozesses
    
    				printf("Fehler beim erzeugen eines Prozesses");
    
    			}
    		}
    
    	i = 0;
    	printf("weiteres Komando: ");
    	gets(command);
    
    	}while(strcmp(command,"exit")!=0);
    
    return 1;	
    }
    

    Könnte mir vielleicht noch einen Tipp geben wie ich das mit der Umlenkung hinkriegen könnte.

    Gruss

    syn_c


Anmelden zum Antworten