Ciao a tutti,
Sto cercando di completare un esercizio ma sto incontrando difficoltà.
In sostanza devo emulare una shell ed eseguire i comandi in background e foreground, monitorando lo stato.
Riporto un esempio
root/root> ls&
Padre [1006]
root/root> Figlio [1007]
input.c input.o makefile note.txt smallsh smallsh.c smallsh.h smallsh.o
ls
Padre [1006]
Figlio [1008]
input.c input.o makefile note.txt smallsh smallsh.c smallsh.h smallsh.o
[1007] Processo terminato correttamente.
eseguendo una ls in background
stampo id del padre, il processo padre mi chiede un altro comando, e in bakground vedo il figlio che mi stampa il risultato dell ls
il problema è che prima di vedere il 1007 come processo terminato devo per forza lanciare un altro comando e non riesco a capire il perchè.
Riporto la funzione principale
codice:
void runcommand(char **cline,int where) /* esegue un comando */
{
if(strcmp(*cline,"bp")==0){
printf("BPID=%s\n",getenv("BPID"));
return;
}
pid_t pid;
int exitstat,ret;
//char *BPIDTmp;
//char *PIDTmp="";
char str[100];
pid = fork();
if (pid == (pid_t) -1) {
perror("smallsh: fork fallita");
return;
}
if (pid == (pid_t) 0) { //processo figlio
//esegue il comando il cui nome e' il primo elemento di cline,
//passando cline come vettore di argomenti
printf("Figlio [%d] \n",getpid());
execvp(*cline,cline);
perror(*cline);
exit(1);
}
printf("Padre [%d] \n",getpid());
//aggiorno la env BPID
//strcat(str, integer_to_string(pid));
//strcat(str, ":");
//setenv("BPID",str,1);
// processo padre: avendo messo exec e exit non serve "else"
if (where == FOREGROUND) {
//ignoro SIGINT su padre
sigStruct.sa_handler = SIG_IGN;
sigaction(SIGINT, &sigStruct, NULL);
//ret = wait(&exitstat);
ret = waitpid(pid, &exitstat, 0);
if (ret == -1) perror("wait");
//NON CAPISCO
if (WIFSIGNALED(exitstat)){
printf("\nProcesso figlio terminato da un segnale non gestito.\n");
}
//siabilito SIGINT su padre
sigStruct.sa_handler = sigMessage;
sigaction(SIGINT, &sigStruct, NULL);
}else{
strcat(str, integer_to_string(pid));
strcat(str, ":");
setenv("BPID",str,1);
}
/*
ret = waitpid(pid, &exitstat, 0);
printf("[%5d] Processo terminato ", ret);
if (WIFEXITED(exitstat))
printf("correttamente.\n");
else if (WIFSIGNALED(exitstat))
printf("forzatamente da un segnale.\n");
*/
while ((ret = waitpid(-1, &exitstat, WNOHANG)) > 0) {
printf("[%d] Processo terminato ", ret);
if (WIFEXITED(exitstat))
printf("correttamente.\n");
else if (WIFSIGNALED(exitstat))
printf("forzatamente da un segnale.\n");
}
}