2016-03-30 6 views
-1

Ich schreibe meine eigene einfache Shell. Eine Sache, die ich tun muss, ist, das SIGINT-Signal zu kontrollieren, indem ich in der Shell bleibe und nur die Eingabeaufforderung auf eine neue Zeile drucke, wenn Strg + C gedrückt wird. Momentan konnte ich mit dem Signal umgehen und die Shell druckt einfach ^C nach der Eingabeaufforderung. Der Cursor bleibt jedoch in derselben Zeile. Was ich stattdessen tun möchte, ist die Shell ^C nach der Eingabeaufforderung zu drucken, in die nächste Zeile zu gehen und dann eine neue Eingabeaufforderung zu drucken.Meine eigene Shell schreiben - Probleme mit der Handhabung von Strg + C (SIGINT) richtig

Ich habe this question gefunden, die genau das gleiche Problem angeht. Das Problem mit mir ist, dass mein main eine andere Funktion aufruft, wo die Aufforderungsschleife ausgeführt wird. Ich habe viele verschiedene Wege ausprobiert, um zu versuchen, die Lösung, die auf der obigen Verbindung gegeben ist, sowohl in der Haupt- als auch in der Aufforderungsschleifenfunktion zu implementieren, aber alles ohne Glück. Hier ist mein Code so weit:

Main.c

#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 
#include "MyShell.h" 

void ctrl_C_handler(); 

int main(int argc, char **argv) { 

    signal(SIGINT, ctrl_C_handler); 
    my_shell_loop(); 

    return EXIT_SUCCESS; 
} 

void ctrl_C_handler() { 
    //Catches the SIGINT signal fine without anything happening in this function 
    //I cannot figure out how to have MyShell print a fresh prompt on a new line 
    //after ctrl+C is pressed 
} 

MyShellLoop.c

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 
#include "MyShell.h" 

char *get_time(); 

void my_shell_loop() { 
    char *line; 
    char **args; 
    int status; 

    char *prompt = (char *) malloc(17); 

    do { 
     strcpy(prompt, get_time()); 
     strcat(prompt, " # "); 
     printf("%s", prompt); 
     line = read_command(); 
     args = split_command(line); 
     status = execute_command(args); 

     free(line); 
     free(args); 
    } while (status); 

    free(prompt); 
} 

EDIT

Verwendung:

void ctrl_C_handler() { 
    signal(SIGINT, ctrl_C_handler); 
    printf("\n"); 
    my_shell_loop(); 
} 

wirkt wie gewünscht, wenn Strg + c zum ersten Mal gedrückt wird, aber dann wie zuvor für weitere Male gedrückt wird.

+0

Ich sehe wirklich nichts, das "Problem" genannt werden kann. Führen Sie einfach eine Schleifeniteration mit leerer Eingabe durch. Ja, Sie müssen Dinge neu anordnen, um Code-Duplizierung zu vermeiden. –

+0

@EugeneSh. Das war eine Lösung, die auch mir einfiel, aber ich konnte keine Schleife ohne Benutzereingabe durchführen. Wie könnte ich das erreichen? – KOB

+0

Nehmen Sie den Schleifeninhalt in eine separate Funktion auf. Oder besser zu zwei - eins für die Eingabe, eins für die Ausgabe. Dann rufe einfach den einen zur Ausgabe an. –

Antwort

0

signal fügt einen Handler nur für das erste geeignete Signal an, das empfangen wird. Nach diesem Aufruf wird der Handler getrennt. Eine gängige Methode ist, dass sich der Handler wie in int foo() { signal(SIGINT, &foo); do_the_stuff(); } wieder anbringt.

Jedoch signal is non-portable. POSIX empfiehlt stattdessen die Verwendung von sigaction.

+0

Ihre erste Lösung ist in meinem Fall nicht möglich, da 'signal' in' main' gerufen wird - stimmt das richtig? – KOB

+0

Sie rufen immer noch das erste Mal an, in Haupt- oder wo auch immer, nur einmal. Jedes Mal, wenn das Signal danach abgefangen wird, wird sich der HF selbst wieder anmelden, indem er das Signal in seinem eigenen Körper anruft. –

+0

Ich habe wirklich Probleme damit zu kommen, weil ich die "Signal" -Funktion nur schlecht verstehe. Ich habe meine "Haupt" -Methode genau so, wie sie oben ist, und rufe 'signal (SIGINT, ctrl_C_handler)' auf. Dann habe ich 'void ctrl_C_handler() {Signal (SIGINT, ctrl_C_handler)}}, aber es wird immer noch nur '^ C' gedruckt, ohne die neue Eingabeaufforderung zu drucken. Was muss ich noch hinzufügen? – KOB