2017-11-05 3 views
-1

Ich versuche, mehr über Unix zu lernen und schreibe eine Shell in C. Mein execute() Befehl ersetzt die Funktion system(), und es funktioniert für Befehle wie ls, clear, usw. Ich kann es jedoch nicht für den Katzenkommando arbeiten. Vielmehr verdoppelt sich die Anzahl der Fehlermeldungen jedes Mal (siehe unten).Shell geschrieben in C - cat Befehl

==>cat 
==>a 
==>error in child==>a 
a 
a 
==>error in child==>a 
==>error in child==>a 
a 
a 
==>error in child==>a 
==>error in child==>a 
==>error in child==>a 
==>error in child==>a 
a 
a 
==>error in child==>a 
==>error in child==>a 
==>error in child==>a 
==>error in child==>a 
==>error in child==>a 
==>error in child==>a 
==>error in child==>a 
==>error in child==>a 
a 
a 

Dies ist der Befehl execute(). Wenn ich system() überall benutze, wo ich execute() verwende, funktioniert cat gut, aber mit execute() funktioniert das nicht. In dem Fall, in dem der eingegebene Befehl nur cat ist, dann ist args[0]cat und args[1] ist der Nullabschluss. Die Länge ist 1.

int execute (char** args) 
{ 
     int status; 
     pid_t pid; 

     switch(pid = fork()) 
     { 
       case -1: 
         status = -1; 
         fprintf(stderr, "failed to fork"); 
         break; 
       case 0: 
         execvp(args[0], args); 
         fprintf(stderr,"error in child"); 
       default: 
         if(!WIFSIGNALED(status) && !WIFEXITED(status)) 
           waitpid(pid, &status, WUNTRACED); 
     } 
     return 0; 
} 

So wird execute() in der main() -Methode verwendet. Der Befehl von der Tastatur wird als Zeichenfolge in cmndbuf gespeichert (das als deklariert wird). cmndbuf wird dann aufgeteilt und in das neue Array namens Splits eingefügt.

if (cmndbuf[0]){ 
    char** splits=malloc(sizeof(char*)*MAX_BUFFER + 1); 
    int i; 
    char* to_sep=cmndbuf; 
    for(i=0; i<MAX_ARGS; i++) 
    { 
     splits[i] = strsep(&to_sep, " "); 
     if(splits[i]==NULL) break; 
    } 
    execute(splits); 
    //system(cmndbuf); //this works 
    free(splits);          
} 

Danke Jungs! :)

+0

Wie wird 'execute' aufgerufen? Sind Sie sicher, dass das 'args' Array' NULL' terminiert ist? Beachten Sie, dass Sie 'Länge' nicht verwenden. Warum passierst du es? –

+0

BTW, hast du die Dokumentation von [cat (1)] gelesen (http://man7.org/linux/man-pages/man1/cat.1.html)? Ohne zusätzliches Argument ist es nutzlos. Und wir wissen nichts über Ihre Dateideskriptoren. Verwenden Sie [strace (1)] (http://man7.org/linux/man-pages/man1/strace.1.html) mit '-f', um Ihre Shell zu debuggen. –

+1

Eine" C-Shell "ist eine bestimmte Familie Shells - es hat eine spezifische Bedeutung, anders als "Shell in C geschrieben". –

Antwort

0

Die Linien

if(!WIFSIGNALED(status) && !WIFEXITED(status)) 
    waitpid(pid, &status, WUNTRACED); 

wird nicht funktionieren, weil waitpid() muss mindestens einmal ausgeführt, und dann muss es kontinuierlich ausgeführt werden, bis die Bedingung falsch. Das heißt, eine Do-While-Schleife wird benötigt:

do { 
    wpid = waitpid(pid, &status, WUNTRACED); 
} while (!WIFEXITED(status) && !WIFSIGNALED(status)); 
Verwandte Themen