Comment bien attendre pour l'avant-plan/arrière-plan dans mon propre coque en C?

Dans cette question précédente que j'ai posté plus de mon propre shell code. Ma prochaine étape est la mise en œuvre de premier plan et d'arrière-plan de l'exécution du processus et bien d'attendre pour eux de mettre fin, de sorte qu'ils ne restent pas comme des "zombies".

Avant d'ajouter la possibilité de les exécuter en arrière-plan, tous les processus étaient en cours d'exécution en arrière-plan. Et pour cela, j'ai simplement appelé wait(NULL) après l'exécution de tout processus avec execvp(). Maintenant, je vérifie pour le '&' comme le dernier argument, et si c'est là, lancez le processus en arrière-plan et ne pas appeler wait(NULL) et le processus peut s'exécuter heureux dans le fond, je suis retourné à ma coquille.

C'est tout fonctionne correctement (je pense), le problème, c'est que maintenant j'ai aussi besoin de l'appel en attente() (ou waitpid() ?) d'une certaine manière, de sorte que le processus d'arrière-plan ne reste pas en "zombie". C'est mon problème, je ne suis pas sûr de la façon de le faire...

Je crois que j'ai à gérer SIGCHLD et de faire quelque chose là, mais je n'ai pas encore pleinement comprendre quand le signal SIGCHLD est envoyé parce que j'ai essayé d'ajouter aussi de wait(NULL) pour childSignalHandler() mais cela ne fonctionne pas car dès que j'ai exécuté un processus en arrière-plan, la childSignalHandler() la fonction a été appelée et, par conséquent, le wait(NULL), ce qui signifie que je ne pouvais pas faire n'importe quoi avec ma coquille jusqu'à ce que le "fond" le processus est terminé. Ce qui n'était pas en cours d'exécution sur le fond plus à cause de l'attente dans le gestionnaire de signal.

Ce qui me manque dans tout cela?

Une dernière chose, une partie de cet exercice, j'ai aussi besoin d'imprimer les changements de processus d'état, comme la fin du processus. Ainsi, aucune information sur qui est également vraiment appréciée.

C'est mon code pour le moment:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wait.h>
#include <signal.h>
#include <sys/types.h>
#include "data.h" //Boolean typedef and true/false macros
void childSignalHandler(int signum) {
//
}
int main(int argc, char **argv) {
char bBuffer[BUFSIZ], *pArgs[10], *aPtr = NULL, *sPtr;
bool background;
ssize_t rBytes;
int aCount;
pid_t pid;
//signal(SIGINT, SIG_IGN);
signal(SIGCHLD, childSignalHandler);
while(1) {
write(1, "\e[1;31mmyBash \e[1;32m# \e[0m", 27);
rBytes = read(0, bBuffer, BUFSIZ-1);
if(rBytes == -1) {
perror("read");
exit(1);
}
bBuffer[rBytes-1] = '\0';
if(!strcasecmp(bBuffer, "exit")) {
exit(0);
}
sPtr = bBuffer;
aCount = 0;
do {
aPtr = strsep(&sPtr, " ");
pArgs[aCount++] = aPtr;
} while(aPtr);
background = FALSE;
if(!strcmp(pArgs[aCount-2], "&")) {
pArgs[aCount-2] = NULL;
background = TRUE;
}
if(strlen(pArgs[0]) > 1) {
pid = fork();
if(pid == -1) {
perror("fork");
exit(1);
}
if(pid == 0) {
execvp(pArgs[0], pArgs);
exit(0);
}
if(!background) {
wait(NULL);
}
}
}
return 0;
}

OriginalL'auteur Ricardo Amaral | 2009-05-22