J'écris mon propre shell simple. Une chose que je dois faire est de contrôler le signal SIGINT en restant dans le shell et en imprimant simplement l'invite sur une nouvelle ligne lorsque ctrl + c est pressé. Actuellement, j'ai été capable de gérer le signal et le shell imprime simplement ^C
après l'invite. Cependant, le curseur reste sur la même ligne. Ce que je voudrais faire à la place est d'imprimer le shell ^C
après l'invite, passer à la ligne suivante et imprimer une nouvelle invite. J'ai trouvé this question, qui corrige exactement le même problème. Le problème avec le mien est que mon main
appelle une autre fonction où la boucle d'invite est exécutée. J'ai essayé plusieurs façons d'implémenter la solution donnée sur le lien ci-dessus, à la fois dans la fonction principale et dans la fonction de boucle rapide, mais sans aucune chance. Voici mon code à ce jour:Écrire mon propre shell - problème avec la gestion correcte de ctrl + c (SIGINT)
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
utilisant:
void ctrl_C_handler() {
signal(SIGINT, ctrl_C_handler);
printf("\n");
my_shell_loop();
}
agit comme on le souhaite la première fois que ctrl + c est pressé, mais agit ensuite comme il le faisait auparavant pour toutes les fois où il est pressé.
Je ne vois vraiment rien qui puisse être nommé "problème". Il suffit d'effectuer une itération de boucle avec une entrée vide. Oui, vous devrez réarranger les choses pour éviter la duplication de code. –
@EugeneSh. C'est une solution que j'ai trouvée moi aussi, mais je n'ai pas pu faire une boucle sans intervention de l'utilisateur. Comment pourrais-je y parvenir? – KOB
Prendre le contenu de la boucle dans une fonction séparée. Ou mieux à deux - un pour l'entrée, un pour la sortie. Ensuite, appelez simplement celui pour la sortie. –