Je fais mon propre shell parce que pourquoi pas. Lorsque vous exécutez une commande et que vous la terminez par &, le processus sera exécuté en arrière-plan, donc j'aimerais créer une commande fg que vous pouvez utiliser pour mettre le processus en arrière-plan au premier plan.
J'ai quelques difficultés à faire fonctionner le fg. Si je comprends bien, mettre signal() dans le processus enfant va permettre à ce dernier de recevoir un signal. Le signal reçoit deux arguments, signum et la fonction handler. Nous allons utiliser tcsetpgrp() pour mettre un processus d'arrière plan donné au premier plan. Donc dans lsh_fg j'appelle tcsetpgrp(STDIN_FILENO, pid).
Donc signum devrait être sigttou pour qu'il puisse recevoir le signal de tcsetpgrp().
Je ne sais pas ce qu'il faut mettre dans le gestionnaire, puisque tcsetpgrp() est censé faire ce que la page de manuel décrit : " La fonction tcsetpgrp() crée le groupe de processus avec l'identifiant de groupe de processus pgrp le groupe de processus de premier plan sur le terminal associé à fd " Si je comprends bien, tcsetpgrp() envoie un signal au processus qui a signal(sigttou,handler), qui est mis au premier plan quand il le reçoit. Mais j'ai clairement mal compris puisque ça ne fonctionne pas.
Mes questions : Comment dois-je comprendre la façon dont tcsetpgrp() et signal(sigttou,handler) fonctionnent ensemble ? Et que doit inclure mon handler ? J'apprécie vraiment vos réponses car je suis vraiment coincé ici :-) Voir mon code ci-dessous : Ps : Je suis nouveau à C et la programmation du système et c'est mon premier poste jamais donc toute critique constructive concernant mon code est chaleureusement bienvenue MERCI BEAUCOUP :D
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
pid_t pid;
int toke_c;
//function declaration for the function pointers
int lsh_cd(char **args);
int lsh_pwd(char **args);
int lsh_exit(char **args);
int lsh_fg(char **args);
//An array of functions:
int (*builtin_func[]) (char **) = {
&lsh_cd,
&lsh_pwd,
&lsh_exit,
&lsh_fg
};
//An array of the given strings:
char *builtin_str[] = {
"cd",
"pwd",
"exit",
"fg"
};
///built in functions cd and pwd
int lsh_fg(char **args){
tcsetpgrp(STDIN_FILENO, pid);
return 1;
}
void fg_handler()
{
//What to put here???
}
///built in functions cd and pwd
int lsh_cd(char **args)
{
if (args[1] == NULL) {
fprintf(stderr, "lsh: cd: no arguments given\n");
} else {
if (chdir(args[1]) != 0) {
perror("lsh");
}
}
return 1;
}
int lsh_pwd(char **args)
{
char * cwd;
cwd=getcwd (NULL,0);
printf ("%s\n ", cwd);
return 1;
}
int lsh_exit(char **args)
{
return 0;
}
/* Handlers Here*/
void killer()
{
if (pid == 0)
exit(0);
}
void handler()
{
//I DON'T KNOW WHAT TO PUT HERE
}
int lsh_launch(char **args)
{
int status=0;
pid = fork();
if (pid == 0) {
// child process
signal(SIGINT, killer);
if (execvp(args[0], args) == -1) {
fprintf(stderr,"Command not found in $PATH\n");
}
return 1;
} else if (pid < 0) {
//error
perror("lsh");
} else {
// parent
signal(SIGINT, killer);
waitpid(pid, &status, WUNTRACED);
}
return 1;
}
int lsh_background(char **args)
{
pid_t pid;
int status=0;
pid = fork();
if (pid == 0) {
// child process
setpgid(0, 0);
signal(SIGINT, killer);
signal(SIGTTOU, fg_handler);
if (execvp(args[0], args) == -1) {
fprintf(stderr,"Command not found in $PATH\n");
}
return 1;
} else if (pid < 0) {
//error
perror("lsh");
} else {
// parent
signal(SIGTTOU, fg_handler);
signal(SIGINT, killer);
}
return 1;
}
//if a command was entered that we've been using
int lsh_exec(int argc, char **args)
{
int i;
if (args[0] == NULL) {return 1;}
int tresh=4;
char **args1=malloc(toke_c*sizeof(char *));
int j;
for(j=0;j<toke_c-1;j++){
args1[j]=args[j];
}
if(strcmp(args[toke_c-1],"&")==0){
return lsh_background(args1);
}
for (i = 0; i < tresh; i++) {
if (strcmp(args[0], builtin_str[i]) == 0) {
return (*builtin_func[i])(args);
}
}
return lsh_launch(args);
}
#define MAX_STR 256
//reading the line
char *lsh_lread(void)
{
char *str = malloc (MAX_STR);
fgets (str, MAX_STR, stdin);
}
//tokenizer
char **lsh_tokenizer(char *line)
{
int bufsize = 64;
int pos_t = 0;
char **tokens = malloc(bufsize * sizeof(char*));
char *token;
token = strtok(line, " \t\r\n\a");
while (token != NULL) {
tokens[pos_t] = token;
pos_t++;
token = strtok(NULL, " \t\r\n\a");
}
tokens[pos_t] = NULL;
toke_c=pos_t;
return tokens;
}
void lsh_loop(void)
{
int argc;
char *line;
char **args;
int status;
do {
printf(">> ");
line = lsh_lread();
args = lsh_tokenizer(line);
status = lsh_exec(argc,args);
free(line);
free(args);
} while (status);
}
int main(int argc, char **argv)
{
lsh_loop();
return 0;
}